llvm-1-实现Kaleidoscope语言的词法分析器

121 阅读1分钟
#include <string>
#include <iostream>

using namespace std;
/*词法分析器
 * 将输入分解为标记
 * 要么是Token枚举值之一
 * 要么是未知字符的ASCII*/

enum Token {
    tok_eof = -1,

    // commands
    tok_def = -2,
    tok_extern = -3,

    // primary
    tok_identifier = -4,//标识符
    tok_number = -5,//数字
};

static std::string IdentifierStr; // 保存标识符的名称
static double NumVal;             // 保存数字

/*词法分析器的实际实现*/
//从标准输入返回下一个标记
static int gettok() {
    static int LastChar = ' ';

    //跳过空格
    while (isspace(LastChar))
        LastChar = getchar();//一次读一个字符

    //识别标识符和特定关键字
    if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
        IdentifierStr = LastChar;//转换了这个字符 本来为int 现在转换为字符串
//读第一个字符 为数字的时候 继续从输入流中读字符
        while (isalnum((LastChar = getchar())))
            IdentifierStr += LastChar;

        if (IdentifierStr == "def")
            return tok_def;
        if (IdentifierStr == "extern")
            return tok_extern;
        return tok_identifier;
    }

    //识别数字
    if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
        std::string NumStr;
        do {
            NumStr += LastChar;
            LastChar = getchar();
        } while (isdigit(LastChar) || LastChar == '.');

        NumVal = strtod(NumStr.c_str(), 0);
        return tok_number;
    }

    //识别注释
    if (LastChar == '#') {
        // Comment until end of line.
        do
            LastChar = getchar();
        while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');

        if (LastChar != EOF)
            return gettok();
    }


    // Check for end of file.  Don't eat the EOF.
    if (LastChar == EOF)
        return tok_eof;

    // Otherwise, just return the character as its ascii value.
    int ThisChar = LastChar;
    LastChar = getchar();
    return ThisChar;

}


/*测试
 * 直接打印出来
 * g++编译
 * g++ my-lang.cc -o my-lang.bin
 * -o 指定生成的程序
 * 自己的习惯把二进制文件成为bin
 * run
 * ./my-lang.bin*/

int main() {
    while (true) {
        int tok = gettok();
        cout << "got token:" << tok << endl;
    }
}