Mess_LR(0)——自下而上分析

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++;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值