ANTLR4 不能正确处理左递归
ANTLR4 doesn't manage with left recursion properly
我正在尝试使用 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
当我在析取规则中交换析取和合取,使析取右结合时,它起作用了,但这可能会导致我的工作出现一些错误。
因为这可能很重要,所以我使用 Intellij Idea 的 ANTLR4 插件生成解析器。
我做错了什么?
先感谢您。
在您的代码中引用 disjunction
时:
disjunction returns [Expression value]
: conjunction {$value = $conjunction.value;}
| disjunction OR conjunction {$value = new Disjunction($disjunction.value, $conjunction.value);}
;
如果您执行 $disjunction
而不是 disjunction OR ...
中的 disjunction
,ANTLR 将尝试获取整个封闭规则的 value
。
如果要在disjunction OR ...
中引用disjunction
,需要在引用前先标注:
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;
我正在尝试使用 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
当我在析取规则中交换析取和合取,使析取右结合时,它起作用了,但这可能会导致我的工作出现一些错误。
因为这可能很重要,所以我使用 Intellij Idea 的 ANTLR4 插件生成解析器。
我做错了什么? 先感谢您。
在您的代码中引用 disjunction
时:
disjunction returns [Expression value]
: conjunction {$value = $conjunction.value;}
| disjunction OR conjunction {$value = new Disjunction($disjunction.value, $conjunction.value);}
;
如果您执行 $disjunction
而不是 disjunction OR ...
中的 disjunction
,ANTLR 将尝试获取整个封闭规则的 value
。
如果要在disjunction OR ...
中引用disjunction
,需要在引用前先标注:
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;