如何消除左递归?
我正在尝试为一种保留了递归的简单语言编写语法,但我不太明白如何实现。
基本上我的语法看起来像这样:
expr: expr('@'TYPE)? '.' ID '(' (expr ',')∗ ')'
| expr '+' expr
| ID
| INTEGER
| STRING
INTEGER : ('0'..'9')+;
STRING : '"' ('a'..'z' | 'A'..'Z' | '0'..'9')* '"';
TYPE : ('String' | 'Bool' | 'Int')
ID : ('a'..'z' | 'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'9')*;
还有更多内容,但这是我试图删除的左递归的重要部分。
我一直在维基百科上查找有关它的信息,这就是我最终得到的结果:
expr: function
| add
| ID
| INTEGER
| STRING
function : ( ('@'TYPE)? '.' ID '(' (expr',')* ')' function)?;
add : (('+' expr) add)?;
但是antlr仍然说它是左递归的,我无法让它识别我想要的语言。谁能帮我解释一下如何删除左递归?
I'm trying to write a grammar for a simple language that has left recursion, but I don't really understand how.
Basically my grammar looks like this:
expr: expr('@'TYPE)? '.' ID '(' (expr ',')∗ ')'
| expr '+' expr
| ID
| INTEGER
| STRING
INTEGER : ('0'..'9')+;
STRING : '"' ('a'..'z' | 'A'..'Z' | '0'..'9')* '"';
TYPE : ('String' | 'Bool' | 'Int')
ID : ('a'..'z' | 'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'9')*;
There is more to it but that's the important part with the left recursion I'm trying to remove.
I've been looking on the Wikipedia about it, and this is what I ended up with:
expr: function
| add
| ID
| INTEGER
| STRING
function : ( ('@'TYPE)? '.' ID '(' (expr',')* ')' function)?;
add : (('+' expr) add)?;
However antlr still says it's left recursive and I can't get it to recognize the language I want it to. Could anyone help me out and explain to me how to remove the left recursion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
function
和add
都匹配 ε(空字符串)。删除规则末尾的?
就可以了:请注意
(expr',')*
规定表达式“列表”必须始终以一个逗号。也许下面的内容更合适:匹配 ε 或一个或多个以逗号分隔的
expr
。请注意,左递归语法:
可以翻译为:
其中 ANTLR 没有问题(即不再有左递归)。
Both
function
andadd
match ε (empty string). Remove the?
at the end of the rules and you're fine:Note that
(expr',')*
dictates that a "list" of expressions must always end with a comma. Perhaps the following is more appropriate:which matches ε or one or more
expr
separated by a comma.Note that the left recursive grammar:
could be translated into:
where ANTLR has no problems with (ie. no left recursion anymore).