编译原理(十) SLR文法分析法-算法原理

时间:2024-03-30 13:01:39

前情提要

因为SLR文法分析法就是对LR(0)的一种优化,它提供了一种解决冲突的方法,所以很多之前在LR(0)提及的东西,在此只提供一个引用。
LR(0)文法分析法

算法描述

SLR文法构造分析表的主要思想是:许多冲突性的动作都可能通过考察有关非终结符的FOLLOW集而获解决。
解决冲突的方法:解决冲突的方法是分析所有含A和B的句型,考察集合FOLLOW(A)和FOLLOW(B),如果这两个集合不相交,而且也不包含b,那么当状态I面临输入符号a时,我们可以使用如下策略:

  • 若a=b,则移进。
  • 若a∈FOLLOW(A),则用产生式A→α进行归约;
  • 若a∈FOLLOW(B),则用产生式B→α进行归约;
  • 此外,报错*

SLR的基本算法:

  • 假定LR(0)规范族的一个项目集I中含有m个移进项目
    A1→α•a1β1,A2→α•a2β2,…,Am→α•amβm;
    同时含有n个归约项目
    B1→α•,B2→α•,…,B3→α•,
  • 如果集合{ a1,…, am},FOLLOW(B1),…,FOLLOW(Bn)两两不相交(包括不得有两个FOLLOW集合有#),则隐含在I中的动作冲突可以通过检查现行输入符号a属于上述n+1个集合中的哪个集合而活的解决:
    • 若a是某个ai,i=1,2,…,m,则移进。
    • 若a∈FOLLOW(Bi),i=1,2,…,m,则用产生式Bi→α进行归约;
    • 此外,报错

这种冲突的解决方法叫做SLR(1)解决办法

SLR语法分析表的构造方法:
首先把G拓广为G’,对G’构造LR(0)项目集规范族C和活前缀识别自动机的状态转换函数GO。函数ACTION和GOTO可按如下方法构造:

  • 若项目A→α•bβ属于Ik,GO(Ik,a)= Ij,a为终结符,置ACTION[k,a]为“把状态j和符号a移进栈”,简记为“sj”;
  • 若项目A→α•属于Ik,那么,对任何非终结符a,a∈FOLLOW(A),置ACTION[k,a]为“用产生式A→α进行归约”,简记为“rj”;其中,假定A→α为文法G’的第j个产生式
  • 若项目S’→S•属于Ik,则置ACTION[k,#]为可“接受”,简记为“acc”;
  • 若GO(Ik, A)= Ij,A为非终结符,则置GOTO[k, A]=j;

分析表中凡不能用规则1至4填入信息的空白格均填上“出错标志”。
语法分析器的初始状态是包含S’ →•S的项目集合的状态
SLR解决的冲突只是移进-规约冲突规约-规约冲突

Input

7
S->E
E->E+T
E->T
T->T*F
T->F
F->(E)
F->i

Output

生成的项目表

编译原理(十) SLR文法分析法-算法原理

非终结符的follow集合

编译原理(十) SLR文法分析法-算法原理

项目规范族

编译原理(十) SLR文法分析法-算法原理
编译原理(十) SLR文法分析法-算法原理

构造出的DFA

编译原理(十) SLR文法分析法-算法原理

SLR文法表和一个例子的文法分析过程

编译原理(十) SLR文法分析法-算法原理