Antlr4意外停止解析表达式
我发展与公式语法简单的计算器:Antlr4意外停止解析表达式
grammar Formula ;
expr : <assoc=right> expr POW expr # pow
| MINUS expr # unaryMinus
| PLUS expr # unaryPlus
| expr PERCENT # percent
| expr op=(MULTIPLICATION|DIVISION) expr # multiplyDivide
| expr op=(PLUS|MINUS) expr # addSubtract
| ABS '(' expr ')' # abs
| '|' expr '|' # absParenthesis
| MAX '(' expr (',' expr)* ')' # max
| MIN '(' expr (',' expr)* ')' # min
| '(' expr ')' # parenthesis
| NUMBER # number
| '"' COLUMN '"' # column
;
MULTIPLICATION: '*' ;
DIVISION: '/' ;
PLUS: '+' ;
MINUS: '-' ;
PERCENT: '%' ;
POW: '^' ;
ABS: [aA][bB][sS] ;
MAX: [mM][aA][xX] ;
MIN: [mM][iI][nN] ;
NUMBER: [0-9]+('.'[0-9]+)? ;
COLUMN: (~[\r\n"])+ ;
WS : [ \t\r\n]+ -> skip ;
"column a"*"column b"
输入给了我预期下面的树:
但"column a" * "column b"
输入意外停止解析:
我错过了什么?
您的WS
规则违反COLUMN
规则,该规则具有较高的precedence。更确切地说,问题是~[\r\n"]
也与空间字符匹配。
"column a"*"column b"
LEXES如下:'"'
COLUMN
'"'
MULTIPLICATION
'"'
COLUMN
'"'
"column a" * "column b"
LEXES如下:'"'
COLUMN
'"'
COLUMN
'"'
COLUMN
'"'
是, “航天恒星空间” 得到lexed为COLUMN
令牌,因为这就是ANTLR词法分析器规则的工作原理:更长的令牌匹配得到优先级。
正如你所看到的,此令牌流不不比赛expr
规则作为一个整体,所以expr
比赛一样,因为它可以,这是'"'
COLUMN
'"'
。
声明一个词法则规则只有一个负面的规则,就像你做的是总是一个坏主意。并且有独立的'"'
令牌也不适合我。
你应该做的是什么,包括在COLUMN
规则的报价,因为他们是在逻辑部分标记:
COLUMN: '"' (~["\r\n])* '"';
然后从你的解析器规则的独立行情。您可以稍后在处理分析树时取消引用文本,也可以更改词法分析器中的令牌发射逻辑以更改令牌的基础值。
而且为了不忽略尾随输入,添加另一个规则,这将确保你已经消耗的整个输入:
formula: expr EOF;
调用解析器的时候然后使用此规则为您的入场规则,而不是expr
。
但是, “列” * “列B” 输入意外停止解析
如果我用ANTLR 4运行你的语法。6,它不会停止解析,它解析整个文件,并显示在粉红什么解析器无法比拟的:
的点代表空格。
而且还有一个重要的错误消息:
line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'}
至于我,只要你有一个“不匹配”的错误解释here,加-tokens到GRUN。
随着"column a"*"column b"
:
$ grun Formula expr -tokens -diagnostics t1.text
[@0,0:0='"',<'"'>,1:0]
[@1,1:8='column a',<COLUMN>,1:1]
[@2,9:9='"',<'"'>,1:9]
[@3,10:10='*',<'*'>,1:10]
[@4,11:11='"',<'"'>,1:11]
[@5,12:19='column b',<COLUMN>,1:12]
[@6,20:20='"',<'"'>,1:20]
[@7,22:21='<EOF>',<EOF>,2:0]
随着"column a" * "column b"
:
$ grun Formula expr -tokens -diagnostics t2.text
[@0,0:0='"',<'"'>,1:0]
[@1,1:8='column a',<COLUMN>,1:1]
[@2,9:9='"',<'"'>,1:9]
[@3,10:12=' * ',<COLUMN>,1:10]
[@4,13:13='"',<'"'>,1:13]
[@5,14:21='column b',<COLUMN>,1:14]
[@6,22:22='"',<'"'>,1:22]
[@7,24:23='<EOF>',<EOF>,2:0]
line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'}
你立即看到" * "
被解释为COLUMN
。
约匹配与词法分析规则输入许多问题已经被问这最后的日子:
卢卡斯曾多次发布一个虚假的问题,只是作出一个总结所有问题的答案:disambiguate。
非常感谢您的详细解释! – tiktak