我正在尝试为类似json的语言设计一种语法。主要的区别是属性名不需要双引号(虽然可以),数字只能是整数(不能是浮点数)。
这是一个例子:
{
"property1": "string value",
property2: 321,
arr: [1,2,3]
}
这是我的(尝试)语法:
grammar Command;
command: object;
object: '{' pair (',' pair)* '}' ;
pair: name ':' value ;
name
: '"' ID '"'
| ID
;
value
: string
| integer
| object
| array
| bool
;
array: '[' value (',' value)* ']' ;
string: STRING ;
integer
: ZERO
| NONZERO
;
bool
: 'true'
| 'false'
;
ID : [a-zA-Z0-9_]+ ;
STRING: '"' (ESC | .)*? '"' ;
fragment ESC: '\"' | '\\' ;
ZERO: '0' ;
NONZERO: '-'? [1-9] [0-9]* ;
WS : [ tnr]+ -> skip ;
然而,试图在我的示例输入上运行testg,我得到
line 2:2 no viable alternative at input '"property"'
line 3:10 no viable alternative at input '321'
line 4:8 no viable alternative at input '1'
line 4:10 no viable alternative at input '2'
line 4:12 no viable alternative at input '3'
你知道我哪里错了吗?
谢谢你的时间!
图
-
词法分析器正在为
"property"
创建单个STRING
令牌,因此您应该调整name
规则:name : STRING | ID;
-
您需要将
ID
规则移动到ZERO
和NONZERO
之后。由于您的数字也匹配ID
词法分析器规则,因此将根据语法中出现的第一个规则为它们分配标记类型。您希望第一个规则是ZERO
或NONZERO
,而当前是ID
。(因为你所有的数字目前都导致ID
令牌,ID
不允许作为value
,你得到语法错误。)