我不知道如何在不使用backtrack = true;的情况下解决这个问题。
我的示例语法:
grammar Test;
options {
language = Java;
output = AST;
}
parse : expression
;
expression : binaryExpression
| tupleExpression
;
binaryExpression : addingExpression (('=='|'!='|'<='|'>='|'>'|'<') addingExpression)*
;
addingExpression : multiplyingExpression (('+'|'-') multiplyingExpression)*
;
multiplyingExpression : unaryExpression
(('*'|'/'|'div'|'inter') unaryExpression)*
;
unaryExpression: ('!'|'-')* primitiveElement;
primitiveElement : literalExpression
| id
| sumExpression
| '(' expression ')'
;
sumExpression : 'sum'|'div'|'inter' expression
;
tupleExpression : ('<' expression '>' (',' '<' expression '>')*)
;
literalExpression : INT
;
id : IDENTIFIER
;
// L E X I C A L R U L E S
INT : DIGITS ;
IDENTIFIER : LETTER (LETTER | DIGIT)*;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
fragment LETTER : ('a'..'z' | 'A'..'Z' | '_') ;
fragment DIGITS: DIGIT+;
fragment DIGIT : '0'..'9';
有没有办法修复语法,这样就不会发生警告?我们假设我想根据具体情况选择两种选择。
提前谢谢!
答案 0 :(得分:3)
请注意:
sumExpression : 'sum'|'div'|'inter' expression
;
被解释为:
sumExpression : 'sum' /* nothing */
| 'div' /* nothing */
| 'inter' expression
;
因为|
的优先级较低。你可能想要:
sumExpression : ('sum'|'div'|'inter') expression
;
我们假设我想根据具体情况选择两种选择。
这是不可能的:你不能让解析器选择两种(或更多)替代品,它只能选择一种。
我假设你知道为什么语法含糊不清?如果没有,原因如下:输入A div B
可以通过两种方式解析:
unaryExpression 'div' unaryExpression
| |
A B
id sumExpression
| | \
A 'div' B
您希望'sum'
,'div'
和'inter'
成为某种一元运算符,在这种情况下,您可以将它们合并到unaryExpression
规则中:
unaryExpression : '!' unaryExpression
| '-' unaryExpression
| 'sum' unaryExpression
| 'div' unaryExpression
| 'inter' unaryExpression
| primitiveElement
;
primitiveElement : literalExpression
| id
| '(' expression ')'
;
这样你就不会有任何歧义。请注意,A div B
现在将被解析为multiplyingExpression
和A div sum B
:
multiplyingExpression
/ \
'div' unaryExpression
/ / \
A 'sum' B