LL(1)分析過程程式設計

路過蜻蜓~發表於2020-12-06

LL(1)分析過程程式設計

文法:
E->T{+T}
T->F{*F}
F->i|’(‘E’)’

import java.util.Stack;

public class Demo1 {
    private static String[][] M;//預測分析表
    private static Stack<Character> stack;//符號棧

    static {//初始化預測分析表  與符號棧
        stack = new Stack<>();
        stack.push('#');
        stack.push('E');
        M = new String[6][7];
        for (int i = 0; i < M.length; i++) {
            for (int j = 0; j < M[0].length; j++) {
                M[i][j] = "";
            }
        }
        //給預測分析表賦值
        M[0][1] = "i";
        M[0][2] = "+";
        M[0][3] = "*";
        M[0][4] = "(";
        M[0][5] = ")";
        M[0][6] = "#";

        M[1][0] = "E";
        M[2][0] = "e";
        M[3][0] = "T";
        M[4][0] = "t";
        M[5][0] = "F";

        M[1][1] = "Te";
        M[3][1] = "Ft";
        M[5][1] = "i";
        M[2][2] = "+Te";
        M[4][2] = " ";
        M[4][3] = "*Ft";
        M[1][4] = "Te";
        M[3][4] = "Ft";
        M[5][4] = "(E)";
        M[2][5] = " ";
        M[4][5] = " ";
        M[2][6] = " ";
        M[4][6] = " ";

    }
    //分析過程
    public static void method(String string) {
        for (int i = 0; i < string.length(); ) {
            char input = string.charAt(i);
            char peek = stack.peek();
//            System.out.println("input:" + input + "   peek:" + peek);
            if (input == peek && input != '#') {//匹配
                printStack();
                System.out.printf("%10s",input);
                System.out.println("\t\t匹配,彈出棧頂符號" + peek + ",並讀取下一個輸入符號" + string.charAt(i + 1));
                stack.pop();//彈出棧頂元素  讀取下一個輸入字元
                i++;
                continue;
            }
            if (input == peek && input == '#') {//分析完成
                if (stack.size() == 1) {//符號棧中只剩#
                    printStack();
                    System.out.printf("%10s",input);
                    System.out.println("\t\t匹配,分析成功");
                    break;
                }
            }
            int row = findRow(String.valueOf(peek));//求行
            int col = findCloum(String.valueOf(input));//求列
//            System.out.println("row " + row + "   col" + col);
            String s = M[row][col];//分析表中的字串
            if (" ".equals(s)) {//當T->空
                printStack();
                System.out.printf("%10s",input);
                System.out.println("\t\t彈出棧頂符號" + peek + ",因為M[" + peek + "," + input + "]中" + peek + "->空,故不壓棧");
                stack.pop();
            } else if (!s.equals("") && s.length() > 0) {//不為空
                printStack();
                System.out.printf("%10s",input);
                System.out.println("\t\t彈出棧頂符號" + peek + ",將M[" + peek + "," + input + "]中" + peek + "->" + s + "逆序壓棧");
                stack.pop();
                for (int j = s.length() - 1; j >= 0; j--) {
                    stack.push(s.charAt(j));
                }
            }

        }
    }
    //求行數  E在哪一行
    public static int findRow(String s) {
        for (int i = 1; i < M.length; i++) {
            if (s.equals(M[i][0])) {
                return i;
            }
        }
        return -1;
    }
    //求列數 i在哪一列
    public static int findCloum(String s) {
        for (int i = 1; i < M[0].length; i++) {
            if (s.equals(M[0][i])) {
                return i;
            }
        }
        return -1;
    }
    //列印符號棧
    public static void printStack() {
        int i=0;
        for (i = 0; i < stack.size(); i++) {
            System.out.print(stack.get(i));
        }
        for(;i<9;i++){
            System.out.printf(" ");
        }
    }

    public static void main(String[] args) {
       /* for(int i=0;i<M.length;i++){
            for(int j=0;j<M[0].length;j++){
                System.out.printf(M[i][j]+" ");
            }
            System.out.println();
        }*/
        System.out.println("符號棧\t\t當前輸入符號\t\t說明");
        String s = "i+i*i#";
        method(s);
    }
}

相關文章