LL(0), LR(0), SLR(1), LR(1), LALR(1)的比较
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;
public class Ex5 {
private String input;
private String lookahead;
private int nextIndex;
private Stack<String> stack = new Stack<>();
private final Map<String, String> map = new HashMap<>() {
{
// 匿名子类实例,中间添加静态代码块用于初始化
// 手工录入分析表... 感觉好low...
// Action 表格式为 <"输入符号,状态","表中状态">
// Goto 表格式为 <"非终结符,状态", "转移后状态">
// 《编译原理》- 陈意云 第三版 P72
put("id,0", "s5");
put("(,0", "s4");
put("E,0", "1");
put("T,0", "2");
put("F,0", "3");
put("+,1", "s6");
put("$,1", "acc");
put("+,2", "r2");
put("*,2", "s7");
put("),2", "r2");
put("$,2", "r2");
put("+,3", "r4");
put("*,3", "r4");
put("$,3", "r4");
put("),3", "r4");
put("id,4", "s5");
put("(,4", "s4");
put("E,4", "8");
put("T,4", "2");
put("F,4", "3");
put("+,5", "r6");
put("*,5", "r6");
put("),5", "r6");
put("$,5", "r6");
put("id,6", "s5");
put("(,6", "s4");
put("T,6", "9");
put("F,6", "3");
put("F,7", "10");
put("id,7", "s5");
put("(,7", "s4");
put("+,8", "s6");
put("),8", "s11");
put("+,9", "r1");
put("*,9", "s7");
put("),9", "r1");
put("$,9", "r1");
put("+,10", "r3");
put("*,10", "r3");
put("),10", "r3");
put("$,10", "r3");
put("+,11", "r5");
put("*,11", "r5");
put("),11", "r5");
put("$,11", "r5");
}
};
private final Map<String, String> reduceMap = new HashMap<>() {
{
// 归约表
// <"产生式序号","非终结符,右产生式符号个数">
put("1", "E,3");
put("2", "E,1");
put("3", "T,3");
put("4", "T,1");
put("5", "F,3");
put("6", "F,1");
}
};
public Ex5() {
input();
process();
}
private void process() {
stack.push("0");
String search;
String result;
while(true){
search = lookahead + "," + stack.peek(); // 组装搜索串
result = map.get(search); // 获得结果
while (null == result){
System.out.println("Error! cannot find action[" +search + "]");
nextToken(); // 跳过当前符号
search = lookahead + "," + stack.peek(); // 组装搜索串
System.out.println("try action[" + search + "]");
result = map.get(search); // 获得结果
}
if(result.charAt(0) == 's'){
// 移进操作
stack.push(lookahead); // 非终结符入栈
nextToken();
result = result.replace("s", ""); // 删除s
stack.push(result); // 状态入栈
System.out.println("shift!");
}else if(result.charAt(0) == 'r'){
// 归约操作
search = result.replace("r", ""); // 删除r,获取产生式序号
result = reduceMap.get(search); // 获取非终结符和右产生式符号个数
// 输出提示
System.out.println("reduce according to (" + search +") Production!" );
String nonTerminal = result.charAt(0) + ""; // 非终结符
int popTimes = 2 *
Integer.parseInt(result.replace(nonTerminal+",", "")); // 弹栈次数
// 弹栈
for(int i = 0; i < popTimes; i++){
stack.pop();
}
// 转移操作
// 此时非终结符未入栈,取最上面的状态与终结符构成查询串,查询 GOTO
search = nonTerminal + "," + stack.peek();
result = map.get(search);
// 非终结符以及查询到的状态入栈
stack.push(nonTerminal);
stack.push(result);
}else if(result.charAt(0) == 'a'){
// 接受操作
System.out.println("Accept!");
break;
}else{
// 错误处理
System.out.println("Map Value Error! Exit!");
System.exit(0);
}
}
}
public static void main(String[] args) {
new Ex5();
}
public void input() {
Scanner scanner = new Scanner(System.in);
System.out.println("target grammar : \n"
+ "(1)E -> E + T\n"
+ "(2)E -> T\n"
+ "(3)T -> T * F\n"
+ "(4)T -> F\n"
+ "(5)F -> (E)\n"
+ "(6)F -> id"
);
System.out.print("Please input a string to check:");
input = scanner.nextLine() + "$";
nextToken();
}
public void nextToken() {
lookahead = input.charAt(nextIndex) + "";
nextIndex++;
if (lookahead.equals("i")) {
lookahead = "id";
nextIndex++;
}
}
}