将无上下文语法转换为LL(1)

时间:2014-10-02 12:33:31

标签: compiler-construction ll

我有以下语法:

S -> S+S|SS|S*|(S)|a

如何将其转换为LL(1)语法?

我试图消除左递归,所以我得到了

S->(S)S'|aS'
S'->+SS'|SS'|*S'|epsilon

我还尝试先做左分解,然后消除左递归,我得到了类似的东西:

S->(S)S"|aS"
       S"->S'S"|epsilon
       S'->+S|*|S

但我仍然没有得到完美的答案。我觉得语法仍然不是LL(1)。请帮忙。

1 个答案:

答案 0 :(得分:0)

尝试编写语法可能会有所帮助,以便您阅读一些完整的术语,然后可选择尝试以某种方式扩展它。例如,您可以尝试这样的事情:

  

S→期限

     

术语→CoreTerm OptMore

     

CoreTerm→a | (期限)

     

OptMore→ε|期限| +期限| * OptMore

例如,您将(a + a)* a派生为

  

取值

     

⇒期限

     

⇒CoreTermOptMore

     

⇒选择OptMore

     

⇒一个术语

     

⇒CoreTermOptMore

     

⇒a(CoreTerm OptMore)OptMore

     

⇒a(OptMore)OptMore

     

⇒a(a + Term)OptMore

     

⇒a(a + CoreTerm OptMore)OptMore

     

⇒a(a + a OptMore)OptMore

     

⇒a(a + a)OptMore

     

⇒a(a + a)* OptMore

     

⇒a(a + a)* Term

     

⇒a(a + a)* CoreTerm OptMore

     

⇒a(a + a)* a OptMore

     

⇒a(a + a)* a

要看到这是一个LL(1)语法,这里是FIRST集:

  • FIRST(S)= {
  • FIRST(Term)= {a,(}
  • FIRST(CoreTerm)= {a,(}
  • FIRST(OptMore)= {ε,a,(,+,*}

这是FOLLOW集:

  • 关注(S)= {$}
  • 关注(期限)= {$,)}
  • 关注(CoreTerm)= {a,(,+,*,$}
  • 关注(OptMore)= {$,)}

现在我们可以填写解析表:

         | a                | (                | +      | *         | )   | $
---------+------------------+------------------+--------+-----------+-----+------
S        | Term             | Term             |        |           |     |
Term     | CoreTerm OptMore | CoreTerm OptMore |        |           |     |
CoreTerm | a                | (Term)           |        |           |     |
OptMore  | Term             | Term             | + Term | * OptMore | eps | eps

所以这个语法确实是LL(1)。