In the process of implementing lexer and parser, you must define the token type. In programming language implementation mode, java code is used to directly define static int TEXT = 1. It can be inherited to the actually used lexer when lexer is extended. However, when C ++ defines static members of a class, it must be initialized separately outside. This is not very nice. In C ++ 11, enum class is implemented,
First, check whether the enum class meets the requirements. For example:
enum class TokenType{ _EOF, TEXT};TokenType a = TokenType::TEXT;
You can use TokenType: TEXT to indicate the type. Only the same type as TokenType can be compared. If you want to expand
enum class ExprTokenType:public TokenType{ NUMBER, OP};
We hope that the new type ExprTokenType will be added based on TokenType. Since it is a class, it should be okay to inherit it? However, an error is reported during compilation. I had to give up this method.
Later I thought of the following implementation,
Class TokenType {public: TokenType () {nameMap = {"_ EOF", "TEXT" };} string Name (int x) {return nameMap. at (x);} public: const static int _ EOF = 0; // The const static member can be directly initialized here. // if it is only a const modifier, the const member must be assigned a value in the constructor's initialization list // public Member. You can use TokenType like enum class. TEXT access const static int TEXT = 1; protected: vector <string> nameMap; // you can obtain its name based on the type for debugging.} TokenType; class ExprTokenType: public TokenType {publ Ic: ExprTokenType () {nameMap. push_back ("NUMBER"); // Add the corresponding name for the newly added type, nameMap. push_back ("OP");} public: const static int NUMBER = 2; const static int OP = 3;} ExprTokenType; // an instance of the same name is defined here, you can use the class name directly later. type, // if you do not do this, you may declare all its content as static, and the same is true.
The expected functions are implemented, but they are different from the enum class and are not of type security. But it doesn't matter. It can be used.
The following is the test code,
int main(){ cout << "---test enum type---" << endl; int a = TokenType::TEXT; cout << "TokenType a:" << a << endl; cout << "ToeknType a:" << TokenType.Name(a) << endl; int b = ExprTokenType::OP; cout << "ExprTokenType b:" << b << endl; cout << "ExprToeknType b:" << ExprTokenType.Name(b) << endl; b = ExprTokenType::TEXT; cout << "ExprTokenType b:" << b << endl; cout << "ExprToeknType b:" << ExprTokenType.Name(b) << endl; if(a==b) cout << "test done." << endl; return 0;}
Note that C ++ 11 support must be added during compilation. g ++-std = c ++ 0x .....
There should be a better way to achieve it, hoping to communicate with you.