Java LL1文法中的左递归消除
我试图从以下语法摘录中消除左递归-Java LL1文法中的左递归消除,java,compiler-construction,context-free-grammar,javacc,Java,Compiler Construction,Context Free Grammar,Javacc,我试图从以下语法摘录中消除左递归- expression := fragment ( ( + | - | * | / ) fragment )* fragment := identifier | number | ( + | - ) fragment | expression 问题是表达式可以转到片段,可以转到表达式。我已经尝试了很多方法来消除它,有些看起来很有效(在JavaCC中),但我a)不确定它们的正确性,b)非常确定我通过改变语法结构破坏了关联性 我很确定我需要一个表达,而且 fr
expression := fragment ( ( + | - | * | / ) fragment )*
fragment := identifier | number | ( + | - ) fragment | expression
问题是表达式可以转到片段,可以转到表达式。我已经尝试了很多方法来消除它,有些看起来很有效(在JavaCC中),但我a)不确定它们的正确性,b)非常确定我通过改变语法结构破坏了关联性
我很确定我需要一个表达,而且
fragment := identifier | number | ( + | - ) fragment | expression
改为
fragment := identifier | number | ( + | - ) fragment | expressionPrime
但我不确定如何形成expressionPrime。两者
expressionPrime := identifier | number | ( + | - ) fragment | {}
及
看起来很管用,但我知道不能两者兼而有之
任何想法都将受到欢迎,即使是正确方向上的一点 从
expression ::= fragment ( ( + | - | * | / ) fragment )*
fragment ::= identifier | number | ( + | - ) fragment | expression
定义
frag1 ::= identifier | number | ( + | - ) fragment
请注意,片段相当于frag1 |表达式
。用后者取代前者,到处都能得到
expression ::= (frag1 | expression) ( ( + | - | * | / ) (frag1 | expression) )*
frag1 ::= identifier | number | ( + | - ) (frag1 | expression)
片段
不再需要
分发
expression ::= frag1 more | expression more ,
在哪里
现在您可以看到表达式是一个frag1
,后跟一个或多个more
所以
您的语法仍然模棱两可——“1*-2*3”有两个解析树。但至少它不再是递归的
(如果你在作业中使用了这个,一定要引用这个答案,这样你就不会违反学校的学术不诚实规则。)
我仍然认为你的导师犯了一个错误,因为,如果你改变
fragment ::= identifier | number | ( + | - ) fragment | expression
到
你对表达式有一套合理的语法 从
expression ::= fragment ( ( + | - | * | / ) fragment )*
fragment ::= identifier | number | ( + | - ) fragment | expression
定义
frag1 ::= identifier | number | ( + | - ) fragment
请注意,片段相当于frag1 |表达式
。用后者取代前者,到处都能得到
expression ::= (frag1 | expression) ( ( + | - | * | / ) (frag1 | expression) )*
frag1 ::= identifier | number | ( + | - ) (frag1 | expression)
片段
不再需要
分发
expression ::= frag1 more | expression more ,
在哪里
现在您可以看到表达式是一个frag1
,后跟一个或多个more
所以
您的语法仍然模棱两可——“1*-2*3”有两个解析树。但至少它不再是递归的
(如果你在作业中使用了这个,一定要引用这个答案,这样你就不会违反学校的学术不诚实规则。)
我仍然认为你的导师犯了一个错误,因为,如果你改变
fragment ::= identifier | number | ( + | - ) fragment | expression
到
你对表达式有一套合理的语法 删除左递归的方法有很多:您尝试了什么?为什么您认为您需要
片段中的表达式
?更改了问题以反映我的尝试。我遇到的部分问题是措辞,我读过的示例使用了A->Ab | c这样的产品来说明,但我发现很难将上面的语法部分与教程中各自的部分联系起来。user2357112,这是我们设置的语法,如果我们能提出更改的理由,我们可以更改它。如果我只是从片段中删除表达式,它不会从根本上改变语法可以接受的东西吗?是的。因为它太短了,不能作为一个注释,所以是的。有很多文档化的方法可以删除左递归:你尝试了什么?为什么你认为你需要片段中的表达式
?更改了问题以反映我的尝试。我遇到的部分问题是措辞,我读过的示例使用了A->Ab | c这样的产品来说明,但我发现很难将上面的语法部分与教程中各自的部分联系起来。user2357112,这是我们设置的语法,如果我们能提出更改的理由,我们可以更改它。如果我只是从片段中删除表达式,它不会从根本上改变语法可以接受的东西吗?是的。因为篇幅太短,不能作为评论,是的,非常感谢。我已经给讲师发了一封关于“和”的电子邮件,看看他怎么说。目前我已经将表达式和片段重新定义为expresion/term/factor,我认为它定义了相同的语法-表达式::=term expressionPrime expressionPrime::=+表达式|-表达式{}term::=factor term prime term::=*term |/term{}factor::=number | id这会接受相同的输入吗?如果添加一元运算符,我认为会。另外,您现在正在处理*和/和+和-,这可能是正确的做法。您认为我应该将一元运算符放在哪里?我不得不修改一下,因为他的示例文件让我们解析,包括模(%)运算符。我正在考虑定义一个非终端一元数()并向其添加运算符,但不确定是将它们放入术语还是factorIt,这取决于它们的优先级。非常感谢。我已经给讲师发了一封关于“和”的电子邮件,看看他怎么说。目前我已经将表达式和片段重新定义为expresion/term/factor,我认为它定义了相同的语法-表达式::=term expressionPrime expressionPrime::=+表达式|-表达式{}term::=factor term prime term::=*term |/term{}factor::=number | id这会接受相同的输入吗?如果添加一元运算符,我认为会。另外,您现在正在处理*和/和+和-,这可能是正确的做法。您认为我应该将一元运算符放在哪里?我不得不修改一下,因为他的示例文件让我们解析,包括模(%)运算符。我正在考虑定义一个非终端一元数()并向其添加运算符,但不确定是将它们放入术语还是factorIt中,这取决于它们的优先级。