Permit trailing commas in JSON maps & arrays

Handled in both dbYacc and yajl parsers.
Adds tests to linkInitTest.
This commit is contained in:
Andrew Johnson
2017-06-05 12:49:26 -05:00
parent e1ba1c6bba
commit 4c6b570a46
3 changed files with 28 additions and 18 deletions

View File

@@ -4,7 +4,7 @@
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* in file LICENSE that is included with this distribution.
\*************************************************************************/
%{
static int yyerror();
@@ -97,7 +97,7 @@ choice: tokenCHOICE '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("choice %s %s\n",$3,$5);
dbMenuChoice($3,$5); dbmfFree($3); dbmfFree($5);
}
}
| include;
recordtype_head: '(' tokenSTRING ')'
@@ -139,12 +139,12 @@ recordtype_field_body: '{' recordtype_field_item_list '}' ;
recordtype_field_item_list: recordtype_field_item_list recordtype_field_item
| recordtype_field_item;
recordtype_field_item: tokenSTRING '(' tokenSTRING ')'
recordtype_field_item: tokenSTRING '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("recordtype_field_item %s %s\n",$1,$3);
dbRecordtypeFieldItem($1,$3); dbmfFree($1); dbmfFree($3);
}
| tokenMENU '(' tokenSTRING ')'
| tokenMENU '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("recordtype_field_item %s (%s)\n","menu",$3);
@@ -154,7 +154,7 @@ recordtype_field_item: tokenSTRING '(' tokenSTRING ')'
device: tokenDEVICE '('
tokenSTRING ',' tokenSTRING ',' tokenSTRING ',' tokenSTRING ')'
{
{
if(dbStaticDebug>2) printf("device %s %s %s %s\n",$3,$5,$7,$9);
dbDevice($3,$5,$7,$9);
dbmfFree($3); dbmfFree($5);
@@ -290,6 +290,7 @@ json_object: '{' '}'
};
json_members: json_pair
| json_pair ','
| json_pair ',' json_members
{
$$ = dbmfStrcat3($1, ",", $3);
@@ -325,6 +326,14 @@ json_array: '[' ']'
};
json_elements: json_value
| json_value ','
{ /* Retain the trailing ',' so link parser can distinguish a
* 1-element const list from a PV name (commas are illegal)
*/
$$ = dbmfStrcat3($1, ",", "");
dbmfFree($1);
if (dbStaticDebug>2) printf("json %s\n", $$);
};
| json_value ',' json_elements
{
$$ = dbmfStrcat3($1, ",", $3);
@@ -342,7 +351,7 @@ json_value: jsonNULL { $$ = dbmfStrdup("null"); }
%%
#include "dbLex.c"
@@ -363,7 +372,7 @@ static long pvt_yy_parse(void)
{
static int FirstFlag = 1;
long rtnval;
if (!FirstFlag) {
yyAbort = FALSE;
yyFailed = FALSE;

View File

@@ -326,8 +326,9 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
}
break;
case yajl_tok_right_bracket: {
if (yajl_bs_current(hand->stateStack) ==
yajl_state_array_start)
yajl_state s = yajl_bs_current(hand->stateStack);
if (s == yajl_state_array_start ||
s == yajl_state_array_need_val)
{
if (hand->callbacks &&
hand->callbacks->yajl_end_array)
@@ -396,20 +397,21 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
}
yajl_bs_set(hand->stateStack, yajl_state_map_sep);
goto around_again;
case yajl_tok_right_brace:
if (yajl_bs_current(hand->stateStack) ==
yajl_state_map_start)
{
case yajl_tok_right_brace: {
yajl_state s = yajl_bs_current(hand->stateStack);
if (s == yajl_state_map_start ||
s == yajl_state_map_need_key) {
if (hand->callbacks && hand->callbacks->yajl_end_map) {
_CC_CHK(hand->callbacks->yajl_end_map(hand->ctx));
}
yajl_bs_pop(hand->stateStack);
goto around_again;
}
}
default:
yajl_bs_set(hand->stateStack, yajl_state_parse_error);
hand->parseError =
"invalid object key (must be a string)";
"invalid object key (must be a string)";
goto around_again;
}
}
@@ -490,4 +492,3 @@ yajl_do_parse(yajl_handle hand, const unsigned char * jsonText,
abort();
return yajl_status_error;
}

View File

@@ -90,10 +90,10 @@ record(event, "ev2") {
}
record(int64in, "i1") {
field(INP, [1234567890123456789,0])
field(INP, [1234567890123456789,])
}
record(int64in, "i2") {
field(INP, {const:1234567890123456789})
field(INP, {const:1234567890123456789,})
}
record(int64in, "i3") {
field(INP, 1234567890123456789)
@@ -101,6 +101,6 @@ record(int64in, "i3") {
record(waveform, "i4") {
field(NELM, 1)
field(FTVL, "INT64")
field(INP, [1234567890123456789,0])
field(INP, [1234567890123456789,])
}