從零開始寫個編譯器吧 - Token.java 文件的編寫

如今,讓咱們來動手寫編譯器的第一個個java文件吧。本章要寫的類,是Token類。如其名字所示,這個類實例化的對象用於表示詞法分析器 Tokenizer 的產物。同時,也做爲下一階段的語法分析器 Parser 的原料。java

讓咱們開始吧!先新建一個Token.java 於 src/com/taozeyu/taolan/analysis之中。函數

package com.taozeyu.taolan.analysis;

public class Token {
    public static enum Type {
        Keyword, Number, Identifier, Sign, Annotation,
        String, RegEx, Space, NewLine, EndSymbol;
    }
    final Type type;
    final String value;

    Token(Type type, String value) {
        //TODO
    }
}

如以前章節討論的同樣,Token對象應該包含類型和語素兩個屬性。注意這個 Type 枚舉類型,其內容就是我在上一章所說的 tao 語言應該具有的10種單詞類型。this

我但願詞法分析器從源代碼中提取出語素,並根據上下文推測出單詞類型,從而構造出Token對象。但實際上,請注意Type這個枚舉類的三個類型:編碼

Keyword, Number, Identifier

這三個類型不一樣之處?實際上這三個類型的形式極其相似(甚至 Keyword 和 Identifier 的形式是徹底相同的),而且能夠僅經過語素準確斷定其類型。所以,我但願對詞法分析器 Tokenizer 隱藏着三種類型的區別,將這三種類型統稱 Identifier,以簡化編碼。code

Token(Type type, String value) {
    if(type == Type.Identifier) {
        char firstChar = value.charAt(0);
        if(firstChar >= '0' & firstChar < '9') {
            type = Type.Number;
        } else if(keywordsSet.contains(value)){
            type = Type.Keyword;
        }
    }
    this.type = type;
    this.value = value;
}

因而,Token 對 Tokenizer 隱藏了 Number、Keyword 類型。Tokenizer 只須要構造出 Identifier 類型便可,進一步細分將在 Token 的構造函數中進行。對象

特別的,構造函數中引用了一個 keywordsSet 變量。實際上這個變量應該包含全部 tao 語言的關鍵字。此處稍稍定義一下。字符串

private static final HashSet<String> keywordsSet = new HashSet<>();

static {
    keywordsSet.add("if");
    keywordsSet.add("when");
    keywordsSet.add("elsif");
    keywordsSet.add("else");
    keywordsSet.add("while");
    keywordsSet.add("begin");
    keywordsSet.add("until");
    keywordsSet.add("for");
    keywordsSet.add("do");
    keywordsSet.add("try");
    keywordsSet.add("catch");
    keywordsSet.add("finally");
    keywordsSet.add("end");
    keywordsSet.add("def");
    keywordsSet.add("var");
    keywordsSet.add("this");
    keywordsSet.add("null");
    keywordsSet.add("throw");
    keywordsSet.add("break");
    keywordsSet.add("continue");
    keywordsSet.add("return");
    keywordsSet.add("operator");
}

好吧,tao 語言我能想出的可能有的關鍵字都在這裏了。若是有遺漏或者多餘,其實之後再回過頭來改也沒問題。編譯器

特別的,對於 Annotation、String、RegEx ,它們在源代碼中存在的形式和具體的語素並不徹底等同。io

  • #我是註釋(回車)
  • "我是一個字符串"
  • ^\s+\d+$
  • 對於 Tokenizer 而言,它傾向於讀出如上一整行信息。可是僅僅只加下劃線的文字是Token的語素。所以,我還須要再構造函數中對構造參數value進行進一步提取,以獲得正確的語素。

另外,EndSymbol 的語素必須爲空,無論 Tokenizer 傳入什麼參數都必須如此。編譯

相關文章
相關標籤/搜索