左递归消除

时间:2012-12-25 19:01:27

标签: parsing compiler-construction context-free-grammar computation-theory

我有这个语法

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

我想知道如何从这个语法中消除左递归,因为S+S确实令人困惑......

2 个答案:

答案 0 :(得分:2)

让我们看看我们是否可以简化给定的语法。

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

我们可以把它写成;

S -> S*|SQ|SS|B|a
Q -> +S
B -> (S)

现在,您可以消除熟悉区域中的左递归。

S  ->  BS'|aS'
S' ->  *S'|QS'|SS'|e
Q  ->  +S
B  ->  (S)

请注意,e是epsilon / lambda。

我们删除了左递归,因此我们不再需要Q和B.

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

You'll find this useful when dealing with left recursion elimination

答案 1 :(得分:0)

我使用this reference

中的理论回答

如何消除Context-Free-Grammar中的左递归。

S -->  S+S | SS | S*    |        a | (S)
      --------------            -------   
      Sα form                   β form    
      Left-Recursive-Rules      Non-Left-Recursive-Rules       

我们可以像

一样写
  

S ---> Sα 1 | Sα 2 | Sα 3 | β 1 | β 2

转换为等效非递归语法的规则:

  

S ---&gt; β 1 | β<子> 2
    Z ---&gt; α 1 |   α 2 | α<子> 3
     Z ---&gt; α 1 Z |   α 2 Z | α<子> 3 ž
     S ---&gt; β 1 Z | β<子> 2 ž

哪里

  

α 1 = + S
   α 2 = S
   α 3 = *

β - 作品无法开始以S开头:

  

β 1 = a    β 2 =(S)

没有左递归的语法:

非左递归制作S - &gt; β<子>名词

S -->  a | (S)   

使用以下产品介绍新变量Z:Z ---&gt; α n 和Z - > α<子>名词ž

Z --> +S | S | * 

and 

Z --> +SZ | SZ | *Z  

新的S作品:S - &gt; β<子>名词ž

S -->  aZ | (S)Z     

第二种形式(答案)

制作Z --> +S | S | *Z --> +SZ | SZ | *Z可以合并为Z --> +SZ | SZ | *Z| ^,其中^为空符号。

Z --> ^用于从生产规则中删除Z

所以第二个答案

S --> aZ | (S)Z Z --> +SZ | SZ | *Z| ^