java編寫簡單的語法分析預測程序


編譯原理課程中,編了一個簡單的語法分析預測程序,這個程序時根據固定的文法得到預測分析表,然后編寫程序來判斷表達式是否會正確推到出來。

前提是程序沒有左遞歸符合LL(1)文法:

文法如下:

E→TE'

E’ →+TE'|ε

T→FT'

T’ →*FT'|ε

 F→(E)|i

為了程序便於編寫將E'替換為e,T'替換為t

(2)FIRST集

FIRST(E)={(,i}; 

FIRST(E’)={+, ε};

FIRST(T)={(,i};

FIRST(T’)={ *, ε};

FIRST(F)={(,i};

(3)FALLOW集

FOLLOW(E)={),#};

FOLLOW(E’)={),#};

FOLLOW(T)={+,),#};

FOLLOW(T’)={+,),#};

FOLLOW(F)={*,+,),#};

(4)預測分析表

 

i

+

*

(

)

#

E

E->TE’

 

 

E->TE’

 

 

E’

 

E’->+TE’

 

 

E’->ε

E’->ε

T

T->FT’

 

 

T->FT’

 

 

T’

 

T’->ε

T’->*FT’

 

T’->ε

T’->ε

F

F->i

 

 

F->(E)

 

 

 一、Stack.java

public class Stack {
    private char s[];
    private int top;
    private int base;
    private final int MAX = 200;
    /**
     * 
    * <p>Title: </p>
    * <p>Description: 初始化棧</p>
     */
    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;
        }
    }
    /**
     * 
    * <p>Title: getTop</p>
    * <p>Description: 獲取棧頂元素</p>
    * @return 返回棧頂元素
     */
    public char getTop() {
        return s[top-1];
    }
    /**
     * 
    * <p>Title: push</p>
    * <p>Description: 進棧方法</p>
    * @param str 進棧的字符
     */
    public void push(String str) {
        for (int i = str.length() - 1; i >= 0; i--) {
            s[top++] = str.charAt(i);
        }
    }
    /**
     * 
    * <p>Title: clear</p>
    * <p>Description: 清空棧</p>
     */
    public void clear() {
        top = base;
    }
    
    /**
     * 
    * <p>Title: pop</p>
    * <p>Description: 出棧</p>
    * @return 棧頂元素出棧並返回出棧的元素
     */
    public char pop() {
        return s[--top];
    }
    /**
     * 
    * <p>Title: size</p>
    * <p>Description: 返回棧中元素個數</p>
    * @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();
    }
}

二、GrammarAnalyze.java

package grammarAnalyze;

public class GrapparAnalyze {
	//分析表將E'替換為e,T'替換t
	private String tab[][] = { 
		{ "$", "i",  "+",   "*",  "(",   ")", "#" },
		{ "E", "Te", "$",   "$",  "Te", "$",  "$" },
		{ "e", "$", "+Te", "$",   "$",  "ε",  "ε" },
		{ "T", "Ft", "$",   "$",  "Ft","$",  "$" },
		{ "t", "$",  "ε",   "*Ft", "$", "ε",  "ε" },
		{ "F",  "i",  "$",   "$",  "(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 '+':
			return 2;
		case '*':
			return 3;
		case '(':
			return 4;
		case ')':
			return 5;
		case '#':
			return 6;
		default:
			return -1;
		}
	}
	public int line(char c) { //判定預測表中的行
		switch (c) {
		case 'E':
			return 1;
		case 'e':
			return 2;
		case 'T':
			return 3;
		case 't':
			return 4;
		case 'F':
			return 5;
		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")) { 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; } 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; } }

  三、主程序GrammarMain.java

package grammarAnalyze;

import java.util.Scanner;

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();
			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;
				}
			}
		}

	}
	
}

  四、測試運行

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM