2017-10-06 222 views
2

我发展与公式语法简单的计算器: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"输入给了我预期下面的树: enter image description here

"column a" * "column b"输入意外停止解析: enter image description here

我错过了什么?

回答

3

您的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

+0

非常感谢您的详细解释! – tiktak

3

但是, “列” * “列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

约匹配与词法分析规则输入许多问题已经被问这最后的日子:

extraneous input

ordering

greedy

ambiguity

expression

卢卡斯曾多次发布一个虚假的问题,只是作出一个总结所有问题的答案:disambiguate