PL/0簡單編譯系統(二)

詞法分析

詞法分析又稱詞法分析器或者掃描器,是編譯程序的基本子程序之一。本項目采用手工方式設計并實現詞法分析程序。

詞法分析的功能

掃描源程序,按語言的詞法規則識別出各類單詞符號(Token),并將有關字符組合成為單詞并輸出,同時進行詞法檢查。語言的保留字,標識符,常數和運算符等都是單詞的例子。

Token分類

將PL/0編譯系統中所有的字符,字符串的類型按如下表格分類:

類型 字符or字符串
保留字 begin, end, if,then, else, const, procedure,var,do,while, call,read, write, repeat, until
算數運算符 + ,—,*,/
比較運算符 <> , < ,<= , >, >= ,=
賦值符 := , =
標識符 變量名,過程名,常數名
常數 10,25等整數
界符 ‘,’,‘.’,‘;’,‘(’,‘)’
其他符號 :,EOF

Token結構

在具體實現時,由于出錯處理及語法分析的需求,定義如下Token結構:

public class Token {
    private SymType st; //token的類別
    private int line; //token所在行,錯誤處理使用
    private String value; //token的值,只有標識符和常量有值
}

Token分析程序的構造

首先,給出狀態圖:

狀態圖

根據狀態圖,可以寫出分析程序analysis()

private Token analysis() {
    strToken = "";
    getChar();
    while ((ch == ' ' || ch == '\n' || ch == '\t' || ch == '\0') && searchPtr < buffer.length) {
        if (ch == '\n') {
            line++;
        }
        getChar();
    }
    if (ch == '$' && searchPtr >= buffer.length) { //到達文件末尾
        return new Token(SymType.EOF, line, "-1");
    }
    if (isLetter()) { //首位為字母,可能為保留字或者變量名
        while (isLetter() || isDigit()) {
            strToken += ch;
            getChar();
        }
        retract();
        for (int i = 0; i < keyWords.length; i++) {
            if (strToken.equals(keyWords[i])) { //說明是保留字
                return new Token(SymType.values()[i], line, "-");
            }
        }
        //不是保留字,則為標識符,需要保存值
        return new Token(SymType.SYM, line, strToken);
    } else if (isDigit()) { //首位為數字,即為整數
        while (isDigit()) {
            strToken += ch;
            getChar();
        }
        retract();
        return new Token(SymType.CONST, line, strToken);
    } else if (ch == '=') { //等號
        return new Token(SymType.EQU, line, "-");
    } else if (ch == '+') { //加號
        return new Token(SymType.ADD, line, "-");
    } else if (ch == '-') { //減號
        return new Token(SymType.SUB, line, "-");
    } else if (ch == '*') { //乘號
        return new Token(SymType.MUL, line, "-");
    } else if (ch == '/') { //除號
        return new Token(SymType.DIV, line, "-");
    } else if (ch == '<') { //小于或不等于或小于等于
        getChar();
        if (ch == '=') {
            return new Token(SymType.LESE, line, "-");
        } else if (ch == '>') {
            return new Token(SymType.NEQE, line, "-");
        } else {
            retract();
            return new Token(SymType.LES, line, "-");
        }
    } else if (ch == '>') { //大于或大于等于
        getChar();
        if (ch == '=') {
            return new Token(SymType.LARE, line, "-");
        } else {
            retract();
            return new Token(SymType.LAR, line, "-");
        }
    } else if (ch == ',') { //逗號
        return new Token(SymType.COMMA, line, "-");
    } else if (ch == ';') { //分號
        return new Token(SymType.SEMIC, line, "-");
    } else if (ch == '.') { //點
        return new Token(SymType.POI, line, "-");
    } else if (ch == '(') { //左括號
        return new Token(SymType.LBR, line, "-");
    } else if (ch == ')') { //右括號
        return new Token(SymType.RBR, line, "-");
    } else if (ch == ':') { //賦值號
        getChar();
        if (ch == '=') {
            return new Token(SymType.CEQU, line, "-");
        } else {
            retract();
            return new Token(SymType.COL, line, "-");
        }
    }
    return new Token(SymType.EOF, line, "-");
}

analysis()每次分析出一個Token。對代碼進行一遍遍歷,即可得到源程序的token數組。

詞法分析
符號表管理
語法和語義分析
Pcode生成
出錯管理

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容