编译原理学习笔记之自上而下分析Ⅱ

一、FIRST集

FIRST(a)是从a 推导出的串的起始终结符的集合

计算方法

  • 若X->a.., 则将终结符a加入FIRST(X)中
  • 若X->e,则将e加入FIRST(X)中
  • 若X->Y…,且Y属于非终结符,则将FIRST(Y)\{e}加入到FIRST(X)中
  • 若X->Y1Y2..YK,且Y1,Y2,..Yi-1 (2≤i≤k)都是非终结符,且Y1,Y2,..Yi-1 的FIRST集合中均包含e,则将FIRST(Yj)的所有非e元素加入到FIRST(X)中,(j=1,2,..i).特别地,若Y1~YK均有e产生式,则将e加到FIRST(X)中

首先,S推出B,则FIRST(S)=FIRST(B)

同理FIRST(A)包含FIRST(B),且d∈FIRST(A)

由三式知,B可以推出a,b,c所以FIRST(B)={a,b,c}

二、FOLLOW集

FOLLOW(A)是在所有句型中紧跟在A后面的终结符集合

FOLLOW集计算方法

  • 对文法开始符号S,置$于FOLLOW(S)中。
  • 若有A->aBb,则将FIRST(b)\{e} 加入FOLLOW(B)中。 (此处a 可以为空)
  • 若A->a B 或A->a B b,且 b -》e(即e 属于FIRST(b)),则将 FOLLOW(A)加入FOLLOW(B)中(此处a 可以为空)

 

首先对于开始符号S,将$加入FoLLOW(S)中(以下为了方便以F()代指FOLLOW())

B后面是A,因此将FIRST(A)加入到FOLLOW(B)中F(B)={a,b,c,d}

A在推导式最后,因此将F(S)加入F(A),F(A)={$,a,b,c,d}

对于式2,将FIRST(S)加入到F(B)中,F(B)={a,b,c,d}

将F(A)加入到F(S)中,F(S)={$,a,b,c,d}

对于式3,将F(B)加入到F(A),F(S)中

三、LL(1)文法

LL(1)文法有一些明显的特征

  • 没有公共的左因子
  • 不是二义的
  • 不含左递归

该推导显然含有左递归,因此不是LL(1)文法

这是消除左递归后的形式

上式可判断不含左递归,不含公共的左因子,是不是LL(1)文法只需要判断是否满足定义中关于FIRST集和FOLLOW集的条件

显然交集为空,因此该式是LL(1)文法

四、自上而下分析法的递归实现

S(){
       B();
       A();
}
A(){
     if(lookahead==‘a’|’b’|’c’){
         B();  S();
     }else
          match(‘d’);
}
B(){
     if(lookahead==‘a’){
         match(‘a’);  A();
     }else if(lookahead==‘b’){
          match(‘b’); S();
     }else
          match(‘c’);
}

五、自上而下分析法非递归的预测分析

以下表为例,接受id*id+id时

非终

结符

输   入   符   号

id

+

*

. . .

E

E -> TE ¢

 

 

 

E ‘

 

E ' -> +TE '

 

 

T

T -> FT '

 

 

 

T '

 

T ' -> e

T ' -> *FT '

 

F

F -> id

 

 

 

从开始符号入栈,根据栈顶元素和输入到表中对应的行列寻找推导式,将推导结果倒序入栈(替换),栈顶和输入匹配时二者都释放直至都为空。

预测分析表的构建

(1)对文法的每个产生式A -> a执行(2)和(3)。

(2)对FIRST(a)的每个终结符aA ->a 加入 M[A, a](即加入表中Aa列)。

(3)如果eFIRST(a)中,对FOLLOW(A)的每个终结符b包括$), 把A -> a 加入M[A, b]。

(4)M的其它没有定义的条目都是error。

五、预测分析的错误恢复

对于非终结符X对应的一行,把FOLLOW(X)中终结符的对应列都填上同步记号

  1. 查表,当前表项空白,指向记号流的指针后移;
  2. 查表,当前表项中含有同步记号synch,将当前栈中的非终结符弹出栈;
  3. 栈顶终结符和当前指针指向的终结符不匹配,将栈顶终结符弹出栈。

1 栈顶不动;2,3指针不动

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值