1. 程式人生 > 其它 >編譯原理實驗一 -無符號數的詞法分析程式

編譯原理實驗一 -無符號數的詞法分析程式

一、實驗目的和要求:

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

 

執行結果:

 

 

 

          

四、心得體會

詞法分析階段是編譯過程的第一個階段,是編譯的基礎。這個階段的任務是從左到右一個字元一個字元地讀入源程式,即對構成源程式的字元流進行掃描然後根據構詞規則識別單詞(也稱單詞符號或符號)。