LL1语法中的左递归消除

时间:2013-12-04 00:05:29

标签: java compiler-construction context-free-grammar javacc

我正在尝试从以下语法提取中消除左递归 -

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 | {}

expressionPrime := ( ( + | - | * | / )  fragment )*

似乎工作,但我知道它不可能两者兼而有之。

任何想法都会受到高度赞赏,甚至是正确方向上的一点。

1 个答案:

答案 0 :(得分:1)

开始
expression ::= fragment ( ( + | - | * | / )  fragment )*
fragment ::= identifier | number | ( + | - ) fragment | expression

定义

frag1 ::= identifier | number | ( + | - ) fragment

请注意,片段相当于frag1 | expression。得到后者替换前者

expression ::= (frag1 | expression) ( ( + | - | * | / )  (frag1 | expression) )*
frag1 ::= identifier | number | ( + | - ) (frag1 | expression)

fragment不再需要。

分发以获取

expression ::= frag1 more | expression more   ,

,其中

more ::= ( ( + | - | * | / )  (frag1 | expression) )*

现在,您可以看到表达式为frag1,后跟一个或多个more

所以

expression ::= frag1 (more)+

你的语法仍然含糊不清 - 有2个解析tress为“1 * - 2 * 3”。但至少它不再是递归的。

(如果您在作业中使用此作品,请务必引用此答案,这样您最终不会违反学校的学术不诚实规则。)

我仍然认为你的导师犯了一个错误,因为如果你改变了

fragment ::= identifier | number | ( + | - ) fragment | expression

fragment ::= identifier | number | ( + | - ) fragment | "(" expression ")"   ,

你有一个明智的表达语法。