Grammar LL解析的语法重构

Grammar LL解析的语法重构,grammar,ll,Grammar,Ll,在一个简单的例子中,我对如何通过删除左递归将此语法转换为LL语法感到困惑。欢迎任何提示 G = { A -> A a | A B | a B -> b } 我通过申请获得以下信息: 这似乎可以为解析器生成C伪代码: void A() { switch (token) { case 'a' : next(); X(); break; } } void X() { switch (token) {

在一个简单的例子中,我对如何通过删除左递归将此语法转换为LL语法感到困惑。欢迎任何提示

G = {
      A -> A a | A B | a
      B -> b
    }
我通过申请获得以下信息:

这似乎可以为解析器生成C伪代码:

void A() {
    switch (token) {
        case 'a' : next(); X(); break;
    }
}

void X() {
    switch (token) {
        case 'e' : finish(); break;
        case 'a' : A(); break;
        case 'b' : B(); X(); break;
    }
}

void B() {
    next();
}
并为单词生成解析树:
aabab

A ---+
|    |
a    X
     |
     A ---+
     |    |
     a    X ---+
          |    |
          B    X
          |    |
          b    A ---+
               |    |
               a    X ---+
                    |    |
                    B    X
                    |    |
                    b    e

嗯,我只是不确定它是否正确…

首先,你的语法似乎接受由单个
b
s分隔的
a
s序列,因此没有两个
b
组合在一起。(
aaa…abaaaa…abaaa…a
)这应该相当于:

Q -> P | P b P
P -> a | a P

首先,您的语法似乎接受由单个
b
s分隔的
a
s序列,因此没有两个
b
组合在一起。(
aaa…abaaaa…abaaa…a
)这应该相当于:

Q -> P | P b P
P -> a | a P

对不起,没说。我需要保留一些原始语法的结构。看一下编辑=D@Vinicius:嗯,你提出的语法(第二个)似乎是正确的。伪代码中唯一的变化是(1)开关中的默认情况,产生错误,(2)
'e'
不应该是字符,而应该是EOF或任何标记输入流结束的东西。很抱歉没有说。我需要保留一些原始语法的结构。看一下编辑=D@Vinicius:嗯,你提出的语法(第二个)似乎是正确的。伪代码中唯一的变化是(1)开关中的默认情况,产生错误,(2)
'e'
不应该是字符,而是EOF或任何标记输入流结束的东西。