實驗一、詞法分析實驗
商業軟件工程專業 張樹恆 201506110093
一、 實驗目的
通過設計一個詞法分析程序,對詞法進行分析,加強對詞法的理解,掌握對程序設計語言的分解和理解。
二、 實驗內容和要求
在原程序中輸入源代碼
- 對字符串表示的源程序
- 從左到右進行掃描和分解
- 根據詞法規則
- 識別出一個一個具有獨立意義的單詞符號
- 以供語法分析之用
- 發現詞法錯誤,則返回出錯信息
在源程序中,自動識別單詞,把單詞分為五種,並輸出對應的單詞種別碼。
- 識別關鍵字:main if int for while do return break continue,該類的單詞碼為1.
- 識別標識符:表示各種名字,如變量名、數組名、函數名等,如char ch, int syn, token,sum,該類的單詞碼為2.
- 運算符:+、-、*、/、=、>、<、>=、<=、!=
- 分隔符:,、;、{、}、(、)
- 常數,如123,4587
各種單詞符號對應的種別碼。
輸出形式:
- 二元式
– (單詞種別,單詞自身的值)
- 單詞種別,表明單詞的種類,語法分析需要的重要信息
– 整數碼
- 關鍵字、運算符、界符:一符一碼
- 標識符:10, 常數:11
- 單詞自身的值
– 標識符token、常數sum
– 關鍵字、運算符、界符token
三、 實驗方法、步驟及結果測試
- 1. 源程序名:編譯原理實驗報告中源程序名算法分析.c
可執行程序名:編譯原理實驗報告.exe
- 2. 原理分析及流程圖
- 3. 主要程序段及其解釋:
import java.awt.*;
import java.util.Scanner;
/**
* Created by s2002 on 2016/9/30.
*/
public class com {
public static void main(String[] args) {
//限制字符串最大值
final int MAX_LEN = 100;
//關鍵字
String[] key_word = new String[]{"begin","end","if","then","while","do"};
//錄入用戶輸入
Scanner input = new Scanner(System.in);
System.out.print("Please input a string <end with '#'>:");
String uString = input.nextLine();
char[] analyseData = new char[MAX_LEN];
int index = 0, key = 0;
List list = new List();
do {
String compareStr = null;
char temp = uString.charAt(index);
list = extactCharacters(temp, analyseData, key_word, uString, index, compareStr);
if (list.getItemCount() == 0) {
index++;
continue;
}
// 規定List的第一個元素為index,第二個元素為key
index = Integer.parseInt(list.getItem(0));
key = Integer.parseInt(list.getItem(1));
String words = list.getItem(2);
System.out.println("< " + key + " ," + words + " >");
} while (key != 0);
}
public static List extactCharacters(char temp, char[] analyseDate, String[] keywords, String uString, int index,
String compareStr) {
int keyID = -1, m = 0;
List list = new List();
//判斷下一個讀入的字符是否為空格,若讀取到空格則跳過,提取下一個字符進行判斷
while (temp != ' ') {
//判斷當前字符是字母或者數字和字母的組合
if (temp >= 'a' && temp <= 'z') {
m = 0;
// 當讀取到不是大小寫字母或者數字時候判斷為一個單詞讀取完成
while (temp >= 'a' && temp <= 'z' || temp >= 'A' && temp <= 'Z' || temp >= '0' && temp <= '9') {
analyseDate[m++] = temp;
compareStr += temp + "";
temp = uString.charAt(++index);
}
// 與讀取出來的字符判斷是否為關鍵字
compareStr = compareStr.substring(4);
for (int i = 0; i < 6; i++) {
if (compareStr.equals(keywords[i])) {
keyID = i + 1;
list.add(index + "");
list.add(keyID + "");
list.add(compareStr);
return list;
}
}
//若為非關鍵字就當作為標識符
keyID = 10;
list.add(index + "");
list.add(keyID + "");
list.add(compareStr);
return list;
}
//判斷當前字符是否為數字
else if (temp >= '0' && temp <= '9') {
m = 0;
String tempTokens = null;
// 對后面的字符進行判斷是否為數字
while (temp >= '0' && temp <= '9') {
analyseDate[m++] = temp;
tempTokens += temp;
temp = uString.charAt(++index);
}
// 不是數字則返回種別碼,結束當前方法
keyID = 11;
tempTokens = tempTokens.substring(4);
list.add(index + "");
list.add(keyID + "");
list.add(tempTokens + "");
return list;
}
m = 0;
//判斷當前字符是否為其他關系運算符
String token = null;
switch (temp) {
case '<':
// String token = null;
analyseDate[m++] = temp;
token += temp;
if (uString.charAt(++index) == '=') {
analyseDate[m++] = temp;
keyID = 22;
token += uString.charAt(index++);
} else if (uString.charAt(++index) == '>') {
analyseDate[m++] = temp;
keyID = 21;
token += uString.charAt(index++);
} else {
keyID = 23;
}
list.add(index + "");
list.add(keyID + "");
token = token.substring(4);
list.add(token);
return list;
case '>':
analyseDate[m++] = temp;
token += temp;
if (uString.charAt(++index) == '=') {
keyID = 24;
analyseDate[m++] = temp;
token += uString.charAt(index++);
} else {
keyID = 20;
}
list.add(index + "");
list.add(keyID + "");
token = token.substring(4);
list.add(token);
return list;
case ':':
analyseDate[m++] = temp;
token += temp;
if (uString.charAt(++index) == '=') {
keyID = 18;
// analyseDate[m++] = temp;
analyseDate[m++] = uString.charAt(index);
token += uString.charAt(index++);
} else {
keyID = 17;
}
list.add(index + "");
list.add(keyID + "");
token = token.substring(4);
list.add(token);
return list;
case '*':
keyID = 13;
break;
case '/':
keyID = 14;
break;
case '+':
keyID = 15;
break;
case '-':
keyID = 16;
break;
case '=':
keyID = 25;
break;
case ';':
keyID = 26;
break;
case '(':
keyID = 27;
break;
case ')':
keyID = 28;
break;
case '#':
keyID = 0;
break;
default:
keyID = -1;
break;
}
analyseDate[m++] = temp;
list.add(++index + "");
list.add(keyID + "");
list.add(temp + "");
return list;
}
return list;
}
}
- 4. 運行結果及分析
輸入源代碼:begin x:=0; end#
符合個字符的單詞碼
四、 實驗總結
學會編寫一個簡單的詞法分析程序,學會了利用詞法分析程序分析源代碼,逐個單詞進行分析拆分,把標識符,保留字區分,並且能識別出空格,並把數據能從文件中讀出來,對代碼的理解更加的深刻。