├── .gitignore ├── ASTNode.h ├── CMakeLists.txt ├── CodeGenerator.cpp ├── CodeGenerator.h ├── Decl.cpp ├── Decl.h ├── Expr.cpp ├── Expr.h ├── LICENSE ├── OperationKinds.def ├── Parser.cpp ├── Parser.h ├── README.md ├── Stmt.cpp ├── Stmt.h ├── TokenKinds.def ├── lexer.cpp ├── lexer.h ├── main.cpp ├── readme_resources ├── ast.png ├── help.png ├── ir.png ├── test.png └── tokens.png ├── token.cpp └── token.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | .vscode/ 35 | build/ -------------------------------------------------------------------------------- /ASTNode.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/ASTNode.h -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.0) 2 | 3 | project(ToyCC VERSION 0.1.0) 4 | 5 | #include(CTest) 6 | #enable_testing() 7 | 8 | add_executable(tcc 9 | CodeGenerator.cpp 10 | Decl.cpp 11 | Expr.cpp 12 | lexer.cpp 13 | Parser.cpp 14 | Stmt.cpp 15 | token.cpp 16 | main.cpp) 17 | 18 | find_package(nlohmann_json CONFIG REQUIRED) 19 | 20 | find_package(LLVM REQUIRED CONFIG) 21 | 22 | message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") 23 | message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") 24 | 25 | add_definitions(${LLVM_DEFINITIONS}) 26 | 27 | target_include_directories(tcc 28 | SYSTEM PUBLIC 29 | ${LLVM_INCLUDE_DIRS} 30 | ) 31 | 32 | llvm_map_components_to_libnames(llvm_libs CORE) 33 | 34 | target_link_libraries(tcc 35 | PRIVATE 36 | nlohmann_json nlohmann_json::nlohmann_json 37 | ${llvm_libs} 38 | ) 39 | 40 | #set(CPACK_PROJECT_NAME ${PROJECT_NAME}) 41 | #set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) 42 | #include(CPack) 43 | -------------------------------------------------------------------------------- /CodeGenerator.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/CodeGenerator.cpp -------------------------------------------------------------------------------- /CodeGenerator.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/CodeGenerator.h -------------------------------------------------------------------------------- /Decl.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Decl.cpp -------------------------------------------------------------------------------- /Decl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Decl.h -------------------------------------------------------------------------------- /Expr.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Expr.cpp -------------------------------------------------------------------------------- /Expr.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Expr.h -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Compiler-Moyu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OperationKinds.def: -------------------------------------------------------------------------------- 1 | 2 | #ifndef BINARY_OPERATION 3 | # define BINARY_OPERATION(Name, Spelling) 4 | #endif 5 | 6 | #ifndef UNARY_OPERATION 7 | # define UNARY_OPERATION(Name, Spelling) 8 | #endif 9 | 10 | // [C++ 5.5] Pointer-to-member operators. 11 | // BINARY_OPERATION(PtrMemD, ".*") 12 | // BINARY_OPERATION(PtrMemI, "->*") 13 | // [C99 6.5.5] Multiplicative operators. 14 | BINARY_OPERATION(Mul, "*") 15 | BINARY_OPERATION(Div, "/") 16 | BINARY_OPERATION(Rem, "%") 17 | // [C99 6.5.6] Additive operators. 18 | BINARY_OPERATION(Add, "+") 19 | BINARY_OPERATION(Sub, "-") 20 | // [C99 6.5.7] Bitwise shift operators. 21 | BINARY_OPERATION(Shl, "<<") 22 | BINARY_OPERATION(Shr, ">>") 23 | // C++20 [expr.spaceship] Three-way comparison operator. 24 | // BINARY_OPERATION(Cmp, "<=>") 25 | // [C99 6.5.8] Relational operators. 26 | BINARY_OPERATION(LT, "<") 27 | BINARY_OPERATION(GT, ">") 28 | BINARY_OPERATION(LE, "<=") 29 | BINARY_OPERATION(GE, ">=") 30 | // [C99 6.5.9] Equality operators. 31 | BINARY_OPERATION(EQ, "==") 32 | BINARY_OPERATION(NE, "!=") 33 | // [C99 6.5.10] Bitwise AND operator. 34 | BINARY_OPERATION(And, "&") 35 | // [C99 6.5.11] Bitwise XOR operator. 36 | BINARY_OPERATION(Xor, "^") 37 | // [C99 6.5.12] Bitwise OR operator. 38 | BINARY_OPERATION(Or, "|") 39 | // [C99 6.5.13] Logical AND operator. 40 | BINARY_OPERATION(LAnd, "&&") 41 | // [C99 6.5.14] Logical OR operator. 42 | BINARY_OPERATION(LOr, "||") 43 | // [C99 6.5.16] Assignment operators. 44 | BINARY_OPERATION(Assign, "=") 45 | BINARY_OPERATION(MulAssign, "*=") 46 | BINARY_OPERATION(DivAssign, "/=") 47 | BINARY_OPERATION(RemAssign, "%=") 48 | BINARY_OPERATION(AddAssign, "+=") 49 | BINARY_OPERATION(SubAssign, "-=") 50 | BINARY_OPERATION(ShlAssign, "<<=") 51 | BINARY_OPERATION(ShrAssign, ">>=") 52 | BINARY_OPERATION(AndAssign, "&=") 53 | BINARY_OPERATION(XorAssign, "^=") 54 | BINARY_OPERATION(OrAssign, "|=") 55 | // [C99 6.5.17] Comma operator. 56 | // BINARY_OPERATION(Comma, ",") 57 | 58 | 59 | //===- Unary Operations ---------------------------------------------------===// 60 | 61 | // [C99 6.5.2.4] Postfix increment and decrement 62 | UNARY_OPERATION(PostInc, "++") 63 | UNARY_OPERATION(PostDec, "--") 64 | // [C99 6.5.3.1] Prefix increment and decrement 65 | UNARY_OPERATION(PreInc, "++") 66 | UNARY_OPERATION(PreDec, "--") 67 | // [C99 6.5.3.2] Address and indirection 68 | // UNARY_OPERATION(AddrOf, "&") 69 | // UNARY_OPERATION(Deref, "*") 70 | // [C99 6.5.3.3] Unary arithmetic 71 | UNARY_OPERATION(Plus, "+") 72 | UNARY_OPERATION(Minus, "-") 73 | UNARY_OPERATION(Not, "~") 74 | UNARY_OPERATION(LNot, "!") 75 | 76 | 77 | #undef BINARY_OPERATION 78 | #undef UNARY_OPERATION 79 | -------------------------------------------------------------------------------- /Parser.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Parser.cpp -------------------------------------------------------------------------------- /Parser.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Parser.h -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/README.md -------------------------------------------------------------------------------- /Stmt.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Stmt.cpp -------------------------------------------------------------------------------- /Stmt.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/Stmt.h -------------------------------------------------------------------------------- /TokenKinds.def: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/TokenKinds.def -------------------------------------------------------------------------------- /lexer.cpp: -------------------------------------------------------------------------------- 1 | /// @file lexer.cpp 2 | /// A OI-style lexer 3 | /// todo: code refactoring 4 | 5 | #include 6 | #include 7 | #include "token.h" 8 | #include "lexer.h" 9 | using namespace std; 10 | 11 | /** 12 | * @brief Add a token to the Trie 13 | * @param rt Root of the Trie 14 | * @param s The string to insert 15 | * @param kind of the token 16 | */ 17 | void Lexer::add(int rt, string s, TokenKind kind) 18 | { 19 | int pos = rt; 20 | int m = s.length(); 21 | for (int i = 0; i < m; i++) 22 | { 23 | if (!tr[pos][s[i]]) 24 | { 25 | tr[pos][s[i]] = ++cnt; 26 | } 27 | pos = tr[pos][s[i]]; 28 | } 29 | f[pos] = kind; 30 | } 31 | void Lexer::spsolve_root(int rt, TokenKind flag) 32 | { 33 | f[rt] = flag; 34 | } 35 | int Lexer::build_alpha() 36 | { 37 | int rt = ++cnt; 38 | add(rt, "int", TokenKind::kw_int); 39 | add(rt, "void", TokenKind::kw_void); 40 | add(rt, "if", TokenKind::kw_if); 41 | add(rt, "else", TokenKind::kw_else); 42 | add(rt, "while", TokenKind::kw_while); 43 | add(rt, "return", TokenKind::kw_return); 44 | spsolve_root(rt, TokenKind::identifier); 45 | return rt; 46 | } 47 | int Lexer::build_number() 48 | { 49 | int rt = ++cnt; 50 | spsolve_root(rt, TokenKind::numeric_constant); 51 | return rt; 52 | } 53 | int Lexer::build_sign() 54 | { 55 | int rt = ++cnt; 56 | add(rt, "=", TokenKind::equal); 57 | add(rt, "+", TokenKind::plus); 58 | add(rt, "+=", TokenKind::plusequal); 59 | add(rt, "-", TokenKind::minus); 60 | add(rt, "-=", TokenKind::minusequal); 61 | add(rt, "*", TokenKind::star); 62 | add(rt, "*=", TokenKind::starequal); 63 | add(rt, "/", TokenKind::slash); 64 | add(rt, "/=", TokenKind::slashequal); 65 | add(rt, "%", TokenKind::percent); 66 | add(rt, "%=", TokenKind::percentequal); 67 | add(rt, "==", TokenKind::equalequal); 68 | add(rt, ">", TokenKind::greater); 69 | add(rt, ">>", TokenKind::greatergreater); 70 | add(rt, ">>=", TokenKind::greatergreaterequal); 71 | add(rt, ">=", TokenKind::greaterequal); 72 | add(rt, "<", TokenKind::less); 73 | add(rt, "<<", TokenKind::lessless); 74 | add(rt, "<<=", TokenKind::lesslessequal); 75 | add(rt, "<=", TokenKind::lessequal); 76 | add(rt, "!=", TokenKind::exclaimequal); 77 | add(rt, "^", TokenKind::caret); 78 | add(rt, "^=", TokenKind::caretequal); 79 | add(rt, "&", TokenKind::amp); 80 | add(rt, "&=", TokenKind::ampequal); 81 | add(rt, "&&", TokenKind::ampamp); 82 | add(rt, "|", TokenKind::pipe); 83 | add(rt, "||", TokenKind::pipepipe); 84 | add(rt, "|=", TokenKind::pipeequal); 85 | add(rt, ";", TokenKind::semi); 86 | add(rt, ",", TokenKind::comma); 87 | add(rt, "#", TokenKind::eof); 88 | add(rt, "(", TokenKind::l_paren); 89 | add(rt, ")", TokenKind::r_paren); 90 | add(rt, "{", TokenKind::l_brace); 91 | add(rt, "}", TokenKind::r_brace); 92 | add(rt, "//", TokenKind::s_comment); 93 | add(rt, "/*", TokenKind::lm_comment); 94 | add(rt, "*/", TokenKind::rm_comment); 95 | return rt; 96 | } 97 | std::vector Lexer::Lex() 98 | { 99 | char s[1025]; 100 | while (in.getline(s, 1024)) 101 | { 102 | row++; 103 | int max_col = strlen(s); 104 | for (col = 0; col < max_col; col++) 105 | { 106 | int length = 0; 107 | TokenKind flag = TokenKind::unknown; 108 | switch (check_classify(s[col])) 109 | { 110 | case 1: 111 | solve_alpha(root_alpha, s, max_col, col, length, flag); 112 | break; 113 | case 2: 114 | solve_number(root_number, s, max_col, col, length, flag); 115 | break; 116 | case 3: 117 | solve_sign(root_sign, s, max_col, col, length, flag); 118 | break; 119 | case 4: 120 | flag = TokenKind::unknown; 121 | break; 122 | } 123 | if (flag == TokenKind::unknown) 124 | { 125 | continue; 126 | } 127 | else if (flag == TokenKind::s_comment) 128 | { 129 | break; 130 | } 131 | else if (flag == TokenKind::lm_comment) 132 | { 133 | readin = 0; 134 | } 135 | else if (flag == TokenKind::rm_comment) 136 | { 137 | readin = 1; 138 | } 139 | else 140 | { 141 | if (!readin) 142 | { 143 | col += length - 1; 144 | continue; 145 | } 146 | if (flag == TokenKind::eof) 147 | { 148 | stop = 1; 149 | } 150 | 151 | //tokens[tot].kind = flag; 152 | string tmp; 153 | for (int i = col; i <= col + length - 1; i++) 154 | tmp = tmp + s[i]; 155 | Location loc{ row,col+1 }; 156 | tokens.emplace_back(Token{ flag,tmp,loc }); 157 | } 158 | col += length - 1; 159 | } 160 | if (stop) 161 | { 162 | break; 163 | } 164 | } 165 | if (tokens.rbegin()->kind != TokenKind::eof) 166 | { 167 | tokens.push_back({ TokenKind::eof, "", Location{row + 1, 0} }); 168 | } 169 | return tokens; 170 | } 171 | int Lexer::check_classify(char ch) 172 | { 173 | if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) 174 | return 1; 175 | else if (ch >= '0' && ch <= '9') 176 | return 2; 177 | else 178 | { 179 | switch (ch) 180 | { 181 | case '=': 182 | case '+': 183 | case '-': 184 | case '*': 185 | case '/': 186 | case '%': 187 | case '>': 188 | case '<': 189 | case '!': 190 | case ';': 191 | case ',': 192 | case '#': 193 | case '(': 194 | case ')': 195 | case '{': 196 | case '}': 197 | case '^': 198 | case '|': 199 | case '&': 200 | return 3; 201 | break; 202 | default: 203 | return 4; 204 | break; 205 | } 206 | } 207 | return 0; 208 | } 209 | void Lexer::solve_alpha(int rt, char* s, int m, int l, int& len, TokenKind& flag) 210 | { 211 | int pos = rt; 212 | bool sg = 0; 213 | len = 0; 214 | for (int i = l; i < m; i++) 215 | { 216 | if (check_classify(s[i]) < 3) 217 | { 218 | len++; 219 | if (tr[pos][s[i]] && !sg) 220 | { 221 | pos = tr[pos][s[i]]; 222 | } 223 | else 224 | { 225 | sg = 1; 226 | } 227 | } 228 | else 229 | { 230 | break; 231 | } 232 | } 233 | if (!sg && f[pos]!=TokenKind::unknown) 234 | { 235 | flag = f[pos]; 236 | } 237 | else 238 | { 239 | flag = f[rt]; 240 | } 241 | } 242 | void Lexer::solve_number(int rt, char* s, int m, int l, int& len, TokenKind& flag) 243 | { 244 | len = 0; 245 | for (int i = l; i < m; i++) 246 | { 247 | if (check_classify(s[i]) == 2) 248 | { 249 | len++; 250 | 251 | } 252 | else 253 | { 254 | break; 255 | } 256 | } 257 | flag = f[rt]; 258 | } 259 | void Lexer::solve_sign(int rt, char* s, int m, int l, int& len, TokenKind& flag) 260 | { 261 | int pos = rt; 262 | bool sg = 0; 263 | len = 0; 264 | for (int i = l; i < m; i++) 265 | { 266 | if (check_classify(s[i]) == 3) 267 | { 268 | if (tr[pos][s[i]]) 269 | { 270 | pos = tr[pos][s[i]]; 271 | len++; 272 | } 273 | else 274 | { 275 | break; 276 | } 277 | } 278 | else 279 | { 280 | break; 281 | } 282 | } 283 | if (f[pos]!=TokenKind::unknown) 284 | { 285 | flag = f[pos]; 286 | } 287 | } 288 | 289 | -------------------------------------------------------------------------------- /lexer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "token.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | const int N = 255; 10 | 11 | class Lexer 12 | { 13 | std::vector tokens; 14 | int tr[N][131]; 15 | int cnt, tot; 16 | TokenKind f[N]; 17 | ifstream in; 18 | int row, col; 19 | int root_alpha, root_number, root_sign; 20 | bool stop, readin; 21 | void add(int rt, string s, TokenKind kind); 22 | void spsolve_root(int rt, TokenKind flag); 23 | int build_alpha(); 24 | int build_number(); 25 | int build_sign(); 26 | public: 27 | Lexer(std::ifstream& in):in(std::move(in)) 28 | { 29 | cnt = 0; 30 | col = 0; 31 | tot = 0; 32 | row = 0; 33 | stop = 0; 34 | readin = 1; 35 | memset(tr, 0, sizeof(tr)); 36 | fill(std::begin(f), std::end(f), TokenKind::unknown); 37 | root_alpha = build_alpha(); 38 | root_number = build_number(); 39 | root_sign = build_sign(); 40 | } 41 | std::vector Lex(); 42 | int check_classify(char ch); 43 | void solve_alpha(int rt, char* s, int m, int l, int& len, TokenKind& flag); 44 | void solve_number(int rt, char* s, int m, int l, int& len, TokenKind& flag); 45 | void solve_sign(int rt, char* s, int m, int l, int& len, TokenKind& flag); 46 | }; 47 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #pragma warning(push, 0) 6 | #include "llvm/Support/CommandLine.h" 7 | #pragma warning(pop) 8 | 9 | #include "lexer.h" 10 | #include "Parser.h" 11 | #include "CodeGenerator.h" 12 | using namespace std; 13 | 14 | static cl::opt inputFile(cl::Positional, cl::desc(""), cl::Required); 15 | static cl::opt outputFile("o", cl::desc("Output file name"), cl::value_desc("filename"), cl::init("a.out")); 16 | static cl::opt dumpTokens("dump-tokens", cl::desc("Run preprocessor, dump internal rep of tokens")); 17 | static cl::opt dumpAST("dump-ast", cl::desc("Run parser, dump AST")); 18 | 19 | void usage(const char* exeName) 20 | { 21 | cout << "Usage : " << exeName << " " << endl; 22 | } 23 | 24 | int main(int argc, char* argv[]) 25 | { 26 | cl::ParseCommandLineOptions(argc, argv); 27 | ifstream fin(inputFile); 28 | if (!fin.is_open()) 29 | { 30 | cout << "Can't open " << inputFile << endl; 31 | return 0; 32 | } 33 | 34 | Lexer* lexer = new Lexer(fin); 35 | auto tokens = lexer->Lex(); 36 | fin.close(); 37 | 38 | if (dumpTokens) 39 | { 40 | json res = json::array(); 41 | for (size_t i = 0; i < tokens.size(); i++) 42 | { 43 | res.push_back(json({ 44 | {"id",i + 1}, 45 | {"content",tokens[i].content}, 46 | {"prop",tokens[i].getKindName()}, 47 | {"loc",to_string(tokens[i].loc.row) + "," + to_string(tokens[i].loc.col)} 48 | })); 49 | } 50 | std::cout << res.dump(4) << std::endl; 51 | return 0; 52 | } 53 | Parser* p = new Parser(tokens, inputFile); 54 | auto res = p->parse(); 55 | if (!res) 56 | { 57 | std::cerr << "Error"; 58 | return 0; 59 | } 60 | if (dumpAST) 61 | { 62 | std::cout << res->toJson().dump(4) << std::endl; 63 | return 0; 64 | } 65 | CodeGenerator* generator = new CodeGenerator(); 66 | res->genCode(*generator); 67 | generator->print(outputFile.getValue().c_str()); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /readme_resources/ast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/readme_resources/ast.png -------------------------------------------------------------------------------- /readme_resources/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/readme_resources/help.png -------------------------------------------------------------------------------- /readme_resources/ir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/readme_resources/ir.png -------------------------------------------------------------------------------- /readme_resources/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/readme_resources/test.png -------------------------------------------------------------------------------- /readme_resources/tokens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/readme_resources/tokens.png -------------------------------------------------------------------------------- /token.cpp: -------------------------------------------------------------------------------- 1 | #include "token.h" 2 | 3 | std::string Token::getKindName() const 4 | { 5 | switch (kind) 6 | { 7 | default: 8 | case TokenKind::unknown: 9 | return "unknown"; 10 | case TokenKind::s_comment: 11 | return "s_comment"; 12 | case TokenKind::lm_comment: 13 | return "lm_comment"; 14 | case TokenKind::rm_comment: 15 | return "rm_comment"; 16 | case TokenKind::identifier: 17 | return "identifier"; 18 | case TokenKind::numeric_constant: 19 | return "numeric_constant"; 20 | case TokenKind::eof: 21 | return "eof"; 22 | case TokenKind::l_paren: 23 | return "l_paren"; 24 | case TokenKind::r_paren: 25 | return "r_paren"; 26 | case TokenKind::l_brace: 27 | return "l_brace"; 28 | case TokenKind::r_brace: 29 | return "r_brace"; 30 | case TokenKind::star: 31 | return "tar"; 32 | case TokenKind::plus: 33 | return "plus"; 34 | case TokenKind::minus: 35 | return "minus"; 36 | case TokenKind::minusequal: 37 | return "minuesequal"; 38 | case TokenKind::exclaimequal: 39 | return "exclaimequal"; 40 | case TokenKind::slash: 41 | return "lash"; 42 | case TokenKind::less: 43 | return "less"; 44 | case TokenKind::lessless: 45 | return "lessless"; 46 | case TokenKind::lessequal: 47 | return "lessequal"; 48 | case TokenKind::greater: 49 | return "greater"; 50 | case TokenKind::greatergreater: 51 | return "greatergreater"; 52 | case TokenKind::greaterequal: 53 | return "greaterequal"; 54 | case TokenKind::semi: 55 | return "semi"; 56 | case TokenKind::equal: 57 | return "equal"; 58 | case TokenKind::equalequal: 59 | return "equalequal"; 60 | case TokenKind::comma: 61 | return "comma"; 62 | case TokenKind::kw_else: 63 | return "kw_else"; 64 | case TokenKind::kw_if: 65 | return "kw_if"; 66 | case TokenKind::kw_int: 67 | return "kw_int"; 68 | case TokenKind::kw_return: 69 | return "kw_return"; 70 | case TokenKind::kw_void: 71 | return "kw_void"; 72 | case TokenKind::kw_while: 73 | return "kw_while"; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /token.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maoyao233/ToyCC/ad7b942a9d8ea00a34d3a8e2595e1a3006bf7b73/token.h --------------------------------------------------------------------------------