/**
* E→TE' E'→+TE' |ε T→FT' T'→*FT'|ε F→(E)|id
* FOLLOW( E')={ ), # }; FOLLOW( T')={ +, ), # };
FIRST(TE')={(,id}; FIRST(id)={id} FIRST(+TE')={+};
FIRST(FT')={(,id}; FIRST(*FT')={*}; FIRST((E))={(}
*
*/
package 编译原理;
import java.util.Scanner;
import java.util.Stack;
//预测分析表
class AnalysisTable {
public String[][] table = {
/*0*/{"TE1","","","TE1","",""},//E
/*1*/{"","+TE1","","","$","$"},//E1
/*2*/{"FT1","","","FT1","",""},//T
/*3*/{"","$","*FT1","","$","$"},//T1
/*4*/{"i","","","(E)","",""}//F
};
}
public class p4{
public static void main(String[] args) {
Stack<String> st = new Stack<String>();
Scanner sc = new Scanner(System.in);
System.out.print("请输入以#结尾的字符串:");
String s = sc.nextLine();
sc.close();
st.push("#");
st.push("E");
System.out.println("缓冲区"+s+"\t\t\t\t"+"当前栈"+st.toString()+"\t\t\t\t"+"无产生式");
AnalysisTable table = new AnalysisTable();
// while(st.peek()!="#" && s.charAt(0)!='#')!st.empty()
while(!st.empty()) {//只要栈不为空
String temp =""+s.charAt(0);
if(st.peek().equals(temp)) {
if(st.peek().equals("#")) {//如果栈中只剩#,结束循环
break;
}
st.pop();//栈顶out
s = s.substring(1);//缓冲区去掉第一个字符
System.out.print("缓冲区"+s+"\t\t\t\t");
System.out.print("当前栈"+st.toString()+"\t\t\t\t");
System.out.println("无产生式");//相等时无产生式
continue;
}
//从预测分析表中得出value
else if(!st.peek().equals(temp)) {
int row = analyNoneCharacter(st.peek());
int column = AnalysisTCharacter(temp);
if (row == -1 || column == -1) {
System.out.println(s + "No");
continue;
}
String value = table.table[row][column];
if(value.equals("$") ) {//如果产生式为空,栈顶pop
String v = st.pop();
System.out.print("缓冲区"+s+"\t\t\t\t");
System.out.print("当前栈"+st.toString()+"\t\t\t\t");
System.out.println("产生式"+v+"->$"+"\t\t\t\t");
continue;
}
String p = st.pop();//不匹配时,栈顶元素out
if(value.equals("TE1")) {
//st.pop();
st.push("E1");
st.push("T");
}
else if(value.equals("FT1")) {
//st.pop();
st.push("T1");
st.push("F");
}
else if(value.equals("i")) {
//st.pop();
st.push("i");
}
else if(value.equals("(E)")) {
//st.pop();
st.push(")");
st.push("E");
st.push("(");
}
else if(value.equals("*FT1")) {
//st.pop();
st.push("T1");
st.push("F");
st.push("*");
}
else if(value.equals("+TE1")) {
//st.pop();
st.push("E1");
st.push("T");
st.push("+");
}
System.out.print("缓冲区"+s+"\t\t\t\t");
System.out.print("当前栈"+st.toString()+"\t\t\t\t");
System.out.println("产生式"+p+"->"+value+"\t\t\t\t");//out->value
//System.out.println(st.peek()+s.charAt(0));
continue;
}
}//while
}
//分析预测分析表中的x
public static int analyNoneCharacter(String ch) {
String c = ch;
int flag = -1;
switch (c) {
case "E":
flag = 0;
break;
case "E1":
flag = 1;
break;
case "T":
flag = 2;
break;
case "T1":
flag = 3;
break;
case "F":
flag = 4;
break;
}
return flag;
}
//分析预测分析表中的y
public static int AnalysisTCharacter(String s) {
char ch = s.charAt(0);
switch (ch) {
case 'i':
return 0;
case '+':
return 1;
case '*':
return 2;
case '(':
return 3;
case ')':
return 4;
case '#':
return 5;
}
return -1;
}
}
编译原理之语法分析器的实验与设计,花了我好久时间。唉,其实就那样,但当时代码就是写不出来,写出来的结果也是错的。但还好最后写出来了,坚持就是胜利,哈哈哈哈哈
结果: