ANTLR4语法中的N元运算符

ANTLR4语法中的N元运算符,antlr,antlr4,grammar,Antlr,Antlr4,Grammar,我有一个解析布尔公式的语法: expr: op=NOT right=expr #Not | left=expr op=AND right=expr #And | left=expr op=OR right=expr #Or | left=expr op=XOR right=expr

我有一个解析布尔公式的语法:

expr: op=NOT right=expr                                   #Not
    | left=expr op=AND right=expr                         #And
    | left=expr op=OR right=expr                          #Or
    | left=expr op=XOR right=expr                         #Xor
    | <assoc=right> left=expr op=IMPL right=expr          #Implication
    | <assoc=right> left=expr op=EQ right=expr            #Equivalence
    | boolean=BOOL                                        #Boolean
    | '(' content=expr+ ')'                               #Brackets
    | atomic=ATOMIC                                       #Atomic
    ;
BOOL        : TRUE|FALSE;
NOT         : ('!'|'not');
AND         : ('&'|'and');
OR          : ('|'|'or');
XOR         : ('^'|'xor');
IMPL        : '->';
EQ          : '<->';
TRUE        : ('True'|'true');
FALSE       : ('False'|'false');
ATOMIC      : [a-z]+([_]?[a-z]+)*;
WS          : [ \t\n]+ -> skip;       //Skip whitespaces
expr:op=NOT right=expr#NOT
|左=expr op=和右=expr#和
|左=expr op=或右=expr#或
|左=expr op=XOR右=expr#XOR
|左=expr op=IMPL右=expr#蕴涵
|左=expr op=EQ右=expr#等价
|布尔=布尔#布尔
|“(“content=expr+”)”括号
|原子的
;
布尔:对|错;
不:(“!”|“不”);
和:(“&”和“);
或:(“|”或“);
异或:(“^”|“异或”);
IMPL:“->”;
等式:'';
真:(‘真’|‘真’);
假:(‘假’|‘假’);
原子:[a-z]+([]?[a-z]+)*;
WS:[\t\n]+->跳过//跳过空白

如何将
异或
更改为n元而不是二进制(以便这些运算符的子运算符处于同一级别)?我尝试将
left=expr op=和right=expr
替换为
expr(op=和expr)+
,这不会改变任何东西。

类似的方法可以实现以下目的:

expr
 : <assoc=right> expr IMPL expr
 | <assoc=right> expr EQ expr
 | xor_expr
 ;

xor_expr
 : or_expr (XOR or_expr)*
 ;

or_expr
 : and_expr (OR and_expr)*
 ;

and_expr
 : unary (AND unary)*
 ;

unary
 : NOT atom
 | atom
 ;

atom
 : BOOL
 | '(' expr+ ')'
 | ATOMIC
 ;
expr
:expr IMPL expr
|expr EQ expr
|xor_表达式
;
xor_表达式
:或_expr(XOR或_expr)*
;
或_expr
:and_expr(或and_expr)*
;
和_expr
:一元(和一元)*
;
一元
:不是原子
|原子
;
原子
:BOOL
|“(‘expr+’)”
|原子的
;

谢谢!但是像
a->b->c
这样的东西不能再被解析了。这样的表达式应该是正确的。如何做到这一点?将
impl\u expr(EQ impl\u expr)?
替换为
impl\u expr(EQ impl\u expr)*
将丢失正确的关联性。