2016-08-23 130 views
1

我試圖用ANTLR4來描述邏輯表達式的語法。 當然,這個語法有直接的左遞歸,正如我讀過的ANTLR4支持它。ANTLR4沒有正確處理左遞歸

grammar Logic; 
@header { 
package parser; 
import expression.*; 
} 

expression returns [Expression value] : disjunction {$value = $disjunction.value;} 
             | disjunction IMPLIES expression {$value = new Implication($disjunction.value, $expression.value);}; 

disjunction returns [Expression value] : conjunction {$value = $conjunction.value;} 
             | disjunction OR conjunction {$value = new Disjunction($disjunction.value, $conjunction.value);}; 

conjunction returns [Expression value] : negation {$value = $negation.value;} 
             | conjunction AND negation {$value = new Conjunction($conjunction.value, $negation.value);}; 

negation returns [Expression value] : variable {$value = $variable.value;} 
            | NOT negation {$value = new Negation($negation.value);} 
            | OB expression CB {$value = $expression.value;}; 

variable returns [Expression value] : VAR {$value = new Variable($VAR.text);}; 

IMPLIES : '->'; 
OR : '|'; 
AND : '&'; 
NOT : '!'; 
OB : '('; 
CB : ')'; 
VAR : [A-Z]([0-9])*; 

但是當我運行ANTLR生成解析器我的語法,它提供了一些奇怪的錯誤:

error(65): Logic.g4:5:125: unknown attribute value for rule disjunction in $disjunction.value 
error(65): Logic.g4:5:125: unknown attribute value for rule conjunction in $conjunction.value 

當我換脫節,並結合在脫節規則,使得脫節右關聯,它可以工作,但是這會在我的工作中造成一些錯誤。

因爲它可能很重要,所以我使用ANTLR4-plugin爲Intellij Idea生成解析器。

我在做什麼錯? 預先感謝您。

回答

1

當提到你的代碼disjunction

disjunction returns [Expression value] 
: conjunction {$value = $conjunction.value;} 
| disjunction OR conjunction {$value = new Disjunction($disjunction.value, $conjunction.value);} 
; 

ANTLR試圖讓整個封閉規則的value如果你$disjunction,而不是在disjunction OR ...disjunction

如果你想引用disjunctiondisjunction OR ...,你需要引用它之前,它貼上標籤:

disjunction returns [Expression value] 
: c1=conjunction     {$value = $c1.value;} 
| d=disjunction OR c2=conjunction {$value = new Disjunction($d.value, $c2.value);} 
; 

這裏有一個完整的工作(測試)例如:

grammar Logic; 

@header { 
    import expression.*; 
} 

expression returns [Expression value] 
: d1=disjunction      {$value = $d1.value;} 
| d2=disjunction IMPLIES e=expression {$value = new Implication($d2.value, $e.value);} 
; 

disjunction returns [Expression value] 
: c1=conjunction     {$value = $c1.value;} 
| d=disjunction OR c2=conjunction {$value = new Disjunction($d.value, $c2.value);} 
; 

conjunction returns [Expression value] 
: n1=negation     {$value = $n1.value;} 
| c=conjunction AND n2=negation {$value = new Conjunction($c.value, $n2.value);} 
; 

negation returns [Expression value] 
: variable   {$value = $variable.value;} 
| NOT n=negation {$value = new Negation($n.value);} 
| OB expression CB {$value = $expression.value;} 
; 

variable returns [Expression value] 
: VAR {$value = new Variable($VAR.text);} 
; 

IMPLIES : '->'; 
OR  : '|'; 
AND  : '&'; 
NOT  : '!'; 
OB  : '('; 
CB  : ')'; 
VAR  : [A-Z]([0-9])*; 
SPACE : [ \t\r\n] -> skip; 
+0

不幸的是,這沒」幫助。我的第一條規則沒有任何問題,它按預期工作。這些錯誤分別出現在分離規則和結合規則中。 –

+0

@DariaZenkova我編輯我的答案 –

+0

輝煌,謝謝! –