2017-10-06 196 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