編譯原理實驗一 -無符號數的詞法分析程式
阿新 • • 發佈:2022-03-15
一、實驗目的和要求:
1.掌握詞法分析的基本思想,並用高階語言編寫無符號數的詞法分析程式。
2.要求從鍵盤上輸入一串字元(包括字母、數字等),最後以“;”結束,編
寫程式識別出其中的無符號數
二、實驗平臺:
Java語言
三、主要實驗內容及結果:
實驗內容:
詞法分析的主要任務是:掃描源程式,識別單詞,生成屬性字。單詞的種類一般分為四種:關鍵字、識別符號、常數、特殊符號,無符號數是常數中的一種,無符號數的詞法分析難點在於帶指數的無符號數的識別。
無符號數文法規則可定義如下:
<無符號數>→<無符號實數>│<無符號整數>
<無符號實數>→<無符號整數>.<數字串>[E<比例因子>]│
<無符號整數>E<比例因子>
<比例因子>→<有符號整數>
<有符號整數>→[+│-]<無符號整數>
<無符號整數>→<數字串>
<數字串>→<數字>{<數字>}
<數字>→0 │1 │2 │3...... │9
程式程式碼:
import java.util.ArrayList;
import java.util.Scanner;
public class Unsigned {
private ArrayList<Word> wordList;
public static void main(String[] args) {
Unsigned unsigned = new Unsigned();
//
unsigned.inputWordList();
// 識別單詞列表
for (Word word : unsigned.wordList) {
// 識別單詞
unsigned.whichType(word);
String temp = word.getCJ2();
if (temp != null) {
int index = temp.lastIndexOf(".0");
if (index == temp.length() - 2)
word.setCJ2(temp.substring(0, index));
}
}
//
unsigned.printWordList();
}
// 識別單詞
private void whichType(Word word) {
int w = 0;
int p = 0;
int j = 0;
int e = 1;
int d = 0;
String chars[] = word.getStr().split("");
// 從第一個字元開始
int i = 0;
String current_char = chars[i];
// 數字否?
if (!isNum(current_char)) {
word.setCJ1("出錯");
return;
} else {
while (true) {
d = Integer.parseInt(current_char);
w = w * 10 + d;
current_char = chars[++i];
// 數字否?
if (isNum(current_char)) {
continue;
} else {
// 是'.'否?
if (current_char.equals(".")) {
current_char = chars[++i];
// 數字否?
if (!isNum(current_char)) {
word.setCJ1("出錯");
return;
} else {
while (true) {
d = Integer.parseInt(current_char);
w = w * 10 + d;
j = j + 1;
current_char = chars[++i];
// 數字否?
if (isNum(current_char)) {
continue;
} else {
// 是'E'否?
if (current_char.equals("E")) {
isE(current_char, chars, i, word, w, p, j, e, d);
return;
} else {
// 退一字元
word.setCJ1("實型");
word.setCJ2((w * Math.pow(10, e * p - j)) + "");
return;
}
}
}
}
} else {
// 是'E'否?
if (current_char.equals("E")) {
isE(current_char, chars, i, word, w, p, j, e, d);
return;
} else {
// 退一字元
word.setCJ1("整型");
word.setCJ2((w * Math.pow(10, e * p - j)) + "");
return;
}
}
}
}
}
}
private void isE(String current_char, String[] chars, int i, Word word, int w, int p, int j, int e, int d) {
current_char = chars[++i];
// 是'-'否?
if (current_char.equals("-")) {
e = -1;
current_char = chars[++i];
// 數字否?
if (isNum(current_char)) {
while (true) {
d = Integer.parseInt(current_char);
p = p * 10 + d;
current_char = chars[++i];
if (isNum(current_char)) {
continue;
} else {
// 退一字元
word.setCJ1("實型");
word.setCJ2((w * Math.pow(10, e * p - j)) + "");
return;
}
}
} else {
word.setCJ1("出錯");
return;
}
} else {
// 是'+'否?
if (current_char.equals("+")) {
current_char = chars[++i];
// 數字否?
if (isNum(current_char)) {
while (true) {
d = Integer.parseInt(current_char);
p = p * 10 + d;
current_char = chars[++i];
if (isNum(current_char)) {
continue;
} else {
// 退一字元
word.setCJ1("實型");
word.setCJ2((w * Math.pow(10, e * p - j)) + "");
return;
}
}
} else {
word.setCJ1("出錯");
return;
}
} else {
// 數字否?
if (isNum(current_char)) {
while (true) {
d = Integer.parseInt(current_char);
p = p * 10 + d;
current_char = chars[++i];
if (isNum(current_char)) {
continue;
} else {
// 退一字元
word.setCJ1("實型");
word.setCJ2((w * Math.pow(10, e * p - j)) + "");
return;
}
}
} else {
word.setCJ1("出錯");
return;
}
}
}
}
// 是否為數字
private boolean isNum(String string) {
return "0123456789".contains(string);
}
// 讀入單詞列表
private void inputWordList() {
System.out.println("12996 0269 0E Es265 ;要求從鍵盤上輸入一串字元(包括字母、數字等),最後以“;”結束");
Scanner scanner = new Scanner(System.in);
String temp = scanner.nextLine().replace(";", "");
scanner.close();
String[] strs = temp.split(" ");
wordList = new ArrayList<Word>();
for (String str : strs) {
Word word = new Word();
word.setStr(str + "#");
wordList.add(word);
}
}
// 輸出單詞列表
private void printWordList() {
for (Word word : wordList) {
System.out.println(word.getStr() + "\t" + word.getCJ2() + "\t" + word.getCJ1());
}
}
// 單詞類
private class Word {
// str記原始單詞
private String str;
// CJ1記型別
private String CJ1;
// CJ1記數值
private String CJ2;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public String getCJ1() {
return CJ1;
}
public void setCJ1(String cJ1) {
CJ1 = cJ1;
}
public String getCJ2() {
return CJ2;
}
public void setCJ2(String cJ2) {
CJ2 = cJ2;
}
}
}
執行結果:
四、心得體會
詞法分析階段是編譯過程的第一個階段,是編譯的基礎。這個階段的任務是從左到右一個字元一個字元地讀入源程式,即對構成源程式的字元流進行掃描然後根據構詞規則識別單詞(也稱單詞符號或符號)。