ANTLR中的左递归

ANTLR中的左递归,antlr,left-recursion,Antlr,Left Recursion,stm和stmList给了我这个错误,似乎ANTLR把它看作一个可能的无限递归循环。我怎样才能避免呢以下规则集是相互左递归的[stmList] stmList: stm stmList | ; stm: ifStm | whStm; ifStm: ifPart elifPart* elsePart?; ifPart: IF LB exp RB CLB stmList CRB; elifPart: ELIF LB exp RB CLB stmList CRB; elsePart: ELSE CL

stm
stmList
给了我这个错误,似乎ANTLR把它看作一个可能的无限递归循环。我怎样才能避免呢以下规则集是相互左递归的[stmList]

stmList: stm stmList | ;
stm: ifStm | whStm;

ifStm: ifPart elifPart* elsePart?;
ifPart: IF LB exp RB CLB stmList CRB;
elifPart: ELIF LB exp RB CLB stmList CRB;
elsePart: ELSE CLB stmList CRB;

whStm: WHILE LB exp RB CLB stmList CRB;

LB: '(';
RB: ')';
CLB: '{';
CRB: '}';
WHILE: 'While';
IF: 'If';
ELIF: 'Elif';
ELSE: 'Else';

这可能是因为
stmList
中的alt为空,不过我也不知道为什么会出现这个错误。这似乎不对。但是,我建议不要使用空alt,除非您使用谓词保护其他alt并无条件地“调用”包含规则。当你忘记这一点时,这很容易导致问题。而是删除空alt并使调用可选:

stmList: stm stmList;
elsePart: ELSE CLB stmList? CRB;
此外,
stmList
看起来很像在yacc中进行这样的定义,在yacc中不可能使用EBNF后缀。相反,只需写下:


stmList:stm+

stmList
规则是右递归的。这里没有左递归,但ANTLR显示了这一点error@DuyDuy这可能是,但不是你发布的规则。你把语法删减得太多了。如果您决定剥离代码/语法并将其发布,请始终确保仍在生成原始错误。我建议把整个语法都贴出来。@BartKiers你说得对。我还没有定义已被削减的forStm的生产“我建议无论如何不要使用空的ALT”:非常同意