我有这个非常简单的语法:
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”的表达式,但是当我尝试解析它时:
(+ (+ 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理解一元减去二进制表达式的优先级呢?
答案 0 :(得分:4)
您使用合并的grammar LispExp
,而不是单独的lexer grammar LispExpLexer
和parser grammar LispExpParser
。使用组合语法时,如果在解析器规则中使用字符串文字,代码生成器将根据这些字符串文字创建匿名标记,并以静默方式覆盖词法分析器。
在这种情况下,您的expression
规则包含字符串文字'-'
。输入中-
的所有实例都将被分配此标记类型,这意味着它们永远不会具有标记类型OP
。您的输入包含子表达式(- 2 (- 9) )
,只有在第一个-
是OP
标记时才能解析,因此根据解析器,您的输入中会出现语法错误。
如果您更新代码以使用单独的词法分析器和解析器语法,那么在您尝试生成词法分析器和解析器时,任何尝试在词法分析器语法中使用未在词法分析器语法中定义的字符串文字都会产生错误。 / p>