一、程序设计题目与说明

通过运用编译原理课程所学知识,实现LL(1)文法的语法分析程序,当任意输入一个文法符号串,通过程序中先设定好确定的LL(1)预测分析表,按照预测分析算法对输入串进行语法分析,判断其是否为符合文法规范的一个句子。如果符合文法规范则输出符号串、剩余输入串、规则等信息,否则输出错误信息

(自己加的,便于理解整个流程)简述:

init(),--》根节点E进栈,打印一行信息,不再用

totalControlProgram();,--》

1》第一步判断flag是true 则证明栈区有值,继续往下走,为false则栈区没有元素,退出

2》第二步判断栈顶元素是否是终结符,是终结符则直接pop出栈,缓冲区首字符也移除,打印输出信息

3》第三部判断栈顶元素是否为#有则匹配成功,flag设为false退出程序

4》第三步判断当前元素不为空,(如果到了这步,代表前面已经不是终结符#)把栈顶出栈,然后把得到的矩阵元素字符化后入栈

然后一步步往下走,遇见终结符就到《2》,遇到#就到《3》,遇到非终结符到《4》

二、全部代码

package downloadtest;
import java.util.Stack;
public class analyse {
// 加入同步符号的LL(1)分析表
private String[][] analysisTable = new String[][] { { "TZ", "", "", "TZ", "synch", "synch" },
{ "", "+TZ", "", "", "ε", "ε" }, { "FY", "synch", "", "FY", "synch", "synch" },
{ "", "ε", "*FY", "", "ε", "ε" }, { "i", "synch", "synch", "(E)", "synch", "synch" } };
// 存储终结符
private String[] VT = new String[] { "i", "+", "*", "(", ")", "#" };
// 存储非终结符
private String[] VN = new String[] { "E", "Z", "T", "Y", "F" };
// 输入串
private StringBuilder strToken;
// 分析栈
private Stack stack = new Stack();
// a保存从输入串中读取的一个输入符号,当前符号
private String a = null;
// X中保存stack栈顶符号
private String X = null;
// flag标志预测分析是否成功
private boolean flag = true;
// 记录输入串中当前字符的位置
private int cur = 0;
// 记录步数
private int count = 0;
public analyse(StringBuilder strToken) {
this.strToken = strToken;
init();
totalControlProgram();
printf();
}
// 初始化
protected void init() {
strToken.append("#");
stack.push("#");
System.out.println("步骤\t " + "符号栈\t\t " + "输入串 \t" + "所用产生式 ");
stack.push("E");
curCharacter();
System.out.printf("%-6d %-20s %6s \n", count, stack.toString(), strToken.substring(cur, strToken.length()));
}
// 读取当前栈顶符号
protected String stackPeek() {
X = stack.peek();//栈顶元素(size-1)
return X;
}
// 返回输入串中当前位置的字母
private String curCharacter() {
a = String.valueOf(strToken.charAt(cur));//默认0位为第一个字符
return a;
}
// 判断X是否是终结符
protected boolean XisVT() {
for (int i = 0; i < (VT.length - 1); i++) {
if (VT[i].equals(X)) {
return true;
}
}
return false;
}
// 查找X在非终结符中分析表中的横坐标
protected 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(a)) {//终结符矩阵列比对缓冲区首字符
Tj = j;//记录列号
}
}
return analysisTable[Ni][Tj];//得到行号列号,找到矩阵上唯一的元素,即表达式,推进栈顶
}
// 判断M[A,a]={X->X1X2...Xk}
// 把X1X2...Xk推进栈
// X1X2...Xk=ε,不推什么进栈
protected boolean productionType() {
if (VNTI() != "") {
return true;
}
return false;
}
// 推进stack栈
protected void pushStack() {
stack.pop();//当前元素出栈,加入新的元素
String M = VNTI();
String ch;
for (int i = (M.length() - 1); i >= 0; i--) {
ch = String.valueOf(M.charAt(i));//字符串变成字符依次加入栈,反向,极为栈顶
stack.push(ch);
}
System.out.printf("%-6d %-20s %6s %-1s->%-12s\n", (++count), stack.toString(),
strToken.substring(cur, strToken.length()), X, M);
}
// 总控程序
protected void totalControlProgram() {
while (flag == true) {//无限循环直至,最终栈空间为#
stackPeek();//得到栈顶元素X有值了E
if (XisVT() == true) {//判断是终结符
if (X.equals(a)) {//栈顶元素与缓冲区首字符匹配
cur++;//缓冲区首位元素+1
a = curCharacter();//得到下一位字符
stack.pop();//缓冲区元素为终结符切等于栈顶字符,那么直接pop,打印信息
System.out.printf("%-6d %-20s %6s \n", (++count), stack.toString(),
strToken.substring(cur, strToken.length()));
} else {
ERROR();
}
} else if (X.equals("#")) {//判断是否为最后一个#
if (X.equals(a)) {//缓冲区元素也是#那么匹配成功
flag = false;
} else {
ERROR();
}
} else if (productionType() == true) {//判断矩阵定位的地方有元素
if (VNTI().equals("synch")) {//判断是否为同步字符
ERROR();//无法分析
} else if (VNTI().equals("ε")) {//判断是否为空
stack.pop();//是空则,直接把这个pop出,用下一个栈顶元素求
System.out.printf("%-6d %-20s %6s %-1s->%-12s\n", (++count), stack.toString(),
strToken.substring(cur, strToken.length()), X, VNTI());
} else {//有值,且就是这条线
pushStack();
}
} else {//什么都不是则,文法错误,不可分析
ERROR();
}
}
}
// 出现错误
protected void ERROR() {
System.out.println("输入串错误,分析中断");
System.exit(0);
}
// 打印存储分析表
protected void printf() {
if (flag == false) {
System.out.println("========分析成功");
} else {
System.out.println("========分析失败");
}
}
public static void main(String[] args) {
StringBuilder strToken = new StringBuilder("i*i+i");
new analyse(strToken);
}
}
3

三、测试数据和实验结果分析

当输入串为 “i+)+i*i”时,可知输入串存在非法符号“)”,程序分析结果如下图所示:

javafro语法 java实现语法分析_javafro语法

当输入串为“i+i+i*i”时,程序分析结果如下图所示:

javafro语法 java实现语法分析_javafro语法_02

LL(1)语法分析(java)相关教程