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
    
    
                                      才疏学浅,若有不对之处,欢迎留言批评指正
  • 相关阅读:
    POJ 2955 Brackets 区间DP
    POJ 3311 Hie with the Pie 最短路+状压DP
    POJ 3615 Cow Hurdles(最短路径flyod)
    hdu 3790 最短路径dijkstra(多重权值)
    poj 3254 Corn Fields 状压DP
    状压DP
    poj2411 Mondriaan's Dream 状压DP
    M: Mysterious Conch 字符串哈希
    哈希(hash)理解
    域渗透:GPP(Group Policy Preferences)漏洞
  • 原文地址:https://www.cnblogs.com/Alexkk/p/5977899.html
Copyright © 2011-2022 走看看