如果我具有以下语法来分析由空格分隔的整数列表:
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
;
现在看来一切正常!
[我认为,如果我能够理解为什么会这样,那么我将开始理解我所遇到的一些特质。
词法分析器以以下方式创建令牌:
鉴于上述2条规则的信息,您将看到您的规则:
DIGITS: DIGIT+;
INTLITERAL: (PLUS|MINUS)? DIGITS;
是问题。对于输入100
,创建了DIGITS
令牌:规则2在这里适用:两个规则都与100
匹配,但是由于DIGITS
在INTLITERAL
之前定义,因此创建了DIGITS
令牌。
将INTLITERAL
移到DIGITS
上方:
INTLITERAL: (PLUS|MINUS)? DIGITS;
DIGIT: '0'..'9';
DIGITS: DIGIT+;
但是现在请注意,DIGIT
和DIGITS
永远不会单独成为令牌,因为INTLITERAL
将始终首先匹配。在这种情况下,您可以将这两个规则都设置为fragment
,然后将它们放置在哪里都没有关系,因为fragment
规则仅在其他词法分析器规则中使用(在解析器规则中不使用)
制作DIGIT
和DIGITS
片段
fragment DIGIT: '0'..'9';
fragment DIGITS: DIGIT+;
INTLITERAL: (PLUS|MINUS)? DIGITS;
或者更好的是,不要将运算符粘贴在INTLITERAL
上,而是将其匹配为一元表达式:
expression
: (MINUS | PLUS) expression
| expression (MINUS | PLUS) expression
| integerLiteral
;
integerLiteral
: INTLITERAL
;
PLUS: '+';
MINUS: '-';
fragment DIGIT: '0'..'9';
INTLITERAL: DIGIT+