已知课本P93拓广文法,要求用C语句编写LL(1)语法分析器程序,实现以下功能: (1)显示文法; (2)显示所有的SELECT运算和FOLLOW运算; (3)显示LL(1)分析表; (4)设计LL(1)分析器并验证语句。
时间: 2023-06-08 22:06:16 浏览: 121
你好,以下是我的回答:
首先,我们需要根据P93上的拓广文法来进行LL(1)语法分析器程序的编写,具体实现过程如下:
1. 显示文法
文法的代码如下:
```
S -> E
E -> E + T | T
T -> T * F | F
F -> ( E ) | id
```
2. 显示所有的SELECT和FOLLOW运算
SELECT和FOLLOW的计算过程如下:
(1) SELECT
对于每一个产生式A->α,其SELECT(A->α)的计算方法如下:
- 如果α能推出ε,则将FOLLOW(A)加入SELECT(A->α);
- 如果α不能推出ε,则对于α的每个非终结符B,将FIRST(α)加入SELECT(A->α)。
按照这个方法,我们对文法中的每一个产生式计算它的SELECT集,得到结果如下:
SELECT(S -> E) = { ( }
SELECT(E -> E + T) = { + }
SELECT(E -> T) = { (, id }
SELECT(T -> T * F) = { * }
SELECT(T -> F) = { (, id }
SELECT(F -> ( E )) = { ( }
SELECT(F -> id) = { id }
(2) FOLLOW
对于每一个非终结符A,其FOLLOW(A)的计算方法如下:
- 将$(结束符号)加入FOLLOW(S);
- 对于文法中每个产生式A->αBβ,将FOLLOW(A)加入FOLLOW(B);
- 对于文法中每个产生式A->αB或A->αBβ,并且β能够推出ε,则将FOLLOW(A)加入FOLLOW(B)。
按照这个方法,我们对文法中的每一个非终结符计算它的FOLLOW集,得到结果如下:
FOLLOW(S) = { $ }
FOLLOW(E) = { $, ) }
FOLLOW(T) = { +, $, ), * }
FOLLOW(F) = { +, $, ), *, id }
3. 显示LL(1)分析表
LL(1)分析表的构造过程如下:
- 对于每个产生式A->α,计算它的SELECT集;
- 对于文法中的每个产生式A->α,对于SELECT(A->α)中的每个终结符a,将M[A,a]赋值为A->α;
- 对于每个非终结符A,对于FOLLOW(A)中的每个终结符a,将M[A,a]赋值为synch。
按照这个方法,我们对文法中的每一个产生式和非终结符计算LL(1)分析表,得到结果如下:
| | ( | ) | + | * | id | $ |
| -------- | ----- | ------ | ---- | ---- | ----- | ---- |
| S | \ | | | | \ | |
| E | \ | | \ | | \ | \ |
| T | \ | | | \ | \ | \ |
| F | ( E ) | | | | id | \ |
其中,\表示空格,$表示结束符号,synch表示出错处理。
4. 设计LL(1)分析器并验证语句
我们根据LL(1)分析表来设计LL(1)分析器的算法,实现过程如下:
1. 初始化分析栈stack,将结束符号$和文法起始符号S放入栈中;
2. 读入输入的分析串input,并在串末尾添加$;
3. 重复下列过程,直到分析完成或出错退出:
1. 取出栈顶符号top和当前读入字符a;
2. 如果top是非终结符,则根据LL(1)分析表中的M[top,a]决定下一步操作:如果M[top,a]为空格,则出错退出;如果M[top,a]为A->α,则将α的逆序push入栈中;
3. 如果top是终结符,则判断top和a是否相等:如果相等,则弹出栈顶符号和读入字符a;如果不相等,则出错退出。
通过上述算法,我们可以编写一个C语言的LL(1)语法分析器程序,然后对输入的语句进行验证。
阅读全文