import java.util.Stack; public class LL1 { //加入同步符号的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 = new StringBuilder(")i*+i"); //分析栈 private Stack<String> stack = new Stack<String>(); //a保存从输入串中读取的一个输入符号,当前符号 private String a = null; //X中保存stack栈顶符号 private String X = null; //flag标志预测分析是否成功 private boolean flag = true; //记录输入串中当前字符的位置 private int cur = 0; //记录步数 private int count = 0; //初始化 protected void init(){ strToken.append("#"); stack.push("#"); System.out.printf("%-9s %-38s %6s %-20s\n","步骤 ","符号栈 ","输入串 ","所用产生式 "); 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(); return X; } //返回输入串中当前位置的字母 private String curCharacter(){ a = String.valueOf(strToken.charAt(cur)); 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(); if(XisVT() == true){ if(X.equals(a)){ cur++; a = curCharacter(); stack.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(); 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) { LL1 ll1 = new LL1(); ll1.init(); ll1.totalControlProgram(); ll1.printf(); } }
测试数据1:i*i+i
测试结果1:
步骤 符号栈 输入串 所用产生式 0 [#, E] i*i+i# 1 [#, Z, T] i*i+i# E->TZ 2 [#, Z, Y, F] i*i+i# T->FY 3 [#, Z, Y, i] i*i+i# F->i 4 [#, Z, Y] *i+i# 5 [#, Z, Y, F, *] *i+i# Y->*FY 6 [#, Z, Y, F] i+i# 7 [#, Z, Y, i] i+i# F->i 8 [#, Z, Y] +i# 9 [#, Z] +i# Y->ε 10 [#, Z, T, +] +i# Z->+TZ 11 [#, Z, T] i# 12 [#, Z, Y, F] i# T->FY 13 [#, Z, Y, i] i# F->i 14 [#, Z, Y] # 15 [#, Z] # Y->ε 16 [#] # Z->ε ========分析成功
测试数据2:)i*+i
测试结果2:
步骤 符号栈 输入串 所用产生式 0 [#, E] )i*+i# 输入串出现错误,无法进行分析
时间: 2024-10-12 07:50:13