• 编译原理 消除左递归


    首先先进行一下总结:

     上面就是通用形势,遇见左递归文法,需要消除的时候,提取出

     用下面的文法直接进行替换,就可以了

    一个文法含有下列形式的产生式之一时:

    1)A→Aβ,A∈VN,β∈V*

    2)A→Bβ,B→Aα,A、B∈VN,α、β∈V*

    则称该文法是左递归的。

    一个文法G,若存在P经过一次或多次推导得到Pa(即能推导出以P开头的式子), 则称G是左递归的。


    然而,一个文法是左递归时,不能采取自顶向下分析法。

     

    左递归分为直接左递归和间接左递归。

    直接左递归经过一次推导就可以看出文法存在左递归,如P→Pa|b。

    间接左递归侧需多次推导才可以看出文法存在左递归,如文法:S→Qc|c,Q→Rb|b,R→Sa|a有S =>Qc =>Rbc =>Sabc

     

    消除左递归方法有:

    a)把直接左递归改写为右递归:

    设有文法产生式:A→Aβ|γ。其中β非空,γ不以A打头。

    可写为:A→γA'

    A'→βA'|ε

    一般情况下,假定关于A的产生式是:

    A→Aα1| Aα2 |… |Aαm|β1|β2 |…|βn

    其中,αi(1≤i≤m)均不为空,βj(1≤j≤n)均不以A打头。

    则消除直接左递归后改写为:

    A→ β1A'| β2 A' |…| βnA'

    A'→ α1A' | α2A' |…| αmA' |ε

     

    例:有文法G(E):

    E→E +T |T

    T→T*F | F

    F→ (E)|i

    消除该文法的直接左递归。

    解:按转换规则,可得:

    E→TE'

    E'→+TE'|ε

    T→FT '

    T'→*FT'|ε

    F→(E)|i


    b)消除间接左递归:

    对于间接左递归的消除需要先将间接左递归变为直接左递归,然后再按a)清除左递归。

    例:以文法G6为例消除左递归:

    (1)A→aB

    (2)A→Bb

    (3)B→Ac

    (4)B→d

    解:用产生式(1),(2)的右部代替产生式(3)中的非终结A得到左部为B的产生式:

    (1)B→aBc

    (2)B→Bbc

    (3)B→d

    消除左递归后得到:

    B→aBcB' |dB'

    B'→bcB' |ε

    再把原来其余的产生式A→aB,A→Bb加入,最终得到等价文法为:

    (1) A→aB

    (2) A→Bb

    (3) B→(aBc|d)B'

    (4) B'→bcB'|ε

     

    c)消除文法中一切左递归的算法

    要求文法不存在A 经过一次或多次能推导出A和不存在ε产生式(形如A→ε)。

      1、以某种顺序排列非终结符A1,A2,……,An;

      2、for i = 1 to n do

        {for j = 1 to i - l do

         { 用产生式Ai→a1b|a2b|……|akb代替每个开如Ai→Ajb的产生式,其中,Aj→a1|a2|……|ak是所有的当前Aj产生式;}

        消除关于Ai产生式中的直接左递归性}

       }

      3、化简由步骤2所得到的文法。

     

      例2:有文法S→Qc|c,

    Q→Rb|b,

    R→Sa|a,

    消除文法的左递归。

      以非终结符号排序为R,Q,S

      把R的产生式代入Q中有:

      Q → (Sa|a)b|b

      Q → Sa b|ab|b

      把Q的产生式代入S中有:

      S → (Sa b|ab|b)c|c  

      S → Sa bc|abc|bc|c

      消除直接左递归得到结果:

      S → abcS’|bc S’|cS’

      S’→ abcS’|ε

      Q → Sa b|ab|b

      R → Sa|a

      Q 和 R的产生式是多余的删除,得到最终结果:

      S → abcS’|bc S’|cS’

            S’→ abcS’|ε

    注意,由于对非终结符排序的不同,最后所得的文法在形式上可能不一样。但不难证明,它们都是等价的。

    例如对上述文法的非终结符排序选为S,Q,R,那么,所得的无左递归文法是:

    把Q的产生式代入S中有:

    S->Qc|c

    S->(Rb|b)c|c

    S->Rbc|bc|c

    把S的产生式代入R中有:

    R->Sa|a

    R->(Rbc|bc|c)a|a

    R->Rbca|bca|ca|a

     消除直接左递归得到结果:

    R->bcaR'|caR'|aR'

    R'->bcaR'|ε

    与上面文法是等价的。

  • 相关阅读:
    笔记:JDBC 数据库
    笔记:Eclipse 安装 m2eclipse 插件
    Maven 生成项目站点
    Maven 项目报告插件
    【学习总结】《大话数据结构》- 第8章-查找
    【问题解决方案】Markdown正文中慎用星号否则容易变斜体
    【学习总结】《大话数据结构》- 第7章-图
    【学习总结】《大话数据结构》- 第6章-树
    【刷题】求出栈序列个数之卡特兰数公式
    【学习总结】《大话数据结构》- 第5章-串
  • 原文地址:https://www.cnblogs.com/HIT-ryp/p/12874571.html
Copyright © 2020-2023  润新知