zoukankan      html  css  js  c++  java
  • 语法分析之左递归消除一

    一:什么是左递归

    计算机科学里面,左递归是一种递归的特殊状况。      
    上下文无关文法内里的说法,若一个非终端符号(non-terminal)r有任何直接的文法规则或者通过多个文法规则,
    推导出的句型(sentential form)其中最左边的符号又会出现r,则我们说这个非终端符号r是左递归的。
    即形如:r->rj像这样的式子。

    二:左递归的类型
    1:直接左递归:经过一次推导就能看出文法存在左递归的产生式
    形如:s->sb|ε
    2:间接左递归:经过多次推导才能看出文法存在左递归的产生式
    形如:S->ASb|ε
    A->aA|ε
    当A->ε时,第一个产生式就是直接左递归了。

    三:左递归的解法
    直接左递归的解法:
    1、把所有产生式写成候选式形式。如A→Aa1|Aa2……|Aan|b1|b2……|bm。其中每个a都不等于ε,而每个b都不以A开头。   
    2、变换候选式成如下形式:
    A→b1A’|b2A’……|bmA’
    A’ →a1A’|a2A’……|anA’|ε
    
    
        例子:考虑文法G: S->Sb,|a         
    一次推导: s->sb,
    两次推导: s->sb,b,
    三次推导: s->sb,b,b,
    ....
    n次推导: s->ab,b,b,b,.....
    观察上面的推导式子,该产生式子最后产生的字符串是以a开头的字符串。
    所以 s->sb,|a可以替换为
    s->as'
    s'->b,s'|ε
    间接左递归的解法:将间接转换为直接。
       要求:文法不存在环和ε产生式  
    步凑:    
    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所得到的文法。
    例子:S->Ab|a
    A->Bc|t
    B->Sb|l|d
    1:非终结符号排序:B,A,S
    2: 用B->Sb|l|d中的 Sb|l|d 代替 A->Bc|t中的B得到:

    A->Sbc|lc|dc|t

    A->Sbc|lc|dc|t中的Sbc|lc|dc|t 代替 S->Ab|a中的A得到:

    S->Sbcb|lcb|dcb|tb|a

    消除直接左递归:
    S->lcbs'|dcbs'|tbs'|as'
    s'->bcbs'|ε
    所以最终的结果:
                  
    S->lcbs'|dcbs'|tbs'|as'
    s'->bcbs'|ε
    A->Sbc|lc|dc|t
    B->Sb|l|d
    
    
                                      才疏学浅,若有不对之处,欢迎留言批评指正
  • 相关阅读:
    (转)Python之路,Day6
    (转)函数作用域,匿名函数,函数式编程,面向过程,面向对象
    (转)面向对象编程初步
    day26-多态、封装、反射
    (转)面向对象进阶
    MySql-Mysql技术内幕~SQL编程学习笔记(1)
    Spring MVC-学习笔记(4)数据绑定流程
    Mybatis-学习笔记(10)调用存储过程、存储函数
    Mybatis-学习笔记(9)Mybatis3+spring4+springMVC
    Mybatis-学习笔记(8)常用的注解
  • 原文地址:https://www.cnblogs.com/Alexkk/p/5977899.html
Copyright © 2011-2022 走看看