构建LALR(1)项目集族
构造LALR(1)项目有两种思路。一种是:先构造LR(1)项目,再合并同心项目;另一种是:先构造LR(0)项目,再为为其配上搜索符。本文介绍第二种方法。
搜索符生成有两种方法。一是,自己生成。二是,上一项目集传播获得的。项目集之间传播搜索符遇到的问题是:若多个项目集可以直接转移到一个项目集I上,那么每当I接收到,这些项目集传播过来的新的搜索符时,I就得重新再往下传播自己新的搜索符。考虑到这一点可以使用压栈的方式,将可以传播的项目压栈存好,将栈顶弹出用于传播,在传播过程中同时压入新的可传播项目。直到最后栈为空,即没有项目可以传播为止。
假设一含S’->S的拓广文法为G。具体算法如下:
1. 构造G的 LR(0)项目集规范族(实就是为了方便分析,有皆可)。
2. 将I0,S’->S,#压入栈。(I0为S’->S所在项目,#为搜索符,显然它是可以传播的)
3. 将规范族中的所有项目集的生成搜索符压入栈。因为它们是新生的可传播的。
4. 弹出栈顶,使栈顶往下传播。传播到下一个项目中后,生成自生成项目(就是自生符)。将新项入栈。继续传播,直到不能传播为止。
5. 重复第4步,直到栈为空。
上面过程中,所有新项就是LALR(1)项目集族了,包括自生的,和传播的。
示例。考虑如下文法,求其LALR(1)项目集族:
(1)S->L=R
(2)S->R
(3)L->*R
(4)L->i
(5)R->L
此文法的LR(0)项目集规范族为:
I0: |
S'->·S |
|
I4: |
L->*·R |
|
S->·L=R |
|
R->·L |
|
|
S->·R |
|
L->·*R |
|
|
L->·*R |
|
L->·i |