语法分析之左递归消除一

一:什么是左递归

 

计算机科学里面,左递归是一种递归的特殊状况。      
上下文无关文法内里的说法,若一个非终端符号(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

                                  才疏学浅,若有不对之处,欢迎留言批评指正
posted @ 2016-10-19 16:54  Arrkwin  阅读(11842)  评论(0编辑  收藏  举报