RE:从零开始的编译器编写 03 词法分析(2) 木灵的炼金工作室

词法单元 token.h

我们使用基类token来表示词法单元,以短整型量tags来描述词法单元的类型:

typedef short tokenType;
class token {
public:
    tokenType tags;
    explicit token(tokenType _type) : tags(_type) {};
    virtual void printToken() { std::cout << (int)tags; }
};

假设我们的词法分析单元目前只能处理:(在以后可以扩充)

字面量

  • 整形字面量
  • 浮点字面量
  • 字符串字面量
  • 字符字面量

运算符

  • 赋值运算符: =
  • 运算符:+ - * / % > < >= <= == !=

标识符

  • 一般标识符: 变量名等
  • 保留字:

    true, false
    main, if, else, goto, switch, while, for, do, continue, break, return
    int, float, char, long, short, double, unsigned, signed, void, const
    
  • 分隔符: ( ) { }

我们对于每一类词法单元,使用一个token子类描述它:

class token {
public:
    tokenType tags;
    explicit token(tokenType _type) : tags(_type) {};
    virtual void printToken() { std::cout << (int)tags; }
};

class num : public token { //整形字面量
public:
    int value;
    explicit num(int _number) : token(_NUM), value(_number) {}
    void printToken() override { std::cout << "NUM " << value; }
};
class flo : public token { //浮点字面量
public:
    float value;
    explicit flo(float _number) : token(_FLO), value(_number) {}
    void printToken() override { std::cout << "FLO " << value; }
};
class str : public token { //字符串字面量
public:
    std::string value;
    explicit str(std::string const &_val) : token(_STR), value(_val) {}
    void printToken() override { std::cout << "STR " << value; }
};
class cha : public token { //字符字面量
public:
    char value;
    explicit cha(char _val) : token(_CHA), value(_val) {}
    void printToken() override { std::cout << "CHA " << value; }
};

class equa : public token { //赋值运算符
public:
    int type;
    explicit equa(int _type) : token(_EQUA), type(_type) {}
    void printToken() override { std::cout << "EQUA " << type; }
};
class oper : public token { //一般运算符
public:
    int type;
    explicit oper(int _type) : token(_OPER), type(_type) {}
    void printToken() override { std::cout << "OPER " << type; }
};

class id : public token { //一般标识符
public:
    std::string val;
    explicit id(std::string const &_str) : token(_ID), val(_str) {}
    void printToken() override { std::cout << "ID " << val; }
};
class re : public token { //保留字
public:
    int type;
    explicit re(int _type) : token(_RE), type(_type) {}
    void printToken() override { std::cout << "RE " << type; }
};
class sp : public token { //分隔符
public:
    char type;
    explicit sp(char _type) : token(_SP), type(_type) {}
    void printToken() override { std::cout << "SP " << type; }
};

得到了我们的编译器的首个文件: token.h

#include "ComplierBase.h"
#ifndef _TOKEN_H_
#define _TOKEN_H_

class token {
public:
    tokenType tags;
    explicit token(tokenType _type) : tags(_type) {};
    virtual void printToken() { std::cout << (int)tags; }
};

class num : public token { //整形字面量
public:
    int value;
    explicit num(int _number) : token(_NUM), value(_number) {}
    void printToken() override { std::cout << "NUM " << value; }
};
class flo : public token { //浮点字面量
public:
    float value;
    explicit flo(float _number) : token(_FLO), value(_number) {}
    void printToken() override { std::cout << "FLO " << value; }
};
class str : public token { //字符串字面量
public:
    std::string value;
    explicit str(std::string const &_val) : token(_STR), value(_val) {}
    void printToken() override { std::cout << "STR " << value; }
};
class cha : public token { //字符字面量
public:
    char value;
    explicit cha(char _val) : token(_CHA), value(_val) {}
    void printToken() override { std::cout << "CHA " << value; }
};

class equa : public token { //赋值运算符
public:
    int type;
    explicit equa(int _type) : token(_EQUA), type(_type) {}
    void printToken() override { std::cout << "EQUA " << type; }
};
class oper : public token { //一般运算符
public:
    int type;
    explicit oper(int _type) : token(_OPER), type(_type) {}
    void printToken() override { std::cout << "OPER " << type; }
};

class id : public token { //一般标识符
public:
    std::string val;
    explicit id(std::string const &_str) : token(_ID), val(_str) {}
    void printToken() override { std::cout << "ID " << val; }
};
class re : public token { //保留字
public:
    int type;
    explicit re(int _type) : token(_RE), type(_type) {}
    void printToken() override { std::cout << "RE " << type; }
};
class sp : public token { //分隔符
public:
    char type;
    explicit sp(char _type) : token(_SP), type(_type) {}
    void printToken() override { std::cout << "SP " << type; }
};

#endif

当然,这个头文件的写法是根据你对词法单元的种类定义而变化的,同时描述词法单元的属性的底层实现也是不唯一的。


Copyright AmachiInori 2017-2021. All Right Reserved.
Powered By Jekyll.
amachi.com.cn