编译器设计-需要帮助,以消除CFG的间接左递归

时间:2018-12-21 22:30:00

标签: parsing compiler-construction context-free-grammar left-recursion

我有以下处理数学和逻辑表达式的语法:

A ==> B A'
A' ==> | B A'
A' ==> epsilon

B ==> C B'
B' ==> ^ C B'
B' ==> epsilon

C ==> D C'
C' ==> & D C'
C' ==> epsilon

D ==> E D'
D' ==> << E D' | >> E D'
D' ==> epsilon

E ==> F E'
E' ==> + F E' | - F E'
E' ==> epsilon

F ==> G F'
F' ==> * G F' | / G F' | % G F'
F' ==> epsilon

G ==> +H | -H | ++H | --H | ~H | !H | &H 
G ==> H

H ==> (A) | A T
T ==> -- | ++ | epsilon
H ==> number

以下派生发生时,会发生问题:

A ==> B ==> C ==> D ==> E ==> F ==> G ==> H ==> A

由于间接的左递归,JavaCC不会编译语法文件。

那么应该采取什么步骤来消除上一语法的这种间接左递归?

1 个答案:

答案 0 :(得分:0)

所以我盯着这个语法学习了大约半个小时之后,我才意识到在特殊情况下:

H ==> A

同样的特殊情况也会产生:

A ==> H

因此,我以这样的方式重新定义了语法,即非终结符H的第一条生产规则导致左递归,第二条生产规则不引起任何左递归,因此语法如下所示:

H ==> A T
T ==> -- | ++ | epsilon
H ==> (A) | number

如前所述,我们在第一条生产规则中将A替换为H

H ==> H T
H ==> (A) | number
T ==> -- | ++ | epsilon

现在消除左递归很简单,这就是最终语法的样子:

H ==> (A)H' | number H'
H' ==> T H' | epsilon
T ==> -- | ++ | epsilon