ANTLR走错了分支

ANTLR is taking the wrong branch

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

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;

它应该能够解析一个 "lisp-like" 表达式,但是当我尝试解析这个时:

(+ (+ 5 (* 7 (/ 5 (- 2 (- 9) ) ) ) ) 8)

ANTLR 无法识别最后一个一元减号,并生成以下内容(使用 antlr v4):

(expression ( + (expression ( + (expression 5) (expression ( * (expression 7) (expression ( / (expression 5) (expression ( - (expression 2))) ( -) 9 )) expression ))

那么,我怎样才能让 ANTLR 理解一元减法相对于二元表达式的优先级呢?

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

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

如果您更新代码以使用单独的词法分析器和解析器语法,则在您尝试生成词法分析器和解析器时,任何在分析器语法中使用未在词法分析器语法中定义的字符串文字的尝试都会产生错误.