编译原理语法分析器实验报告
- 格式:doc
- 大小:2.81 MB
- 文档页数:8
编译原理语法分析器实验报告
西安邮电大学
编译原理实验报告
学院名称:计算机学院
****:***
实验名称:语法分析器的设计与实现班级:计科1405班学号:04141152
时间:2017年5月12日
把SELECT (i)存放到temp中结果返回1;
1.构建好的预测分析表
2.语法分析流程图
一.实验结果
正确运行结果:
错误运行结果:
二.设计技巧和心得体会
这次实验编写了一个语法分析方法的程序,但是在LL(1)分析器的编写中我只达到了最低要求,就是自己手动输入的select集,first集,follow集然后通过程序将预测分析表构造出来,然后自己编写总控程序根据分析表进行分析。
通过本次试验,我能够设计一个简单的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
还能选择最有代表性的语法分析方法,如LL(1) 语法分析程序、算符优先分析
程序和LR分析分析程序。
三.源代码
package com.LL1;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* LL1文法分析器,已经构建好预测分析表,采用Deque实现
* Created by HongWeiPC on 2017/5/12.
*/
public class LL1_Deque {
//预测分析表
private String[][] analysisTable = new String[][]{
{"TE'", "", "", "TE'", "", ""},
{"", "+TE'", "", "", "ε", "ε"},
{"FT'", "", "", "FT'", "", ""},
{"", "ε", "*FT'", "", "ε", "ε"},
{"i", "", "", "(E)", "", ""}
};
//终结符
private String[] VT = new String[]{"i", "+", "*", "(", ")", "#"};
//非终结符
private String[] VN = new String[]{"E", "E'", "T", "T'", "F"};
//输入串strToken
private StringBuilder strToken = new StringBuilder("i*i+i");
//分析栈stack
private Deque<String> stack = new ArrayDeque<>();
//shuru1保存从输入串中读取的一个输入符号,当前符号
private String shuru1 = null;
//X中保存stack栈顶符号
private String X = null;
//flag标志预测分析是否成功
private boolean flag = true;
//记录输入串中当前字符的位置
private int cur = 0;
//记录步数
private int count = 0;
public static void main(String[] args) {
LL1_Deque ll1 = new LL1_Deque();
ll1.init();
ll1.totalControlProgram();
ll1.printf();
}
//初始化
private void init() {
strToken.append("#");
stack.push("#");
System.out.printf("%-8s %-18s %-17s %s\n", "步骤", "符号栈", "输入串", "所用产生式");
stack.push("E");
curCharacter();
System.out.printf("%-10d %-20s %-20s\n", count, stack.toString(), strToken.substring(cur, strToken.length()));
}
//读取当前栈顶符号
private void stackPeek() {
X = stack.peekFirst();
}
//返回输入串中当前位置的字母
private String curCharacter() {
shuru1 = String.valueOf(strToken.charAt(cur));
return shuru1;
}
//判断X是否是终结符
private boolean XisVT() {
for (int i = 0; i < (VT.length - 1); i++) {
if (VT[i].equals(X)) {
return true;
}
}
return false;
}
//查找X在非终结符中分析表中的横坐标
private String VNTI() {
int Ni = 0, Tj = 0;
for (int i = 0; i < VN.length; i++) {
if (VN[i].equals(X)) {
Ni = i;
}
}
for (int j = 0; j < VT.length; j++) {
if (VT[j].equals(shuru1)) {
Tj = j;
}
}
return analysisTable[Ni][Tj];
}
//判断M[A,a]={X->X1X2...Xk}
//把X1X2...Xk推进栈
//X1X2...Xk=ε,不推什么进栈
private boolean productionType() {
return VNTI() != "";
}
//推进stack栈
private void pushStack() {
stack.pop();
String M = VNTI();
String ch;
//处理TE' FT' *FT'特殊情况
switch (M) {
case "TE'":
stack.push("E'");
stack.push("T");
break;
case "FT'":
stack.push("T'");
stack.push("F");
break;
case "*FT'":
stack.push("T'");
stack.push("F");
stack.push("*");
break;
case "+TE'":
stack.push("E'");
stack.push("T");
stack.push("+");
break;
default:
for (int i = (M.length() - 1); i >= 0; i--) {
ch = String.valueOf(M.charAt(i));
stack.push(ch);
}
break;
}
System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, M);
}
//总控程序
private void totalControlProgram() {
while (flag) {
stackPeek(); //读取当前栈顶符号令X=栈顶符号
if (XisVT()) {
if (X.equals(shuru1)) {
cur++;
shuru1 = curCharacter();
stack.pop();
System.out.printf("%-10d %-20s %-20s \n", (++count), stack.toString(), strToken.substring(cur, strToken.length()));
} else {
ERROR();
}
} else if (X.equals("#")) {
if (X.equals(shuru1)) {
flag = false;
} else {
ERROR();
}
} else if (productionType()) {
if (VNTI().equals("")) {
ERROR();
} else if (VNTI().equals("ε")) {
stack.pop();
System.out.printf("%-10d %-20s %-20s %s->%s\n", (++count), stack.toString(), strToken.substring(cur, strToken.length()), X, VNTI());
} else {
pushStack();
}
} else {
ERROR();
}
}
}
//出现错误
private void ERROR() {
System.out.println("输入串出现错误,无法进行分析");
System.exit(0);
}
//打印存储分析表
private void printf() {
if (!flag) {
System.out.println("****分析成功啦!****");
} else {
System.out.println("****分析失败了****");
}
}
}。