一、实验目的
编写一个语法分析程序,实现对词法分析提供的单词序列的检查和结果分析。
二、实验要求
用高级语言编写程序,实现对简单语言的语法分析
(1)待分析语言的文法
(2)实验要求说明
输入简单语言,并以 “#” 结尾,输出栈里的内容及其相应的行为,如果成功,打印success,否则打印error。
三、实验过程
本次实验采用的是LL(1)方法,使用的是Java语言编写
1. 求First和Follow
2. 构造预测分析表
(1) 对文法生成式编号
- program -> begin stmts end
- stmts -> stmt stmtsas
- stmtsas -> ; stmt stmtsas
- stmtsas -> ε
- stmt -> ID := exp
- exp -> item items
- items -> + item items
- items -> - item items
- items -> ε
- item -> factor factors
- factors -> * factor factors
- factors -> / factor factors
- factors -> ε
- factor -> ID
- factor -> NUM
- factor -> (exp)
(2)预测分析表
(3)测试用例
测试用例1(正确用例):
begin
x := (3 +5) / 2;
y :=(4 - 1 * x) * 2;
y := x
end #
对应输出:
输出的success表示测试通过.
测试用例2(错误用例):
begin
x := (3 +5) / 2;
y :=(4 - 1 * x) * 2;
y := x;
end #
对应输出:
输出的error表示测试失败.
3. 分析
(1) 试比较测试用例1和测试用例2,会发现测试用例2只在 “end #” 前面多加了个 “;”, 从测试用例的结果(第三张图75行处)来看,出错在栈顶元素为stmt,输入的首单词为end处,查看预测分析表,发现在表中stmt行、end列并没有相应的产生式,故出错。但是正常情况下每行语句后都应有";"表示结束,故我们可以在分析表中的此处加入产生式stmt -> ε,即可解决此问题。
(2) 这个问题是所给文法存在缺陷而造成的,故读者可以根据实际情况来修改,加入的产生式体现在代码71行处,供读者参考。
四、完整代码
主体部分:
package grammar;
import java.io.IOException;
import java.util.Stack;
public class Grammar
{
//预测分析表
private String[][] LL1_table = new String[9][12];
//非终结符
private String[] vn = {
"program", "stmts", "stmtsas", "stmt", "exp", "items", "item", "factors", "factor"};
//终结符
private String[] vt = {
"begin", "end", "ID", "NUM", ";", ":=", "+", "-", "*", "/", "(", ")"};
//定义栈
private Stack<String> a = new Stack<>();
//将栈里的内容拼接成字符串输出
private StringBuilder sstack = new StringBuilder();
//将输入串的前6位(不包括已匹配的单词)拼接成字符串显示
private StringBuilder sin = new StringBuilder()