我正在尝试创建一个类似于json但不完全一样的语法,数据是这样的:
{foo=123,bar=abc}
基本上,名称和字符串没有双引号和等号而不是逗号作为键值分隔符,我的语法基于 json v4 语法,但我有以下修改:
pair
: STRING '=' value
;
value
: STRING
| NUMBER ....;
STRING
: (ESC | SAFECODEPOINT)+
;
但是解析上面的数据片段时,解析器会将整个字符串视为单个值,而不将其分解为标记。我认为问题在于 STRING 定义。如何修复 STRING 令牌定义?
问题是您的 STRING 规则不排除“=”,因此直到最后一个大括号的所有内容都会被该规则消耗。
解决此问题的一种方法是限制字段名称中可以出现的内容,例如只是 Alphabetix 字符。下面显示的 Antlr 语法就是这样做的。您可以在此处进行测试。对于您的示例输入:
{foo=123,bar=abc}
它产生了一个成功的解析树。
完整语法:
grammar JSON;
json
: value EOF
;
obj
: '{' pair (',' pair)* '}'
| '{' '}'
;
pair
: STRING '=' value
;
value
: STRING
| NUMBER
| obj
;
STRING
: [a-zA-Z]+
;
fragment ESC
: '\\' (["\\/bfnrt] | UNICODE)
;
fragment UNICODE
: 'u' HEX HEX HEX HEX
;
fragment HEX
: [0-9a-fA-F]
;
fragment SAFECODEPOINT
: ~ ["\\\u0000-\u001F]
;
NUMBER
: '-'? INT ('.' [0-9] +)? EXP?
;
fragment INT
: '0' | [1-9] [0-9]*
;
fragment EXP
: [Ee] [+\-]? [0-9]+
;
WS
: [ \t\n\r] + -> skip
;