Recursion Antlr4:以下规则集是相互左递归的

Recursion Antlr4:以下规则集是相互左递归的,recursion,antlr4,Recursion,Antlr4,我试图用和和或来描述简单语法,但由于以下错误而失败 以下规则集是相互左递归的 语法如下: expr: NAME | and | or; and: expr AND expr; or: expr OR expr; NAME : 'A' .. 'B' + ; OR: 'OR' | '|'; AND: 'AND' | '&'; 同时,下列语法 expr: NAME | expr AND expr | expr OR exp

我试图用
来描述简单语法,但由于以下错误而失败

以下规则集是相互左递归的

语法如下:

expr:
    NAME |
    and |
    or;

and:
    expr AND expr;

or:
    expr OR expr;

NAME : 'A' .. 'B' + ;
OR: 'OR' | '|';
AND: 'AND' | '&';
同时,下列语法

expr:
    NAME |
    expr AND expr |
    expr OR expr;

NAME : 'A' .. 'B' + ;
OR: 'OR' | '|';
AND: 'AND' | '&';
他会编译


为什么?

ANTLR4只支持直接左递归(这已经是对以前版本的改进)。这意味着您可以在单个规则中保留递归,但不能在多个规则中保留递归(例如,规则
a
使用规则
b
,该规则使用
a
作为备选方案中的第一条规则。

如前所述:ANTLR4仅支持直接左递归。您可以标记备选方案,以便在生成的访问者或侦听器中进行区分:

expr
 : NAME           #NameExpr
 | expr AND expr  #AndExpr
 | expr OR expr   #OrExpr
 ;

NAME : 'A' .. 'B' + ;
OR   : 'OR' | '|';
AND  : 'AND' | '&';
请注意,
'A'..'Z'+
是旧的v3语法,在v4中您可以这样做:
[A-Z]+


请参阅:

但我需要为每个操作(如解析树中的AND和OR)设置适当的节点。如果一个规则将解析所有这些操作,这怎么可能呢?通过查看现有语法,您可以学到很多东西(例如)。您可以定义自己的规则,使左侧的递归部分最终成为一个规则,也可以用非递归的方式来完成。@MikeLischke很难钻研这么多语法。您能否提供一个示例,说明如何使用非递归的方式来解决此问题?