代码基于词法分析程序实现LL(1)语法分析器。并且只实现了根据分析表分析字符串操作,er分析表是静态创建的。
import java.io.IOException;
import java.util.Stack;/*** 语法分析程序* @author 霍淇滨**/
public class Analysis {private Stack<Character> ans; //分析栈private Stack<Character> aim; //余留字符串栈private String[][] table; //分析表private int count = 1;/*** 构造函数,初始化栈和表* @param str*/public Analysis(String str) {ans = new Stack<Character>();aim = new Stack<Character>();table = new String[5][6]; System.out.println(str);aim.push('#');for(int i = str.length()-1;i>=0;i--) //初始化余留字符串栈aim.push(str.charAt(i));ans.push('#'); //初始化分析栈construct(); //构建分析表}/*** 构建分析表*/private void construct() {table[0][0] = "TS";table[0][1] = "error";table[0][2] = "error";table[0][3] = "TS";table[0][4] = "error";table[0][5] = "error";table[1][0] = "error";table[1][1] = "+TS";table[1][2] = "error";table[1][3] = "error";table[1][4] = "0";table[1][5] = "0";table[2][0] = "FZ";table[2][1] = "error";table[2][2] = "error";table[2][3] = "FZ";table[2][4] = "error";table[2][5] = "error";table[3][0] = "error";table[3][1] = "0";table[3][2] = "*FZ";table[3][3] = "error";table[3][4] = "0";table[3][5] = "0";table[4][0] = "i";table[4][1] = "error";table[4][2] = "error";table[4][3] = "(E)";table[4][4] = "error";table[4][5] = "error";}/*** 从分析表中获取字符串* @param A* @param a* @return*/public String getString(char A,char a) {int i=0,j=0;switch(A) { //匹配非终结符case 'E': i = 0;break;case 'S': i = 1;break;case 'T': i = 2;break;case 'Z': i = 3;break;case 'F': i = 4;break;}switch(a) { //匹配终结符case 'i': j = 0;break;case '+': j = 1;break;case '*': j = 2;break;case '(': j = 3;break;case ')': j = 4;break;case '#': j = 5;break;}return table[i][j];}/*** 语法分析方法*/public void analyzer() {char N,n;ans.push('E');PrintHead();n = aim.pop();aim.push(n);Print('E',n);while(!ans.isEmpty()) { //终结条件:分析栈为空char A = ans.pop(); //分析栈出栈char a = aim.pop(); //余留栈出栈if(A == a) {Print('$','$');continue; //相同,双方都需要出栈,继续循环}aim.push(a); //否则余留字符重新入栈String st = getString(A,a); //查询分析表if(st.equals("error")) { //为空,算法结束,匹配不成功Print(A,a);break;}else if(st.equals("0")) {Print(A,a);continue; //0表示空,不需要入分析栈直接进行下一次循环}else {for(int i = st.length()-1;i>=0;i--) { //逆序入栈ans.push(st.charAt(i));}Print(A,a);}}if(aim.isEmpty() && ans.isEmpty()) System.out.println("success");else System.out.println("failture");}/*** 打印栈* @param stack*/public void printStack(Stack<Character> stack) {for(Character s : stack)System.out.print(s);System.out.print("\t");}/*** 打印分析过程* @param A* @param a*/public void Print(char A, char a) {if(ans.isEmpty()) return;System.out.print("步骤" + count++ +"\t");printStack(ans);printStack(aim);if(count==2) {System.out.println();return;}if(A == '$' && a == '$') {System.out.println();return;}else {if(A == '#') System.out.println("success");else {System.out.print("" + A + "->" + getString(A,a));System.out.println();}}}/*** 打印头部*/public void PrintHead() {System.out.println("步骤\t"+"分析栈\t"+"余留栈\t"+"上个步骤所用产生式");}/*** 测试方法* @param args* @throws IOException */public static void main(String[] args) throws IOException {Analyzer ans = new Analyzer("./src/success.txt");//成功样例//Analyzer ans = new Analyzer("./src/failture.txt");//失败样例ans.readFile(); ans.analyse(); String str = ans.reStr();Analysis run = new Analysis(str);run.analyzer();}
}