预测分析表(java实现)
1. 文法
前提是程序没有左递归符合LL(1)文法:
文法如下:
L → E;L|ε
E → TE’
E’ → +TE’|-TE’|ε
T → FT’
T’ → *FT’|/FT’|modFT’|ε
F → (E)|id|num
为了程序便于编写将E’替换为e,T’替换为t,num替换成n,mod替换成m,id替换成i
2. FIRST集合
FIRST(F)={(,i,num};
FIRST(E’)={+, -,ε};
FIRST(T)={(,i,num};
FIRST(T’)={*,/,mod,ε};
FIRST(E)={ (,i,num};
3. FALLOW集合
FOLLOW(L)={#};
FOLLOW(E)={),;};
FOLLOW(E’)={),:};
FOLLOW(T)={+,-,;,)};
FOLLOW(T’)={+,-,;,)};
FOLLOW(F)={+,-,*,/,mod,),;};
4. 预测分析表
| id | n | + | - | * | / | m | ( | ) | ; | # | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| E | E;L | E;L | E;L | ε | |||||||
| E | Te | Te | Te | ||||||||
| e | +Te | -Te | ε | ε | |||||||
| T | Ft | Ft | Ft | ||||||||
| t | ε | ε | *Ft | /Ft | mFt | ε | ε | ||||
| F | id | n | (E) | 
5. 代码实现
package com.xawl.oo;
import java.util.Scanner;
/**
 * @author qin jin
 * @date 2022/6/6 11:14
 *
 *  为了程序便于编写将E'替换为e,T'替换为t,mod替换成m,num替换成n
 */
