簡單的詞法設計——DFA模擬程序


實驗一、簡單的詞法設計——DFA模擬程序

一、實驗目的

通過實驗教學,加深學生對所學的關於編譯的理論知識的理解,增強學生對所學知識的綜合應用能力,並通過實踐達到對所學的知識進行驗證。通過對 DFA 模擬程序實驗,使學生掌握詞法分析的實現技術,及具體實現方法。通過本實驗加深對詞法分析程序的功能及實現方法的理解 。

二、實驗環境

Windows 系統的 PC 機,可用 C++/C#/Java 等編程工具編寫,語言不限。

三、實驗內容

1、自己定義一個 DFA 或者一個右線性正規文法

示例如(僅供參考) G[S]:S→aU|bV U→bV|aQ

V→aU|bQ Q→aQ|bQ|e

2、利用合適數據結構存儲自動機,如


3、利用有窮確定自動機M=(K,Σ,f, S,Z)行為模擬程序算法,來對於任意給定的串,若屬於該語言時,該過程經有限次計算后就會停止並回答“是”,若不屬於,要么能停止並回答“不是”

K:=S;

c:=getchar;

while c<>eof do 

{K:=f(K,c);   

  c:=getchar;       };

if K is in Z then return (‘yes’)

                  else return (‘no’)

四、實驗方式與要求

1、設計的自動機程序要具有通用性,上機編程實現;

2、實驗報告格式要求書寫要點:概要設計(總體設計思想);詳細設計(程序主流程、自動機的存儲格式、關鍵函數的流程圖);結果分析(輸入與輸出結果、存在問題及有待改進善的地方、實驗心得);

3、實驗報告限4頁內。

設計思路:我們主要是用 Java 語言實現詞法分析的過程,需要處理 DFANFA 兩種狀態,所以在文末我們給出了測試樣例以及測試截圖,部分代碼給出了詳細的注釋。

實驗代碼如下:

package python;
import java.util.List;
import java.util.ArrayList;
import java.util.Scanner;
/**
 * @author Angel_Kitty
 * @createTime 2018年11月21日 上午2:23:33
 */
/**狀態轉換式構造類*/
class edge {
	char PriorityState;
	char ch;
	char NextState;
	edge(char p,char c, char n){
		PriorityState = p;
		ch = c;
		NextState = n;
	}
	@Override
	public String toString() {
		return "edge [PriorityState=" + PriorityState + ", ch=" + ch + ", NextState=" + NextState + "]";
	}
}
/**DFA的構造*/
public class DFA {
	static List<edge> listEdge = new ArrayList<edge>();//狀態集
	//static HashMap<edge, Character> mapEdge = new HashMap<>();
	static String S;//初態集
	static String Z;//終態集
	//flag is here
	static boolean judeZ(char ch){
		int j=0;
		for(; j<Z.length(); j++){
			if(Z.charAt(j)==ch) return true;
		}
		return false;
	}
	static void input() {
		Scanner in = new Scanner(System.in);
		String instr = null;
		String subStr[] = null;
		System.out.println("請輸入開始符:");
		S = in.next();
		System.out.println("請輸入終態集(終集符組成的一個字符串):");
		Z = in.next();
		System.out.println("請輸入正規文法以end結尾(形式如下圖):");
		System.out.println("----------");
		System.out.println("|  S-aU  |");
		System.out.println("|  S-bV  |");
		System.out.println("|  U-bV  |");
		System.out.println("|  ....  |");
		System.out.println("|  end   |");
		System.out.println("----------");
		while(in.hasNext()){
			instr = in.next();
			if("end".equals(instr)) break;
			subStr = instr.split("-|\\|");
			String s = subStr[0];//讀取一行f(轉換函數)
			for(int i=1; i<subStr.length; i++){
				edge e = null;
				if(subStr[i].length()==2){
					char c = subStr[i].charAt(0);//有窮符號表
					char n = subStr[i].charAt(1);//狀態集
					listEdge.add(new edge(s.charAt(0),c,n));//f(S,a)=U
				}
				
				if(subStr[i].length()==1){
					char c = subStr[i].charAt(0);
					listEdge.add(new edge(s.charAt(0),c,Z.charAt(0)));
				}
			}
		}
	}
	
	static char judeNextState(char s,char ch){
		for(int i=0; i<listEdge.size(); i++){
			if(s==listEdge.get(i).PriorityState && ch==listEdge.get(i).ch){
				return listEdge.get(i).NextState;
			}
		}
		return '0';
	}
	
	static void judeDFA(){
		Scanner in = new Scanner(System.in);
		System.out.println("請輸入要判斷的字符串:");
		while(in.hasNext()){
			String str = in.next();
			if(str.equals("#")){
				System.out.println("程序已退出,歡迎下次使用!");
				return;
			}
			char temp = S.charAt(0);
			int i=0;
			//System.out.println(temp+" "+mapEdge.get(e));
			for(; i<str.length(); i++){
				//System.out.println("temp="+temp);
				if(str.charAt(i)=='a'){
					temp = judeNextState(temp, 'a');
				}
				else if(str.charAt(i)=='b'){
					temp = judeNextState(temp, 'b');
				}
				else break;
			}
			//flag is here
			if(i>=str.length() && judeZ(temp)) System.out.println("此字符串“屬於”該文法!");
			else System.out.println("此字符串“不屬於”該文法!");
			System.out.println("再次判斷請輸入字符串(退出程序輸入#):");
		}
		
	}
	
	/*main*/
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		DFA.input();
		DFA.judeDFA();
	}
}

/*test example*/
/*
 *
//start symbol
S
//end symbol 
Q
//Regular Grammar1
S-aU
S-bV
U-bV
U-aQ
V-aU
V-bQ
Q-aQ
Q-bQ
end
//judge string
->test sample1: baab
->test sample2: abab
//start symbol
S
//end symbol 
Q,V
//Regular Grammer2
S-aU
S-bV
U-bV
U-aQ
Q-aQ
Q-bQ
end
//judge string
-> test sample1: ab
-> test sample2: abb
if you input '#',The program will exit. 
 * 
 * */

測試結果如下:


免責聲明!

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



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