Левая рекурсия в ANTLR

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';

person Duy Duy    schedule 15.04.2021    source источник
comment
Правило stmList является праворекурсивным. Здесь нет левой рекурсии.   -  person Chris Dodd    schedule 15.04.2021
comment
но ANTLR показывает эту ошибку   -  person Duy Duy    schedule 15.04.2021
comment
@DuyDuy это может быть, но не с опубликованными вами правилами. Вы слишком упростили грамматику. Если вы решите удалить код/грамматику и опубликовать его на SO, всегда убедитесь, что исходная ошибка все еще возникает. Я рекомендую опубликовать всю грамматику.   -  person Bart Kiers    schedule 15.04.2021
comment
@BartKiers ты прав. Я не определил производство для forStm, которое было урезано.   -  person Duy Duy    schedule 15.04.2021


Ответы (1)


Вероятно, это из-за пустого alt в stmList, хотя мне также интересно, почему возникает эта ошибка. Это не кажется правильным. Тем не менее, я рекомендую в любом случае не использовать пустые альты, если только вы не защищаете другие альты предикатом и безоговорочно вызываете содержащее правило. Это может легко привести к проблемам, если вы забудете об этом. Вместо этого удалите пустой alt и сделайте вызов необязательным:

stmList: stm stmList;
elsePart: ELSE CLB stmList? CRB;

Кроме того, stmList выглядит так же, как если бы вы сделали такое определение в yacc, где суффиксы EBNF невозможны. Вместо этого просто напишите:

stmList: stm+;

person Mike Lischke    schedule 15.04.2021
comment
В любом случае, я рекомендую не использовать пустые альты: не могу не согласиться - person Bart Kiers; 15.04.2021