如果我具有以下语法来分析由空格分隔的整数列表:
grammar TEST;
test
: expression* EOF
;
expression
: integerLiteral
;
integerLiteral
: INTLITERAL
;
PLUS: '+';
MINUS: '-';
DIGIT: '0'..'9';
DIGITS: DIGIT+;
INTLITERAL: (PLUS|MINUS)? DIGITS;
WS: [ \t\r\n] -> skip;
它不起作用!如果我通过“ 100”,我将得到:
line 1:0 extraneous input '100' expecting {<EOF>, INTLITERAL}
但是,如果删除词法分析器INTLITERAL规则,并将其放在解析器规则integerLiteral之下,就像这样
integerLiteral
: (PLUS|MINUS)? DIGITS
;
现在看来一切正常!
我认为,如果我能够理解为什么会这样,那么我将开始理解我所遇到的一些特质。
答案 0 :(得分:3)
词法分析器以以下方式创建令牌:
鉴于上述2条规则的信息,您将看到自己的规则:
DIGITS: DIGIT+;
INTLITERAL: (PLUS|MINUS)? DIGITS;
是问题所在。对于输入100
,将创建一个DIGITS
令牌:规则2在这里适用:两个规则都与100
匹配,但是由于DIGITS
是在INTLITERAL
之前定义的,因此{ {1}}令牌已创建。
将DIGITS
移到INTLITERAL
上方:
DIGITS
但是现在请注意,INTLITERAL: (PLUS|MINUS)? DIGITS;
DIGIT: '0'..'9';
DIGITS: DIGIT+;
和DIGIT
永远不会单独成为令牌,因为DIGITS
将始终首先匹配。在这种情况下,您可以同时创建这两个规则INTLITERAL
,然后再放置它们也没关系,因为fragment
规则仅在其他词法分析器规则中使用(在解析器规则中不使用)< / p>
制作fragment
和DIGIT
片段
DIGITS
或者更好的是,不要将运算符粘贴在fragment DIGIT: '0'..'9';
fragment DIGITS: DIGIT+;
INTLITERAL: (PLUS|MINUS)? DIGITS;
上,而是将其与一元表达式匹配:
INTLITERAL