1. 程式人生 > >編譯原理 實驗一 詞法分析之預處理

編譯原理 實驗一 詞法分析之預處理

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Main {

	// res字串陣列儲存經過處理之後的程式
	static int cnt = 0;
	static String[] res = new String[10000];
	// 標誌註釋的開始和結束
	static boolean flagBegin = false;
	static boolean flagEnd = false;

	public static void main(String[] args) {
		// 這裡從指定路徑讀取檔案,也可以由控制檯輸入檔案路徑和檔名
		File file = new File("D:\\plo.txt");
		BufferedReader reader = null;
		String temp = null;
		StringBuilder sb = new StringBuilder(); // 儲存原始檔
		try {
			reader = new BufferedReader(new FileReader(file));
			while ((temp = reader.readLine()) != null) { // 按行讀入同時處理原始檔
				sb.append(temp + "\n");
				res[cnt] = temp;
				compileFile(temp);
				// 不是註釋,輸出
				if (flagBegin == false && flagEnd == false) {
					System.out.println(res[cnt++]);
				}
				// 仍然是註釋,且註釋尚未結束不輸出
				else if (flagBegin == true && flagEnd == false) {
					continue;
				}
				// 註釋結束時,修改flag
				else if (flagBegin == true && flagEnd == true) {
					flagBegin = false;
					flagEnd = false;
					continue;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally { // 關閉檔案讀入流
			if (reader != null) {
				try {
					reader.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		// 輸出原始檔
		System.out.println("\n以下是原始檔:\n");
		System.out.println(sb.toString());
	}

	// 處理多餘空格,並刪除註釋
	private static void compileFile(String temp) {
		// 判斷是否有註釋,並獲取註釋的位置
		int index1 = temp.indexOf("//");
		int index2 = temp.indexOf("(*");
		int index3 = temp.indexOf("*)");
		// 如果一整行都是空格,直接跳過該行,判斷下一行
		if (temp.length() == 0) {
			flagBegin = flagEnd = true;
			return;
		} else {
			if (index1 >= 0) {
				// 單行註釋,分兩種情況,一行都是註釋和有程式碼有註釋
				if (index1 == 0)
					flagBegin = flagEnd = true;
				else
					temp = temp.substring(0, index1);
			} else if (index2 >= 0)
				flagBegin = true;
			else if (index3 >= 0)
				flagEnd = true;
		}

        //去除空格,回車ASCII碼13,換行ASCII碼10,空格ASCII碼32
		StringBuilder strb = new StringBuilder();
		char[] ch = new char[temp.length()];
		ch = temp.toCharArray();
		for (int i = 0; i < ch.length - 1; i++) {
			if (ch[i] != ' ') {
				strb.append(ch[i]);
			}
			if (ch[i] == ' ' && ch[i + 1] != ' ' && (i > 0)) {
				strb.append(ch[i]);
			}
		}
		// 上面的for迴圈,由於判斷ch[i+1],當i=ch.length - 1時,i+1越界,所以單獨判斷最後一個字元
		if (ch[ch.length - 1] != ' ')
			strb.append(ch[ch.length - 1]);
		// 刪除每一行開始的空格
		if (ch[0] == ' ')
			strb.deleteCharAt(0);
		res[cnt] = strb.toString();
	}
}