public class GrammarMain {
    public static void main(String[] args){
        boolean isContinue = true;
        while(isContinue) {
            GrapparAnalyze analyze = new GrapparAnalyze();
            Scanner scan = new Scanner(System.in);
            System.out.println("请输入你要翻译的表达式:");
            String inputExpression = scan.nextLine();
            inputExpression = inputExpression.replace("id","i");
            String srcdata = inputExpression.trim();
            if("".equals(srcdata) || srcdata == null) {
                System.out.println("输入表达式为空,请重新输入");
            }else {
                String result = analyze.work(srcdata);
                System.out.println(result);
                System.out.println("是否继续?y/n");
                String yn = scan.nextLine();
                if("no".equals(yn) || "n".equals(yn)) {
                    isContinue = false;
                }
            }
        }
    }
}
//自定义栈
class Stack {
    private char s[];
    private int top;
    private int base;
    private final int MAX = 200;
    /* 初始化栈 */
    public Stack() {
        initStack();
    }
    private void initStack() {
        s = new char[MAX];
        base = 0;
        top = 0;
    }
    public boolean isEmpty() {
        if(top == base) {
            return true;
        }else {
            return false;
        }
    }
    /**
     * @Description: 获取栈顶元素
     * @return 返回栈顶元素
     */
    public char getTop() {
        return s[top-1];
    }
    /**
     * @Description: 进栈方法
     * @param str 进栈的字符
     */
    public void push(String str) {
        for (int i = str.length() - 1; i >= 0; i--) {
            s[top++] = str.charAt(i);
        }
    }
    /**
     * @Description: 清空栈
     */
    public void clear() {
        top = base;
    }
    /**
     * @Description: 出栈
     * @return 栈顶元素出栈并返回出栈的元素
     */
    public char pop() {
        return s[--top];
    }
    /**
     * @Description: 返回栈中元素个数
     * @return 栈中元素个数
     */
    public int size() {
        return top;
    }
    /**
     * 打印栈里面的元素
     */
    public String toString() {
        StringBuffer tempStack = new StringBuffer();
        for (int i = 0; i < top; i++) {
            tempStack.append(s[i]);
        }
        return tempStack.toString();
    }
}
//分析器
class GrapparAnalyze {
    //分析表将E'替换为e,T'替换t,$为空
    private String tab[][] = {
            { "$",  "i",   "n",  "+",  "-",   "*",   "/",   "m",  "(",    ")",  ";", "#" },
            { "L", "E;L", "E;L", "$",  "$",   "$",   "$",   "$",  "E;L",  "$",  "$",  "ε" },
            { "E", "Te" ,  "Te", "$",   "$",  "$",   "$",   "$",  "Te",   "$",  "$",  "$"  },
            { "e",  "$" ,  "$" , "+Te", "-Te", "$",  "$",   "$",   "$",   "ε",  "ε",  "$" },
            { "T", "Ft",   "Ft",  "$",   "$",   "$", "$",   "$",  "Ft",   "$",  "$",  "$" },
            { "t",  "$",    "$",   "ε",  "ε",  "*Ft", "/Ft", "mFt", "$",  "ε",  "ε",  "$"  },
            { "F",  "i",    "n",   "$",   "$",  "$",    "$",   "$", "(E)", "$", "$", "$"  }
    };
    private String input;  //input中存放输入的表达式
    private StringBuffer tempBuffer;    //存放要输出的字符串
    private int ptr, row, col, step; //指针,预测表中的行,列,当前步骤
    private boolean symbol;
    private Stack stack;
    public GrapparAnalyze(){
        stack = new Stack();
        tempBuffer = new StringBuffer();
        symbol=true;
        input="";
        stack.clear();
        stack.push("#");
        row=1;
        ptr=0;
        step=1;
    }
    public int column(char c) {  //判断预测表中的列
        switch (c) {
            case 'i':
                return 1;
            case 'n':
                return 2;
            case '+':
                return 3;
            case '-':
                return 4;
            case '*':
                return 5;
            case '/':
                return 6;
            case 'm':
                return 7;
            case '(':
                return 8;
            case ')':
                return 9;
            case ';':
                return 10;
            case '#':
                return 11;
            default:
                return -1;
        }
    }
    public int line(char c) { //判定预测表中的行
        switch (c) {
            case 'L':
                return 1;
            case 'E':
                return 2;
            case 'e':
                return 3;
            case 'T':
                return 4 ;
            case 't':
                return 5;
            case 'F':
                return 6;
            default:
                return -1;
        }
    }
    public void show(String str) {
        tempBuffer.append(String.format("%-7d%-14s%-20s%-20s\r\n",
                step, filter(stack.toString()), filter(input.substring(ptr)), filter(str)));
        step++;
    }
    public void analyse() {
        stack.push(tab[row][0]);   //预测表中的第一个元素‘E’
        show("初始化");
        String tmp;
        char ctmp;   //栈顶元素
        while (!(input.charAt(ptr) == '#' && stack.getTop() == '#')) {
            ctmp = stack.getTop();//获取栈顶的元素
            if (input.charAt(ptr) == ctmp) { //与栈顶元素比较
                stack.pop();
                ptr++;
                show("" + ctmp + "匹配");
                continue;
            }
            //判断ptr位置的终结符所在预测表的列位置
            col = column(input.charAt(ptr));
            if (col == -1) {
                symbol = false;
                show("未定义的字符");
                ptr++;
                break;
            }
            //判断栈顶位置所在预测表的行位置
            row = line(ctmp);
            if (row == -1) {
                symbol = false;
                show("出错");
                stack.pop();
                if (input.charAt(ptr) != '#') {
                    ptr++;
                }
                continue;
            }
            tmp = tab[row][col];
            if (tmp.charAt(0) == '$') {
                symbol = false;
                show("出错");
                stack.pop();
                if (input.charAt(ptr) != '#') {
                    ptr++;
                }
            } else if (tmp.charAt(0) == 'ε') {
                stack.pop();
                show("" + ctmp + "->" + 'ε');
            } else {
                stack.pop();
                stack.push(tmp);
                show("" + ctmp + "->" + tmp);
            }
        }
    }
    //过滤方法将打印的字符串中e和t替换为E'和T'
    public String filter(String src) {
        if(src.contains("e") || src.contains("t")|| src.contains("i")|| src.contains("m")|| src.contains("n")) {
            StringBuffer result = new StringBuffer();
            char item;
            for(int i = 0;i < src.length(); i++) {
                item = src.charAt(i);
                if(item == 'e') {
                    result.append("E'");
                    continue;
                }else if(item == 't') {
                    result.append("T'");
                    continue;
                }else if(item == 'i'){
                    result.append("id");
                    continue;
                }else if(item == 'n'){
                    result.append("num");
                    continue;
                }else if(item == 'm'){
                    result.append("mod");
                    continue;
                }
                result.append(item);
            }
            return result.toString();
        }else {
            return src;
        }
    }
    public String work(String inputExpression) {
        input = inputExpression + '#';
        symbol = true;
        tempBuffer.append(String.format("%-8s%-20s%-20s%-20s\r\n",
                "步骤","分析栈","剩余输入栈","所用产生式"));
        analyse();
        if (symbol) {
            tempBuffer.append("\r是正确的符号串\r");
            return tempBuffer.toString();
        } else {
            tempBuffer.append("\r不是正确的符号串\r");
            return tempBuffer.toString();
        }
    }
    public StringBuffer getTempBuffer() {
        return tempBuffer;
    }
    public void setTempBuffer(StringBuffer tempBuffer) {
        this.tempBuffer = tempBuffer;
    }
    public Stack getStack() {
        return stack;
    }
    public void setStack(Stack stack) {
        this.stack = stack;
    }
    public String[][] getTab() {
        return tab;
    }
    public void setTab(String[][] tab) {
        this.tab = tab;
    }
    public String getInput() {
        return input;
    }
    public void setInput(String ns) {
        this.input = ns;
    }
    public int getPtr() {
        return ptr;
    }
    public void setPtr(int ptr) {
        this.ptr = ptr;
    }
    public int getRow() {
        return row;
    }
    public void setRow(int row) {
        this.row = row;
    }
    public int getCol() {
        return col;
    }
    public void setCol(int col) {
        this.col = col;
    }
    public int getStep() {
        return step;
    }
    public void setStep(int step) {
        this.step = step;
    }
    public boolean isBoo() {
        return symbol;
    }
    public void setBoo(boolean boo) {
        this.symbol = boo;
    }
}
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号