【问题标题】:Left-recursion in ANTLRANTLR 中的左递归
【发布时间】:2021-07-10 01:23:57
【问题描述】:

stmstmList 给了我这个错误,似乎 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 规则是右递归的。这里没有左递归。
  • 但 ANTLR 显示该错误
  • @DuyDuy 可能是这样,但不符合您发布的规则。你把语法删减得太多了。如果您决定剥离代码/语法并将其发布在 SO 上,请始终确保仍在产生原始错误。我建议发布整个语法。
  • @BartKiers 你是对的。我还没有为已经被削减的 forStm 定义生产

标签: antlr left-recursion


【解决方案1】:

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

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

此外,stmList 看起来很像您在 yacc 中进行这样的定义,其中不可能有 EBNF 后缀。而是写:

stmList: stm+;

【讨论】:

  • “我建议不要使用空的alts”:完全同意
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多