ANTLR走错了路

ANTLR走错了路,antlr,grammar,Antlr,Grammar,我有一个非常简单的语法: grammar LispExp; expression : LITERAL #LiteralExp | '(' '-' expression ')' #UnaryMinusExp | '(' OP expression expression ')' #OpExp | '(' 'if' expression expression expression ')' #IfExp; OP : '+' |

我有一个非常简单的语法:

grammar LispExp;

expression : LITERAL #LiteralExp
            | '(' '-' expression ')' #UnaryMinusExp
            | '(' OP expression expression ')' #OpExp
            | '(' 'if' expression expression expression ')' #IfExp;

OP : '+' | '-' | '*' | '/' | '==' | '<';
LITERAL : '0'|('1'..'9')('0'..'9')*;
WS       : ('\t' | '\n' | '\r' | ' ') -> skip;
ANTLR无法识别最后一个一元减号,并生成以下内容(使用ANTLR v4):


那么,我如何才能让ANTLR理解一元减号相对于二进制表达式的优先级呢?

您使用的是组合的
语法LispExp
,而不是单独的
词法分析器LispExpLexer
语法分析器Lispexparser
。使用组合语法时,如果在解析器规则中使用字符串文字,代码生成器将根据这些字符串文字创建匿名标记,并以静默方式重写lexer

在本例中,
表达式
规则包括字符串literal
'-'
。您输入的
-
的所有实例都将被分配此令牌类型,这意味着它们永远不会具有令牌类型
OP
。您的输入包含一个子表达式
(-2(-9))
,只有在第一个
-
OP
标记时才能对其进行解析,因此根据解析器,您的输入中存在语法错误


如果您将代码更新为使用单独的lexer和parser语法,则尝试在解析器语法中使用lexer语法中未定义的字符串文字将在您尝试生成lexer和parser时产生错误。

谢谢您的回答。我没有太多时间去尝试,但我一定会尽快去做。不过,你知道混合语法是否有可能达到同样的效果吗?混合语法被认为是不好的练习吗?
(+ (+ 5 (* 7 (/ 5 (- 2 (- 9) ) ) ) ) 8)
(expression ( + (expression ( + (expression 5) (expression ( * (expression 7) (expression ( / (expression 5) (expression ( - (expression 2))) ( -) 9 )) expression ))