看了网站的某些文章,发现许多人对规则一知半解就进行实验,虽然针对书上例子结果正确,但换一种文法、加两条语句、换一个输入就漏洞百出。
- 做实验前一定要把书弄懂
- 书上给的伪代码描述不清楚,尽信书不如无书
希望这篇文章能给大家带来帮助,错误欢迎指出。
代码在 https://github.com/monimm/LLandLR
复制到本地即可运行。
本文的代码已过时,最新的在github上
实验内容
根据某一文法编写LL(1)分析程序,对输入的句子进行语法分析。
SLR(1)的实验也在此环境下完成
先贴实验结果:
注意: 输入产生式,ε用~代替,要手动替换开始符S
“E->TK”, “K->+TK”, “K->~”, “T->FM”, “M->*FM”, “M->~”, “F->i”, “F->(E)”
后附源码:
实验要求
- 输入各个产生式
- 获取first集、follow集
- 构造LL(1)预测分析表
- 输入一个句子
- 根据LL(1)预测分析表对句子进行栈操作,输出分析结果
实验过程
构造first集(龙书4.4.2节有详细介绍)
First(α)定义为可从α推出的串的首符号集合 (α为任意文法符号串)
1.构造单个文法符号X的first集
- 如果X为终结符,First(X)=X
- 如果X->ε是产生式,把ε加入First(X)
- 如果X是非终结符,如X->YZW。从左往右扫描产生式右部,把First(Y)加入First(X)。如果First(Y)不包含ε,表示Y不可为空,便不再往后处理;如果First(Y)包含ε,表示Y可为空,则处理Z,依次类推。
2.构造文法符号串的first集,如:X->YZW;求YZW的first集
- 从左往右扫描该式,加入其非空first集:把First(Y)加入First(YZW)
- 若包含空串 处理下一个符号:如果First(Y)包含空串,便处理Z;不包含就退出;处理到尾部,即所有符号的first集都包含空串 把空串加入First(YZW)
构造follow集(龙书4.4.2节有详细介绍)
对于非终结符A,Follow(A)是可能在某些句型中紧跟在A后的终结符的集合
在计算First(X)集之后的基础上
1.$属于FOLLOW(S),S是开始符
2.查找输入的所有产生式,确定X后紧跟的终结符
3.如果存在A->αBβ,(α、β是任意文法符号串,A、B为非终结符),把first(β)的非空符号加入follow(B)
4.如果存在A->αB或A->αBβ 但first(β)包含空,把follow(A)加入follow(B)
Tips:对于规则3,从左往右扫描非终结符,把左边的看成α,右边的看成β处理
Tips:对于规则4,反向扫描非终结符,把左边的看成α,右边的看成β处理
栗子:X->YZWEFG 假设全为非终结符
处理G:
- 把first(G)加入follow(F);
- 把follow(X)加入follow(G)
- 如果first(G)包含空,把follow(X)加入follow(F),向前处理
处理F:
- 把first(FG)加入follow(E);
- 如果first(FG)包含空,把follow(X)加入follow(E),向前处理
依次处理E、W、Z、Y
构造预测分析表(龙书4.4.3节有详细介绍)
对于每个产生式A->α
- first(α)中的终结符a,把A->α加入M[A,a]
- 如果空串在first(α)中,说明可为空,找它的follow集,对于follow(A)中的终结符b,把A->α加入M[A,b]
- 如果空串在first(α)中,且 ‘$’
- 也在follow(A)中,说明A后可以接终结符,故把A->α加入M[A,$]中
执行分析(龙书算法4.34有详细介绍)
输入一个串,文法G的预测分析表,输出推导过程
$ 和 开始符S入栈
栈顶符号X,index指向分析串的待分析符号a
栈非空执行以下循环
- 如果X==a,表示匹配,符号栈弹出一个,index++指向下一个符号
- 否则,如果X是终结符,出错
- 否则,如果查表为error,出错
- 否则,查表正确,弹出栈顶符号,把其右部各