编译原理LR(0)文法分析

实验五:LR(0)语法分析程序的设计

1.理解和掌握LR(0)文法的判断和分析过程
2.本实验要求设计一个LR(0)语法分析程序。
3.本实验要求自己独立完成,不允许抄袭别人的实验结果。
4.用C#或JAVA语言实现;

public class Experiment_5 {

    //终结符
    private static char[] VN = { 'E', 'A', 'B' };
    // 非终结符
    private static char[] VT = { 'a', 'b', 'c','d','#'};
    // 文法G
    private static String[] G = { "S':E","E:aA","E:bB","A:cA","A:d","B:cB","B:d" };
    // 判断的文法为
//    private static String s = "abab#";

    private static String  V = "abcd#EAB";

    // 创建一个栈
    private static Stack<String> stack = new Stack<String>();
    // 构造LR(1)分析表
    private static String[][] LR1 = {
            {"S2","S3","","","","1","",""},
            {"","","","","acc","","",""},
            {"","","S4","S10","","","6",""},
            {"","","S5","S11","","","","7"},
            {"","","S4","S10","","","8",""},
            {"","","S5","S11","","","","9"},
            {"r1","r1","r1","r1","r1","","",""},
            {"r2","r2","r2","r2","r2","","",""},
            {"r3","r3","r3","r3","r3","","",""},
            {"r5","r5","r5","r5","r5","","",""},
            {"r4","r4","r4","r4","r4","","",""},
            {"r6","r6","r6","r6","r6","","",""},
    };

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入要判断的句子:");
        String s = input.next();
        if (Judge(s) == 1){
            System.out.println("输入的字符串包含无法识别的字符!!!");
        }

        else {
            if (Accept(s)){
                System.out.println("输入的句子可以被接受!!!");
            }
            else{
                System.out.println("输入句子不能被接受!!!");
            }
        }
    }

    // 判断输入的字符串中是否包含无法识别的字符
    public static int Judge(String s) {
        int a = 1;
        for (int i = 0; i < s.length(); i++) {
            a = 1;
            for (int j = 0; j < VT.length; j++) {
                if (s.charAt(i) == VT[j]) {
                    a = 0;
                    break;
                }
            }
            if (a == 1) {
                return a;
            }
        }
        return a;
    }

    // 查询符号在分析表的位置
    private static int posiV(char c) {
        for (int i = 0; i < V.length(); i++) {
            if (c == V.charAt(i)){
                return i;
            }
        }
        return -1;
    }

    // 执行ACTION动作
    private static String ACTION(char c, int i) {
        if (posiV(c) <= (VT.length - 1)){
            return LR1[i][V.indexOf(String.valueOf(c))];
        }
        else{
            return null;
        }
    }

    // 执行GOTO动作
    private static int GOTO(char c, int i) {
        if(LR1[i][posiV(c)] != ""){
            return Integer.parseInt(LR1[i][posiV(c)]);
        }else {
            return 0;
        }
    }

    // 输出分析过程
    private static void printf(int a, String s, String s1, String s2, String s3, String s4) {
        System.out.printf("%-9d%-10s%-10s%-12s%-10s%-8s\n", a, s,s1,s2, s3, s4);
//        System.out.println(a+ "\t" +s+ "\t" +s1+ "\t" +s2+ "\t" +s3+ "\t" +s4);

    }

    // 判断句子是否可以接受
    private static boolean Accept(String s) {
        s += '#';
        // 定义一个字符串,来存放符号
        String stack = new String();
        stack += '#';
        // 定义一个字符串,存放状态
        String state = new String();
        state += '0';
        // 定义一个int变量来记录推导的步数
        int count = 1;
        // 定义一个指针
        int p = 0;
        String ss = "";
        System.out.printf("%-7s%-9s%-8s%-8s%-10s%-8s\n", "步骤", "状态栈","符号栈","剩余输入串", "ACTION", "GOTO");
        System.out.println("---------------------------------------------------------------");
        while (p < s.length()) {

            //判断状态 大于 S9这种数据
            int num = 0 ;
            if(state.charAt(state.length() - 1) ==')'){
                num = Integer.parseInt(state.substring(state.length()-3, state.length()-1));
            }else {
                num = Integer.parseInt(state.charAt(state.length() - 1) + "");
            }

            ss = ACTION(s.charAt(p), num);
//            System.out.println(ss);

            // 移入
            if (!ss.equals("") && ss.charAt(0) == 'S') {
                // 输出步骤
                printf(count, state, stack, s.substring(p), ss, "");
                // 新符号进栈
                stack += s.charAt(p);
                // 新状态进栈
                String nowState ;
                if(ss.length()>=3 ){
                    nowState = "("+ss.substring(1, 3)+")";
                }else {
                    nowState = String.valueOf(ss.charAt(1));
                }
                state += nowState;
                // 指针向后移一位
                p++;
                // 记步数加+
                count++;
            } else {
                // 规约
                if (!ss.equals("") && ss.charAt(0) == 'r') {
//                    System.out.println(ss);
                    String t = G[Integer.parseInt(ss.charAt(1) + "")];
                    // 计算栈中需要被规约的长度
                    int l = numberVT(t, stack);
                    // 从符号栈中出栈
                    stack = stack.substring(0, stack.length() - l);

                    // 从状态栈出栈
                    if(state.charAt(state.length() - 1) ==')'){
                        state= state.substring(0, state.length() - (l+3) );
                    }else {
                        state= state.substring(0, state.length() - l);
                    }
                    // 加入规约后的非终结符
                    stack += t.charAt(0);

                    int inputNum = 0 ;
                    if(state.charAt(state.length() - 1) ==')'){
                        inputNum = Integer.parseInt(state.substring(state.length()-3, state.length()-1));
                    }else {
                        inputNum = Integer.parseInt(state.charAt(state.length() - 1) + "");
                    }

                    int a = GOTO(t.charAt(0), inputNum);
                    state += a;
                    printf(count, state, stack, s.substring(p), ss, a + "");
                    count++;
                } else {
                    if (ss.equals("acc")) {
                        // 输出
                        printf(count, state, stack, s.substring(p), "接受", "");
                        System.out.println("---------------------------------------------------------------");
                        return true;
                    } else{
                        // 输出
                        printf(count, state, stack, s.substring(p), "出错", "");
                    }
                    System.out.println("---------------------------------------------------------------");
                    return false;
                }
            }
        }
        return false;
    }

    // 计算需要被规约的长度
    private static int numberVT(String s, String s1) {
        s = s.substring(2);
        int c = 0;
        for (int i = 0; i < s.length(); i++) {
            for (int j = 0; j < s1.length(); j++) {
                if ((s.charAt(i) == s1.charAt(j))) {
                    c++;
                    break;
                }
            }
        }
        return c;
    }
}

在这里插入图片描述

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值