├── LICENSE ├── Makefile ├── README.md ├── include ├── ASTNode.h ├── AbstractSyntaxTree.h ├── CLexer.h ├── CParser.h ├── GenCVisitor.h ├── Lexer.h ├── Parser.h ├── PrintTreeVisitor.h ├── SymbolTable.h ├── TreeVisitor.h └── common.h ├── src ├── ASTNode.cpp ├── AbstractSyntaxTree.cpp ├── CLexer.cpp ├── CParser.cpp ├── GenCVisitor.cpp ├── Lexer.cpp ├── Parser.cpp ├── PrintTreeVisitor.cpp ├── SymbolTable.cpp ├── TreeVisitor.cpp └── cformat.cpp └── test ├── cpp_out_example.c └── example1.c /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017, 2018 Jozef Kolek 4 | 5 | All rights reserved. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | OBJS = cformat.o CParser.o Parser.o SymbolTable.o CLexer.o Lexer.o \ 2 | AbstractSyntaxTree.o ASTNode.o GenCVisitor.o PrintTreeVisitor.o \ 3 | TreeVisitor.o 4 | 5 | CXX = g++ 6 | CXXFLAGS = -std=c++14 -Wall -g 7 | 8 | SRC = src 9 | INCLUDE = include 10 | BIN = . 11 | DEST = /usr/bin 12 | 13 | all: cformat 14 | 15 | cformat: $(OBJS) 16 | $(CXX) $(CXXFLAGS) $(OBJS) -o cformat 17 | 18 | cformat.o: ${SRC}/cformat.cpp ${INCLUDE}/CParser.h 19 | $(CXX) $(CXXFLAGS) -c ${SRC}/cformat.cpp 20 | 21 | Parser.o: ${INCLUDE}/Parser.h ${INCLUDE}/Lexer.h ${INCLUDE}/SymbolTable.h \ 22 | ${INCLUDE}/AbstractSyntaxTree.h 23 | $(CXX) $(CXXFLAGS) -c ${SRC}/Parser.cpp 24 | 25 | CParser.o: ${INCLUDE}/CParser.h ${INCLUDE}/Lexer.h ${INCLUDE}/SymbolTable.h \ 26 | ${INCLUDE}/AbstractSyntaxTree.h 27 | $(CXX) $(CXXFLAGS) -c ${SRC}/CParser.cpp 28 | 29 | SymbolTable.o: ${INCLUDE}/SymbolTable.h ${INCLUDE}/common.h 30 | $(CXX) $(CXXFLAGS) -c ${SRC}/SymbolTable.cpp 31 | 32 | Lexer.o: ${INCLUDE}/Lexer.h ${INCLUDE}/common.h 33 | $(CXX) $(CXXFLAGS) -c ${SRC}/Lexer.cpp 34 | 35 | CLexer.o: ${INCLUDE}/CLexer.h ${INCLUDE}/common.h 36 | $(CXX) $(CXXFLAGS) -c ${SRC}/CLexer.cpp 37 | 38 | AbstractSyntaxTree.o: ${INCLUDE}/AbstractSyntaxTree.h \ 39 | ${INCLUDE}/ASTNode.h ${INCLUDE}/TreeVisitor.h ${INCLUDE}/PrintTreeVisitor.h 40 | $(CXX) $(CXXFLAGS) -c ${SRC}/AbstractSyntaxTree.cpp 41 | 42 | PrintTreeVisitor.o: ${INCLUDE}/ASTNode.h ${INCLUDE}/TreeVisitor.h \ 43 | ${INCLUDE}/PrintTreeVisitor.h 44 | $(CXX) $(CXXFLAGS) -c ${SRC}/PrintTreeVisitor.cpp 45 | 46 | GenCVisitor.o: ${INCLUDE}/ASTNode.h ${INCLUDE}/TreeVisitor.h \ 47 | ${INCLUDE}/GenCVisitor.h 48 | $(CXX) $(CXXFLAGS) -c ${SRC}/GenCVisitor.cpp 49 | 50 | TreeVisitor.o: ${INCLUDE}/ASTNode.h ${INCLUDE}/TreeVisitor.h 51 | $(CXX) $(CXXFLAGS) -c ${SRC}/TreeVisitor.cpp 52 | 53 | ASTNode.o: ${INCLUDE}/TreeVisitor.h ${INCLUDE}/ASTNode.h 54 | $(CXX) $(CXXFLAGS) -c ${SRC}/ASTNode.cpp 55 | 56 | install: 57 | -cp ${BIN}/cformat ${DEST} 58 | 59 | clean: 60 | -rm *.o cformat typechecker 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CParser 2 | 3 | `CParser` is a standalone C parser library written in C++, that can be easily embedded in other software projects. The library is contained of reusable set of classes. 4 | 5 | ## Demo usage of the library 6 | See `src/cformat.cpp`, `include/GenCVisitor.h` and `src/GenCVisitor.cpp` for the demo source which uses the C parser library. `cformat` is an implementation of a simple C code style formatter. 7 | To clone the project and build the demo, type: 8 | ``` 9 | $ git clone https://github.com/jkolek/cparser.git 10 | $ cd cparser 11 | $ make 12 | ``` 13 | To run the demo with example C file, type: 14 | ``` 15 | $ ./cformat test/example1.c 16 | ``` 17 | 18 | ## How to use the library 19 | 20 | To use the library you can simply implement your own visitor class by inheriting `TreeVisitor` class similarly like `GenCVisitor` (used by the `cformat`) does. Then with this visitor you can traverse abstract syntax tree generated by parser. 21 | 22 | 23 | ## Current work 24 | 25 | My current objectives are to make the parser to be able to parse preprocessed files 26 | like for example `test/cpp_out_example.c`, and to finish the `GenCVisitor` implementation. 27 | 28 | Thank you for your interest in my project. Any feedback would be highly appreciated! 29 | 30 | 31 | ## References 32 | 33 | http://www.quut.com/c/ANSI-C-grammar-l-2011.html 34 | 35 | http://www.quut.com/c/ANSI-C-grammar-y.html 36 | 37 | https://github.com/antlr/grammars-v4/blob/master/c/C.g4 38 | 39 | https://github.com/antlr/grammars-v3/blob/master/ANSI-C/C.g 40 | -------------------------------------------------------------------------------- /include/ASTNode.h: -------------------------------------------------------------------------------- 1 | // ASTNode classes of abstract syntax tree. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef AST_NODE_H 9 | #define AST_NODE_H 10 | 11 | #include "../include/SymbolTable.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define ASSIGN_AST_NODE_REF(x, y) \ 19 | { \ 20 | x = y; \ 21 | if (x != NULL_AST_NODE) \ 22 | x->incRefCount(); \ 23 | } 24 | 25 | #define PUSH_BACK_AST_NODE_REF(v, x) \ 26 | { \ 27 | if (x != NULL_AST_NODE) \ 28 | { \ 29 | v.push_back(x); \ 30 | x->incRefCount(); \ 31 | } \ 32 | } 33 | 34 | #define DELETE_AST_NODE_REF(x) \ 35 | if (x != NULL_AST_NODE) \ 36 | { \ 37 | x->decRefCount(); \ 38 | if (x->getRefCount() == 0) \ 39 | delete x; \ 40 | } 41 | 42 | /* TODO: Define the rest of macros. */ 43 | #define AST_PLUS(t, l, r) new PlusExprASTNode(t, l, r) 44 | #define AST_MINUS(t, l, r) new MinusExprASTNode(t, l, r) 45 | #define AST_MULT(t, l, r) new MultExprASTNode(t, l, r) 46 | 47 | namespace cparser 48 | { 49 | 50 | enum ASTNodeKind 51 | { 52 | NK_UNKNOWN, 53 | NK_IDENT_NODE, 54 | NK_LIST, 55 | NK_SIZEOF_EXPR, 56 | NK_ALIGNOF_EXPR, 57 | 58 | // Declarations 59 | NK_FUNCTION_DECL, 60 | NK_TYPE_DECL, 61 | NK_VAR_DECL, 62 | NK_PARM_DECL, 63 | NK_FIELD_DECL, 64 | 65 | // Statements 66 | NK_ASM_STMT, 67 | NK_BREAK_STMT, 68 | NK_CASE_LABEL, 69 | NK_COMPOUND_STMT, 70 | NK_CONTINUE_STMT, 71 | NK_DECL_STMT, 72 | NK_DO_STMT, 73 | NK_EXPR_STMT, 74 | NK_FILE_STMT, 75 | NK_FOR_STMT, 76 | NK_GOTO_STMT, 77 | NK_IF_STMT, 78 | NK_LABEL_STMT, 79 | NK_RETURN_STMT, 80 | NK_SCOPE_STMT, 81 | NK_SWITCH_STMT, 82 | NK_WHILE_STMT, 83 | 84 | // Expressions 85 | NK_INTEGER_CONST, 86 | NK_REAL_CONST, 87 | NK_COMPLEX_CONST, 88 | NK_STRING_CONST, 89 | NK_CHAR_CONST, 90 | NK_CAST_EXPR, 91 | NK_NEGATE_EXPR, 92 | NK_BIT_NOT_EXPR, 93 | NK_LOG_NOT_EXPR, 94 | NK_PREDECREMENT_EXPR, 95 | NK_PREINCREMENT_EXPR, 96 | NK_POSTDECREMENT_EXPR, 97 | NK_POSTINCREMENT_EXPR, 98 | NK_ADDR_EXPR, 99 | NK_INDIRECT_REF, 100 | NK_FIX_TRUNC_EXPR, 101 | NK_FLOAT_EXPR, 102 | NK_COMPLEX_EXPR, 103 | NK_NON_LVALUE_EXPR, 104 | NK_NOP_EXPR, 105 | NK_LSHIFT_EXPR, 106 | NK_RSHIFT_EXPR, 107 | NK_BIT_IOR_EXPR, 108 | NK_BIT_XOR_EXPR, 109 | NK_BIT_AND_EXPR, 110 | NK_LOG_AND_EXPR, 111 | NK_LOG_OR_EXPR, 112 | NK_PLUS_EXPR, 113 | NK_MINUS_EXPR, 114 | NK_MULT_EXPR, 115 | NK_TRUNC_DIV_EXPR, 116 | NK_TRUNC_MOD_EXPR, 117 | NK_RDIV_EXPR, 118 | NK_ARRAY_REF, 119 | NK_STRUCT_REF, 120 | NK_LT_EXPR, 121 | NK_LE_EXPR, 122 | NK_GT_EXPR, 123 | NK_GE_EXPR, 124 | NK_EQ_EXPR, 125 | NK_NE_EXPR, 126 | NK_ASSIGN_EXPR, 127 | NK_INIT_EXPR, 128 | NK_COMPOUND_EXPR, 129 | NK_COND_EXPR, 130 | NK_CALL_EXPR, 131 | 132 | // Input/output 133 | NK_GETC_EXPR, 134 | NK_PUTC_EXPR, 135 | NK_GETI_EXPR, 136 | NK_PUTI_EXPR, 137 | 138 | // Types 139 | NK_VOID_TYPE, 140 | NK_INTEGRAL_TYPE, 141 | NK_REAL_TYPE, 142 | NK_COMPLEX_TYPE, 143 | NK_ENUMERAL_TYPE, 144 | NK_BOOLEAN_TYPE, 145 | NK_POINTER_TYPE, 146 | NK_REFERENCE_TYPE, 147 | NK_FUNCTION_TYPE, 148 | NK_ARRAY_TYPE, 149 | NK_STRUCT_TYPE, 150 | NK_UNKNOWN_TYPE, 151 | NK_UNION_TYPE 152 | }; 153 | 154 | class AbstractSyntaxTree; 155 | class TreeVisitor; 156 | 157 | class ASTNode 158 | { 159 | protected: 160 | ASTNodeKind kind; 161 | int lineNum; 162 | unsigned flags; // Additional flags 163 | unsigned refCount; 164 | 165 | public: 166 | ASTNodeKind getKind() { return kind; } 167 | 168 | ASTNode() 169 | { 170 | flags = 0; 171 | refCount = 0; 172 | lineNum = 0; 173 | kind = NK_UNKNOWN; 174 | } 175 | 176 | ASTNode(ASTNodeKind Kind) 177 | { 178 | flags = 0; 179 | kind = Kind; 180 | refCount = 0; 181 | lineNum = 0; 182 | } 183 | 184 | // Virtual destructor 185 | virtual ~ASTNode() {} 186 | 187 | int getLineNum() { return lineNum; } 188 | void setLineNum(int LineNum) { lineNum = LineNum; } 189 | unsigned getFlags() { return flags; } 190 | void setFlags(unsigned Flags) { flags = Flags; } 191 | 192 | // Virtual functions 193 | virtual void declare(AbstractSyntaxTree *ast) {} 194 | virtual STType *checkType(AbstractSyntaxTree *ast) { return nullptr; } 195 | virtual void accept(TreeVisitor *v) {} 196 | 197 | bool isType() 198 | { 199 | return (kind == NK_VOID_TYPE || kind == NK_INTEGRAL_TYPE || 200 | kind == NK_REAL_TYPE || kind == NK_COMPLEX_TYPE || 201 | kind == NK_ENUMERAL_TYPE || kind == NK_BOOLEAN_TYPE || 202 | kind == NK_POINTER_TYPE || kind == NK_REFERENCE_TYPE || 203 | kind == NK_FUNCTION_TYPE || kind == NK_ARRAY_TYPE || 204 | kind == NK_STRUCT_TYPE || kind == NK_UNKNOWN_TYPE || 205 | kind == NK_UNION_TYPE); 206 | } 207 | 208 | void incRefCount() { refCount++; } 209 | void decRefCount() { refCount--; } 210 | unsigned getRefCount() { return refCount; } 211 | }; 212 | 213 | // Singleton class 214 | class NullASTNode : public ASTNode 215 | { 216 | static NullASTNode *s_instance; 217 | 218 | public: 219 | NullASTNode() { kind = NK_UNKNOWN; } 220 | 221 | ~NullASTNode() {} 222 | 223 | void accept(TreeVisitor *v); 224 | 225 | static NullASTNode *getInstance() 226 | { 227 | if (!s_instance) 228 | s_instance = new NullASTNode(); 229 | return s_instance; 230 | } 231 | }; 232 | 233 | #define NULL_AST_NODE NullASTNode::getInstance() 234 | 235 | class IdentASTNode : public ASTNode 236 | { 237 | std::string _value; 238 | 239 | public: 240 | IdentASTNode(const std::string &VALUE) 241 | { 242 | _value = VALUE; 243 | kind = NK_IDENT_NODE; 244 | } 245 | 246 | IdentASTNode(const std::string &VALUE, int LineNum) 247 | { 248 | _value = VALUE; 249 | lineNum = LineNum; 250 | kind = NK_IDENT_NODE; 251 | } 252 | 253 | const char *getValue() { return _value.c_str(); } 254 | 255 | //STType *checkType(AbstractSyntaxTree *ast); 256 | void accept(TreeVisitor *v); 257 | }; 258 | 259 | class IntegerConstASTNode : public ASTNode 260 | { 261 | int _value; 262 | 263 | public: 264 | IntegerConstASTNode(int VALUE) 265 | { 266 | _value = VALUE; 267 | kind = NK_INTEGER_CONST; 268 | } 269 | 270 | int getValue() { return _value; } 271 | 272 | //STType *checkType(AbstractSyntaxTree *ast); 273 | void accept(TreeVisitor *v); 274 | }; 275 | 276 | class RealConstASTNode : public ASTNode 277 | { 278 | int _value; 279 | 280 | public: 281 | RealConstASTNode(int VALUE) 282 | { 283 | _value = VALUE; 284 | kind = NK_REAL_CONST; 285 | } 286 | 287 | float getValue() { return _value; } 288 | 289 | //STType *checkType(AbstractSyntaxTree *ast); 290 | void accept(TreeVisitor *v); 291 | }; 292 | 293 | class StringConstASTNode : public ASTNode 294 | { 295 | std::string _value; 296 | public: 297 | StringConstASTNode(const std::string &val) 298 | { 299 | _value = val; 300 | kind = NK_STRING_CONST; 301 | } 302 | 303 | const char *getValue() { return _value.c_str(); } 304 | 305 | //STType *checkType(AbstractSyntaxTree *ast); 306 | void accept(TreeVisitor *v); 307 | }; 308 | 309 | class CharConstASTNode : public ASTNode 310 | { 311 | int _value; 312 | 313 | public: 314 | CharConstASTNode(int VALUE) 315 | { 316 | _value = VALUE; 317 | kind = NK_CHAR_CONST; 318 | } 319 | 320 | int getValue() { return _value; } 321 | 322 | //STType *checkType(AbstractSyntaxTree *ast); 323 | void accept(TreeVisitor *v); 324 | }; 325 | 326 | class SizeOfExprASTNode : public ASTNode 327 | { 328 | ASTNode *_expr; 329 | 330 | public: 331 | SizeOfExprASTNode(ASTNode *Expr) 332 | { 333 | kind = NK_SIZEOF_EXPR; 334 | ASSIGN_AST_NODE_REF(_expr, Expr); 335 | } 336 | 337 | ~SizeOfExprASTNode() 338 | { 339 | DELETE_AST_NODE_REF(_expr); 340 | } 341 | 342 | ASTNode *getExpr() { return _expr; } 343 | 344 | 345 | //STType *checkType(AbstractSyntaxTree *ast); 346 | void accept(TreeVisitor *v); 347 | }; 348 | 349 | class AlignOfExprASTNode : public ASTNode 350 | { 351 | ASTNode *_expr; 352 | 353 | public: 354 | AlignOfExprASTNode(ASTNode *Expr) 355 | { 356 | kind = NK_SIZEOF_EXPR; 357 | ASSIGN_AST_NODE_REF(_expr, Expr); 358 | } 359 | 360 | ~AlignOfExprASTNode() 361 | { 362 | DELETE_AST_NODE_REF(_expr); 363 | } 364 | 365 | ASTNode *getExpr() { return _expr; } 366 | 367 | //STType *checkType(AbstractSyntaxTree *ast); 368 | void accept(TreeVisitor *v); 369 | }; 370 | 371 | class TypeDeclASTNode : public ASTNode 372 | { 373 | ASTNode *_name; 374 | ASTNode *_body; 375 | 376 | public: 377 | TypeDeclASTNode(ASTNode *Name, ASTNode *Body) 378 | { 379 | kind = NK_TYPE_DECL; 380 | ASSIGN_AST_NODE_REF(_name, Name); 381 | ASSIGN_AST_NODE_REF(_body, Body); 382 | } 383 | 384 | ~TypeDeclASTNode() 385 | { 386 | DELETE_AST_NODE_REF(_name); 387 | DELETE_AST_NODE_REF(_body); 388 | } 389 | 390 | void setName(ASTNode *Name) { ASSIGN_AST_NODE_REF(_name, Name); } 391 | void setBody(ASTNode *Body) { ASSIGN_AST_NODE_REF(_body, Body); } 392 | 393 | ASTNode *getName() { return _name; } 394 | ASTNode *getBody() { return _body; } 395 | 396 | void declare(AbstractSyntaxTree *ast); 397 | void accept(TreeVisitor *v); 398 | }; 399 | 400 | class FunctionDeclASTNode : public ASTNode 401 | { 402 | ASTNode *_type; 403 | ASTNode *_name; 404 | ASTNode *_prms; 405 | ASTNode *_body; 406 | STScope *_scope; 407 | 408 | public: 409 | FunctionDeclASTNode(ASTNode *tp, ASTNode *n, ASTNode *p, ASTNode *b) 410 | { 411 | kind = NK_FUNCTION_DECL; 412 | ASSIGN_AST_NODE_REF(_type, tp); 413 | ASSIGN_AST_NODE_REF(_name, n); 414 | ASSIGN_AST_NODE_REF(_prms, p); 415 | ASSIGN_AST_NODE_REF(_body, b); 416 | _scope = nullptr; 417 | } 418 | 419 | ~FunctionDeclASTNode() 420 | { 421 | DELETE_AST_NODE_REF(_type); 422 | DELETE_AST_NODE_REF(_name); 423 | DELETE_AST_NODE_REF(_prms); 424 | DELETE_AST_NODE_REF(_body); 425 | } 426 | 427 | ASTNode *getType() { return _type; } 428 | ASTNode *getName() { return _name; } 429 | ASTNode *getPrms() { return _prms; } 430 | ASTNode *getBody() { return _body; } 431 | 432 | void setType(ASTNode *Type) { ASSIGN_AST_NODE_REF(_type, Type); } 433 | void setName(ASTNode *Name) { ASSIGN_AST_NODE_REF(_name, Name); } 434 | void setPrms(ASTNode *Prms) { ASSIGN_AST_NODE_REF(_prms, Prms); } 435 | void setBody(ASTNode *Body) { ASSIGN_AST_NODE_REF(_body, Body); } 436 | 437 | void setScope(STScope *s) { _scope = s; } 438 | STScope *getScope() { return _scope; } 439 | bool isForwardDeclaration() { return _body == NULL_AST_NODE; } 440 | 441 | void accept(TreeVisitor *v); 442 | }; 443 | 444 | class VarDeclASTNode : public ASTNode 445 | { 446 | ASTNode *_type; 447 | ASTNode *_name; 448 | ASTNode *_init; 449 | 450 | public: 451 | VarDeclASTNode(ASTNode *Type, ASTNode *Name) 452 | { 453 | kind = NK_VAR_DECL; 454 | _init = NULL_AST_NODE; 455 | ASSIGN_AST_NODE_REF(_type, Type); 456 | ASSIGN_AST_NODE_REF(_name, Name); 457 | } 458 | 459 | VarDeclASTNode(ASTNode *Type, ASTNode *Name, ASTNode *Init) 460 | { 461 | kind = NK_VAR_DECL; 462 | ASSIGN_AST_NODE_REF(_type, Type); 463 | ASSIGN_AST_NODE_REF(_name, Name); 464 | ASSIGN_AST_NODE_REF(_init, Init); 465 | } 466 | 467 | ~VarDeclASTNode() 468 | { 469 | DELETE_AST_NODE_REF(_type); 470 | DELETE_AST_NODE_REF(_name); 471 | DELETE_AST_NODE_REF(_init); 472 | } 473 | 474 | void setType(ASTNode *Type) { ASSIGN_AST_NODE_REF(_type, Type); } 475 | void setName(ASTNode *Name) { ASSIGN_AST_NODE_REF(_name, Name); } 476 | void setInit(ASTNode *Init) { ASSIGN_AST_NODE_REF(_init, Init); } 477 | 478 | ASTNode *getName() { return _name; } 479 | ASTNode *getType() { return _type; } 480 | ASTNode *getInit() { return _init; } 481 | 482 | void accept(TreeVisitor *v); 483 | }; 484 | 485 | class ParmDeclASTNode : public ASTNode 486 | { 487 | ASTNode *_type; 488 | ASTNode *_name; 489 | 490 | public: 491 | ParmDeclASTNode(ASTNode *Type, ASTNode *Name) 492 | { 493 | kind = NK_PARM_DECL; 494 | ASSIGN_AST_NODE_REF(_type, Type); 495 | ASSIGN_AST_NODE_REF(_name, Name); 496 | } 497 | 498 | ~ParmDeclASTNode() 499 | { 500 | DELETE_AST_NODE_REF(_type); 501 | DELETE_AST_NODE_REF(_name); 502 | } 503 | 504 | ASTNode *getName() { return _name; } 505 | ASTNode *getType() { return _type; } 506 | 507 | //void declare(AbstractSyntaxTree *ast); 508 | void accept(TreeVisitor *v); 509 | }; 510 | 511 | class FieldDeclASTNode : public ASTNode 512 | { 513 | ASTNode *_type; 514 | ASTNode *_name; 515 | 516 | public: 517 | FieldDeclASTNode(ASTNode *Type, ASTNode *Name) 518 | { 519 | kind = NK_FIELD_DECL; 520 | ASSIGN_AST_NODE_REF(_type, Type); 521 | ASSIGN_AST_NODE_REF(_name, Name); 522 | } 523 | 524 | ~FieldDeclASTNode() 525 | { 526 | DELETE_AST_NODE_REF(_type); 527 | DELETE_AST_NODE_REF(_name); 528 | } 529 | 530 | void setType(ASTNode *Type) { ASSIGN_AST_NODE_REF(_type, Type); } 531 | void setName(ASTNode *Name) { ASSIGN_AST_NODE_REF(_name, Name); } 532 | 533 | ASTNode *getName() { return _name; } 534 | ASTNode *getType() { return _type; } 535 | 536 | //void declare(AbstractSyntaxTree *ast); 537 | void accept(TreeVisitor *v); 538 | }; 539 | 540 | class AsmStmtASTNode : public ASTNode 541 | { 542 | std::string _data; 543 | 544 | public: 545 | AsmStmtASTNode(const std::string &data) 546 | { 547 | _data = data; 548 | } 549 | 550 | ~AsmStmtASTNode() 551 | { 552 | // 553 | } 554 | 555 | const char *getData() { return _data.c_str(); } 556 | 557 | void accept(TreeVisitor *v); 558 | }; 559 | 560 | class BreakStmtASTNode : public ASTNode 561 | { 562 | public: 563 | BreakStmtASTNode() { kind = NK_BREAK_STMT; } 564 | 565 | ~BreakStmtASTNode() {} 566 | 567 | 568 | void accept(TreeVisitor *v); 569 | }; 570 | 571 | class CaseLabelASTNode : public ASTNode 572 | { 573 | ASTNode *_expr; 574 | ASTNode *_stmt; 575 | 576 | public: 577 | CaseLabelASTNode(ASTNode *Expr, ASTNode *Stmt) 578 | { 579 | kind = NK_CASE_LABEL; 580 | ASSIGN_AST_NODE_REF(_expr, Expr); 581 | ASSIGN_AST_NODE_REF(_stmt, Stmt); 582 | } 583 | 584 | ~CaseLabelASTNode() 585 | { 586 | DELETE_AST_NODE_REF(_expr); 587 | DELETE_AST_NODE_REF(_stmt); 588 | } 589 | 590 | ASTNode *getExpr() { return _expr; } 591 | ASTNode *getStmt() { return _stmt; } 592 | 593 | void setExpr(ASTNode *e) 594 | { 595 | DELETE_AST_NODE_REF(_expr); 596 | ASSIGN_AST_NODE_REF(_expr, e); 597 | } 598 | 599 | void setStmt(ASTNode *s) 600 | { 601 | DELETE_AST_NODE_REF(_stmt); 602 | ASSIGN_AST_NODE_REF(_stmt, s); 603 | } 604 | 605 | 606 | void accept(TreeVisitor *v); 607 | }; 608 | 609 | class CompoundStmtASTNode : public ASTNode 610 | { 611 | ASTNode *_decls; 612 | ASTNode *_stmts; 613 | STScope *_scope; 614 | 615 | public: 616 | CompoundStmtASTNode(ASTNode *Decls, ASTNode *Stmts) 617 | { 618 | kind = NK_COMPOUND_STMT; 619 | ASSIGN_AST_NODE_REF(_decls, Decls); 620 | ASSIGN_AST_NODE_REF(_stmts, Stmts); 621 | _scope = nullptr; 622 | } 623 | 624 | ~CompoundStmtASTNode() 625 | { 626 | DELETE_AST_NODE_REF(_decls); 627 | DELETE_AST_NODE_REF(_stmts); 628 | } 629 | 630 | ASTNode *getDecls() { return _decls; } 631 | ASTNode *getStmts() { return _stmts; } 632 | void setDecls(ASTNode *Decls) { ASSIGN_AST_NODE_REF(_decls, Decls); } 633 | void setStmts(ASTNode *Stmts) { ASSIGN_AST_NODE_REF(_stmts, Stmts); } 634 | void setScope(STScope *s) { _scope = s; } 635 | STScope *getScope() { return _scope; } 636 | 637 | void declare(AbstractSyntaxTree *ast); 638 | 639 | void accept(TreeVisitor *v); 640 | }; 641 | 642 | class ContinueStmtASTNode : public ASTNode 643 | { 644 | public: 645 | ContinueStmtASTNode() { kind = NK_CONTINUE_STMT; } 646 | 647 | ~ContinueStmtASTNode() {} 648 | 649 | 650 | void accept(TreeVisitor *v); 651 | }; 652 | 653 | class DoStmtASTNode : public ASTNode 654 | { 655 | ASTNode *_condition; 656 | ASTNode *_body; 657 | 658 | public: 659 | DoStmtASTNode(ASTNode *Condition, ASTNode *Body) 660 | { 661 | kind = NK_DO_STMT; 662 | ASSIGN_AST_NODE_REF(_condition, Condition); 663 | ASSIGN_AST_NODE_REF(_body, Body); 664 | } 665 | 666 | ~DoStmtASTNode() 667 | { 668 | DELETE_AST_NODE_REF(_condition); 669 | DELETE_AST_NODE_REF(_body); 670 | } 671 | 672 | ASTNode *getCondition() { return _condition; } 673 | ASTNode *getBody() { return _body; } 674 | 675 | 676 | void accept(TreeVisitor *v); 677 | }; 678 | 679 | class ForStmtASTNode : public ASTNode 680 | { 681 | ASTNode *_init; 682 | ASTNode *_condition; 683 | ASTNode *_step; 684 | ASTNode *_body; 685 | 686 | public: 687 | ForStmtASTNode(ASTNode *Init, 688 | ASTNode *Condition, 689 | ASTNode *Step, 690 | ASTNode *Body) 691 | { 692 | kind = NK_FOR_STMT; 693 | ASSIGN_AST_NODE_REF(_init, Init); 694 | ASSIGN_AST_NODE_REF(_condition, Condition); 695 | ASSIGN_AST_NODE_REF(_step, Step); 696 | ASSIGN_AST_NODE_REF(_body, Body); 697 | } 698 | 699 | ~ForStmtASTNode() 700 | { 701 | DELETE_AST_NODE_REF(_init); 702 | DELETE_AST_NODE_REF(_condition); 703 | DELETE_AST_NODE_REF(_step); 704 | DELETE_AST_NODE_REF(_body); 705 | } 706 | 707 | ASTNode *getInit() { return _init; } 708 | ASTNode *getCondition() { return _condition; } 709 | ASTNode *getBody() { return _body; } 710 | ASTNode *getStep() { return _step; } 711 | 712 | 713 | void accept(TreeVisitor *v); 714 | }; 715 | 716 | class GotoStmtASTNode : public ASTNode 717 | { 718 | ASTNode *_label; 719 | 720 | public: 721 | GotoStmtASTNode(ASTNode *Label) 722 | { 723 | kind = NK_GOTO_STMT; 724 | ASSIGN_AST_NODE_REF(_label, Label); 725 | } 726 | 727 | ~GotoStmtASTNode() 728 | { 729 | DELETE_AST_NODE_REF(_label); 730 | } 731 | 732 | ASTNode *getLabel() 733 | { 734 | return _label; 735 | } 736 | 737 | void accept(TreeVisitor *v); 738 | }; 739 | 740 | class IfStmtASTNode : public ASTNode 741 | { 742 | ASTNode *_condition; 743 | ASTNode *_thenClause; 744 | ASTNode *_elseClause; 745 | 746 | public: 747 | IfStmtASTNode(ASTNode *Condition, ASTNode *ThenClause, ASTNode *ElseClause) 748 | { 749 | kind = NK_IF_STMT; 750 | ASSIGN_AST_NODE_REF(_condition, Condition); 751 | ASSIGN_AST_NODE_REF(_thenClause, ThenClause); 752 | ASSIGN_AST_NODE_REF(_elseClause, ElseClause); 753 | } 754 | 755 | ~IfStmtASTNode() 756 | { 757 | DELETE_AST_NODE_REF(_condition); 758 | DELETE_AST_NODE_REF(_thenClause); 759 | DELETE_AST_NODE_REF(_elseClause); 760 | } 761 | 762 | ASTNode *getCondition() { return _condition; } 763 | ASTNode *getThenClause() { return _thenClause; } 764 | ASTNode *getElseClause() { return _elseClause; } 765 | 766 | 767 | void accept(TreeVisitor *v); 768 | }; 769 | 770 | class LabelStmtASTNode : public ASTNode 771 | { 772 | ASTNode *_label; 773 | ASTNode *_stmt; 774 | 775 | public: 776 | LabelStmtASTNode(ASTNode *Label, ASTNode *Stmt) 777 | { 778 | kind = NK_LABEL_STMT; 779 | ASSIGN_AST_NODE_REF(_label, Label); 780 | ASSIGN_AST_NODE_REF(_stmt, Stmt); 781 | } 782 | 783 | ~LabelStmtASTNode() 784 | { 785 | DELETE_AST_NODE_REF(_label); 786 | DELETE_AST_NODE_REF(_stmt); 787 | } 788 | 789 | ASTNode *getLabel() { return _label; } 790 | ASTNode *getStmt() { return _stmt; } 791 | 792 | 793 | void accept(TreeVisitor *v); 794 | }; 795 | 796 | class ReturnStmtASTNode : public ASTNode 797 | { 798 | ASTNode *_type; 799 | ASTNode *_expr; 800 | 801 | public: 802 | ReturnStmtASTNode(ASTNode *Type, ASTNode *Expr) 803 | { 804 | kind = NK_RETURN_STMT; 805 | ASSIGN_AST_NODE_REF(_type, Type); 806 | ASSIGN_AST_NODE_REF(_expr, Expr); 807 | } 808 | 809 | ~ReturnStmtASTNode() 810 | { 811 | DELETE_AST_NODE_REF(_type); 812 | DELETE_AST_NODE_REF(_expr); 813 | } 814 | 815 | ASTNode *getExpr() { return _expr; } 816 | 817 | //STType *checkType(AbstractSyntaxTree *ast); 818 | void accept(TreeVisitor *v); 819 | }; 820 | 821 | class SwitchStmtASTNode : public ASTNode 822 | { 823 | ASTNode *_expr; 824 | ASTNode *_stmt; 825 | 826 | public: 827 | SwitchStmtASTNode(ASTNode *Expr, ASTNode *Stmt) 828 | { 829 | kind = NK_SWITCH_STMT; 830 | ASSIGN_AST_NODE_REF(_expr, Expr); 831 | ASSIGN_AST_NODE_REF(_stmt, Stmt); 832 | } 833 | 834 | ~SwitchStmtASTNode() 835 | { 836 | DELETE_AST_NODE_REF(_expr); 837 | DELETE_AST_NODE_REF(_stmt); 838 | } 839 | 840 | ASTNode *getExpr() { return _expr; } 841 | ASTNode *getStmt() { return _stmt; } 842 | 843 | 844 | void accept(TreeVisitor *v); 845 | }; 846 | 847 | class WhileStmtASTNode : public ASTNode 848 | { 849 | ASTNode *_condition; 850 | ASTNode *_body; 851 | 852 | public: 853 | WhileStmtASTNode(ASTNode *Condition, ASTNode *Body) 854 | { 855 | kind = NK_WHILE_STMT; 856 | ASSIGN_AST_NODE_REF(_condition, Condition); 857 | ASSIGN_AST_NODE_REF(_body, Body); 858 | } 859 | 860 | ~WhileStmtASTNode() 861 | { 862 | DELETE_AST_NODE_REF(_condition); 863 | DELETE_AST_NODE_REF(_body); 864 | } 865 | 866 | ASTNode *getCondition() { return _condition; } 867 | ASTNode *getBody() { return _body; } 868 | 869 | 870 | void accept(TreeVisitor *v); 871 | }; 872 | 873 | class CastExprASTNode : public ASTNode 874 | { 875 | ASTNode *_type; 876 | ASTNode *_expr; 877 | 878 | public: 879 | CastExprASTNode(ASTNode *Type, ASTNode *Expr) 880 | { 881 | kind = NK_CAST_EXPR; 882 | ASSIGN_AST_NODE_REF(_type, Type); 883 | ASSIGN_AST_NODE_REF(_expr, Expr); 884 | } 885 | 886 | ~CastExprASTNode() 887 | { 888 | DELETE_AST_NODE_REF(_type); 889 | DELETE_AST_NODE_REF(_expr); 890 | } 891 | 892 | ASTNode *getType() { return _type; } 893 | ASTNode *getExpr() { return _expr; } 894 | 895 | //STType *checkType(AbstractSyntaxTree *ast); 896 | void accept(TreeVisitor *v); 897 | }; 898 | 899 | class BitNotExprASTNode : public ASTNode 900 | { 901 | ASTNode *_type; 902 | ASTNode *_expr; 903 | 904 | public: 905 | BitNotExprASTNode(ASTNode *Type, ASTNode *Expr) 906 | { 907 | kind = NK_BIT_NOT_EXPR; 908 | ASSIGN_AST_NODE_REF(_type, Type); 909 | ASSIGN_AST_NODE_REF(_expr, Expr); 910 | } 911 | 912 | ~BitNotExprASTNode() 913 | { 914 | DELETE_AST_NODE_REF(_type); 915 | DELETE_AST_NODE_REF(_expr); 916 | } 917 | 918 | ASTNode *getExpr() { return _expr; } 919 | 920 | //STType *checkType(AbstractSyntaxTree *ast); 921 | void accept(TreeVisitor *v); 922 | }; 923 | 924 | class LogNotExprASTNode : public ASTNode 925 | { 926 | ASTNode *_type; 927 | ASTNode *_expr; 928 | 929 | public: 930 | LogNotExprASTNode(ASTNode *Type, ASTNode *Expr) 931 | { 932 | kind = NK_LOG_NOT_EXPR; 933 | ASSIGN_AST_NODE_REF(_type, Type); 934 | ASSIGN_AST_NODE_REF(_expr, Expr); 935 | } 936 | 937 | ~LogNotExprASTNode() 938 | { 939 | DELETE_AST_NODE_REF(_type); 940 | DELETE_AST_NODE_REF(_expr); 941 | } 942 | 943 | ASTNode *getExpr() { return _expr; } 944 | 945 | //STType *checkType(AbstractSyntaxTree *ast); 946 | void accept(TreeVisitor *v); 947 | }; 948 | 949 | class PredecrementExprASTNode : public ASTNode 950 | { 951 | ASTNode *_expr; 952 | 953 | public: 954 | PredecrementExprASTNode(ASTNode *Expr) 955 | { 956 | kind = NK_PREDECREMENT_EXPR; 957 | ASSIGN_AST_NODE_REF(_expr, Expr); 958 | } 959 | 960 | ~PredecrementExprASTNode() { DELETE_AST_NODE_REF(_expr); } 961 | 962 | ASTNode *getExpr() { return _expr; } 963 | 964 | //STType *checkType(AbstractSyntaxTree *ast); 965 | void accept(TreeVisitor *v); 966 | }; 967 | 968 | class PreincrementExprASTNode : public ASTNode 969 | { 970 | ASTNode *_expr; 971 | 972 | public: 973 | PreincrementExprASTNode(ASTNode *Expr) 974 | { 975 | kind = NK_PREINCREMENT_EXPR; 976 | ASSIGN_AST_NODE_REF(_expr, Expr); 977 | } 978 | 979 | ~PreincrementExprASTNode() { DELETE_AST_NODE_REF(_expr); } 980 | 981 | ASTNode *getExpr() { return _expr; } 982 | 983 | //STType *checkType(AbstractSyntaxTree *ast); 984 | void accept(TreeVisitor *v); 985 | }; 986 | 987 | class PostdecrementExprASTNode : public ASTNode 988 | { 989 | ASTNode *_expr; 990 | 991 | public: 992 | PostdecrementExprASTNode(ASTNode *Expr) 993 | { 994 | kind = NK_POSTDECREMENT_EXPR; 995 | ASSIGN_AST_NODE_REF(_expr, Expr); 996 | } 997 | 998 | ~PostdecrementExprASTNode() { DELETE_AST_NODE_REF(_expr); } 999 | 1000 | ASTNode *getExpr() { return _expr; } 1001 | 1002 | 1003 | //STType *checkType(AbstractSyntaxTree *ast); 1004 | void accept(TreeVisitor *v); 1005 | }; 1006 | 1007 | class PostincrementExprASTNode : public ASTNode 1008 | { 1009 | ASTNode *_expr; 1010 | 1011 | public: 1012 | PostincrementExprASTNode(ASTNode *Expr) 1013 | { 1014 | kind = NK_POSTINCREMENT_EXPR; 1015 | ASSIGN_AST_NODE_REF(_expr, Expr); 1016 | } 1017 | 1018 | ~PostincrementExprASTNode() { DELETE_AST_NODE_REF(_expr); } 1019 | 1020 | ASTNode *getExpr() { return _expr; } 1021 | 1022 | //STType *checkType(AbstractSyntaxTree *ast); 1023 | void accept(TreeVisitor *v); 1024 | }; 1025 | 1026 | class AddrExprASTNode : public ASTNode 1027 | { 1028 | ASTNode *_type; 1029 | ASTNode *_expr; 1030 | 1031 | public: 1032 | AddrExprASTNode(ASTNode *Type, ASTNode *Expr) 1033 | { 1034 | kind = NK_ADDR_EXPR; 1035 | ASSIGN_AST_NODE_REF(_type, Type); 1036 | ASSIGN_AST_NODE_REF(_expr, Expr); 1037 | } 1038 | 1039 | ~AddrExprASTNode() 1040 | { 1041 | DELETE_AST_NODE_REF(_type); 1042 | DELETE_AST_NODE_REF(_expr); 1043 | } 1044 | 1045 | ASTNode *getExpr() { return _expr; } 1046 | 1047 | //STType *checkType(AbstractSyntaxTree *ast); 1048 | void accept(TreeVisitor *v); 1049 | }; 1050 | 1051 | class IndirectRefASTNode : public ASTNode 1052 | { 1053 | ASTNode *_type; 1054 | ASTNode *_expr; 1055 | ASTNode *_field; 1056 | 1057 | public: 1058 | IndirectRefASTNode(ASTNode *Type, ASTNode *Expr, ASTNode *Field) 1059 | { 1060 | kind = NK_INDIRECT_REF; 1061 | ASSIGN_AST_NODE_REF(_type, Type); 1062 | ASSIGN_AST_NODE_REF(_expr, Expr); 1063 | ASSIGN_AST_NODE_REF(_field, Field); 1064 | } 1065 | 1066 | ~IndirectRefASTNode() 1067 | { 1068 | DELETE_AST_NODE_REF(_type); 1069 | DELETE_AST_NODE_REF(_expr); 1070 | DELETE_AST_NODE_REF(_field); 1071 | } 1072 | 1073 | ASTNode *getType() { return _type; } 1074 | ASTNode *getExpr() { return _expr; } 1075 | ASTNode *getField() { return _field; } 1076 | 1077 | void setExpr(ASTNode *e) 1078 | { 1079 | DELETE_AST_NODE_REF(_expr); 1080 | ASSIGN_AST_NODE_REF(_expr, e); 1081 | } 1082 | 1083 | void setField(ASTNode *f) 1084 | { 1085 | DELETE_AST_NODE_REF(_field); 1086 | ASSIGN_AST_NODE_REF(_field, f); 1087 | } 1088 | 1089 | //STType *checkType(AbstractSyntaxTree *ast); 1090 | void accept(TreeVisitor *v); 1091 | }; 1092 | 1093 | class NopExprASTNode : public ASTNode 1094 | { 1095 | public: 1096 | NopExprASTNode() { kind = NK_NOP_EXPR; } 1097 | 1098 | ~NopExprASTNode() {} 1099 | 1100 | // //STType *checkType(AbstractSyntaxTree *ast); 1101 | void accept(TreeVisitor *v); 1102 | }; 1103 | 1104 | class LShiftExprASTNode : public ASTNode 1105 | { 1106 | ASTNode *_type; 1107 | ASTNode *_lhs; 1108 | ASTNode *_rhs; 1109 | 1110 | public: 1111 | LShiftExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1112 | { 1113 | kind = NK_LSHIFT_EXPR; 1114 | ASSIGN_AST_NODE_REF(_type, Type); 1115 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1116 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1117 | } 1118 | 1119 | ~LShiftExprASTNode() 1120 | { 1121 | DELETE_AST_NODE_REF(_type); 1122 | DELETE_AST_NODE_REF(_lhs); 1123 | DELETE_AST_NODE_REF(_rhs); 1124 | } 1125 | 1126 | ASTNode *getLhs() { return _lhs; } 1127 | ASTNode *getRhs() { return _rhs; } 1128 | 1129 | //STType *checkType(AbstractSyntaxTree *ast); 1130 | void accept(TreeVisitor *v); 1131 | }; 1132 | 1133 | class RShiftExprASTNode : public ASTNode 1134 | { 1135 | ASTNode *_type; 1136 | ASTNode *_lhs; 1137 | ASTNode *_rhs; 1138 | 1139 | public: 1140 | RShiftExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1141 | { 1142 | kind = NK_RSHIFT_EXPR; 1143 | ASSIGN_AST_NODE_REF(_type, Type); 1144 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1145 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1146 | } 1147 | 1148 | ~RShiftExprASTNode() 1149 | { 1150 | DELETE_AST_NODE_REF(_type); 1151 | DELETE_AST_NODE_REF(_lhs); 1152 | DELETE_AST_NODE_REF(_rhs); 1153 | } 1154 | 1155 | ASTNode *getLhs() { return _lhs; } 1156 | ASTNode *getRhs() { return _rhs; } 1157 | 1158 | //STType *checkType(AbstractSyntaxTree *ast); 1159 | void accept(TreeVisitor *v); 1160 | }; 1161 | 1162 | class BitIorExprASTNode : public ASTNode 1163 | { 1164 | ASTNode *_type; 1165 | ASTNode *_lhs; 1166 | ASTNode *_rhs; 1167 | 1168 | public: 1169 | BitIorExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1170 | { 1171 | kind = NK_BIT_IOR_EXPR; 1172 | ASSIGN_AST_NODE_REF(_type, Type); 1173 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1174 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1175 | } 1176 | 1177 | ~BitIorExprASTNode() 1178 | { 1179 | DELETE_AST_NODE_REF(_type); 1180 | DELETE_AST_NODE_REF(_lhs); 1181 | DELETE_AST_NODE_REF(_rhs); 1182 | } 1183 | 1184 | ASTNode *getLhs() { return _lhs; } 1185 | ASTNode *getRhs() { return _rhs; } 1186 | 1187 | //STType *checkType(AbstractSyntaxTree *ast); 1188 | void accept(TreeVisitor *v); 1189 | }; 1190 | 1191 | class BitXorExprASTNode : public ASTNode 1192 | { 1193 | ASTNode *_type; 1194 | ASTNode *_lhs; 1195 | ASTNode *_rhs; 1196 | 1197 | public: 1198 | BitXorExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1199 | { 1200 | kind = NK_BIT_XOR_EXPR; 1201 | ASSIGN_AST_NODE_REF(_type, Type); 1202 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1203 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1204 | } 1205 | 1206 | ~BitXorExprASTNode() 1207 | { 1208 | DELETE_AST_NODE_REF(_type); 1209 | DELETE_AST_NODE_REF(_lhs); 1210 | DELETE_AST_NODE_REF(_rhs); 1211 | } 1212 | 1213 | ASTNode *getLhs() { return _lhs; } 1214 | ASTNode *getRhs() { return _rhs; } 1215 | 1216 | //STType *checkType(AbstractSyntaxTree *ast); 1217 | void accept(TreeVisitor *v); 1218 | }; 1219 | 1220 | class BitAndExprASTNode : public ASTNode 1221 | { 1222 | ASTNode *_type; 1223 | ASTNode *_lhs; 1224 | ASTNode *_rhs; 1225 | 1226 | public: 1227 | BitAndExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1228 | { 1229 | kind = NK_BIT_AND_EXPR; 1230 | ASSIGN_AST_NODE_REF(_type, Type); 1231 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1232 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1233 | } 1234 | 1235 | ~BitAndExprASTNode() 1236 | { 1237 | DELETE_AST_NODE_REF(_type); 1238 | DELETE_AST_NODE_REF(_lhs); 1239 | DELETE_AST_NODE_REF(_rhs); 1240 | } 1241 | 1242 | ASTNode *getLhs() { return _lhs; } 1243 | ASTNode *getRhs() { return _rhs; } 1244 | 1245 | //STType *checkType(AbstractSyntaxTree *ast); 1246 | void accept(TreeVisitor *v); 1247 | }; 1248 | 1249 | class LogAndExprASTNode : public ASTNode 1250 | { 1251 | ASTNode *_type; 1252 | ASTNode *_lhs; 1253 | ASTNode *_rhs; 1254 | 1255 | public: 1256 | LogAndExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1257 | { 1258 | kind = NK_LOG_AND_EXPR; 1259 | ASSIGN_AST_NODE_REF(_type, Type); 1260 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1261 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1262 | } 1263 | 1264 | ~LogAndExprASTNode() 1265 | { 1266 | DELETE_AST_NODE_REF(_type); 1267 | DELETE_AST_NODE_REF(_lhs); 1268 | DELETE_AST_NODE_REF(_rhs); 1269 | } 1270 | 1271 | ASTNode *getLhs() { return _lhs; } 1272 | ASTNode *getRhs() { return _rhs; } 1273 | 1274 | //STType *checkType(AbstractSyntaxTree *ast); 1275 | void accept(TreeVisitor *v); 1276 | }; 1277 | 1278 | class LogOrExprASTNode : public ASTNode 1279 | { 1280 | ASTNode *_type; 1281 | ASTNode *_lhs; 1282 | ASTNode *_rhs; 1283 | 1284 | public: 1285 | LogOrExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1286 | { 1287 | kind = NK_LOG_OR_EXPR; 1288 | ASSIGN_AST_NODE_REF(_type, Type); 1289 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1290 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1291 | } 1292 | 1293 | ~LogOrExprASTNode() 1294 | { 1295 | DELETE_AST_NODE_REF(_type); 1296 | DELETE_AST_NODE_REF(_lhs); 1297 | DELETE_AST_NODE_REF(_rhs); 1298 | } 1299 | 1300 | ASTNode *getLhs() { return _lhs; } 1301 | ASTNode *getRhs() { return _rhs; } 1302 | 1303 | //STType *checkType(AbstractSyntaxTree *ast); 1304 | void accept(TreeVisitor *v); 1305 | }; 1306 | 1307 | class PlusExprASTNode : public ASTNode 1308 | { 1309 | ASTNode *_type; 1310 | ASTNode *_lhs; 1311 | ASTNode *_rhs; 1312 | 1313 | public: 1314 | PlusExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1315 | { 1316 | kind = NK_PLUS_EXPR; 1317 | ASSIGN_AST_NODE_REF(_type, Type); 1318 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1319 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1320 | } 1321 | 1322 | ~PlusExprASTNode() 1323 | { 1324 | DELETE_AST_NODE_REF(_type); 1325 | DELETE_AST_NODE_REF(_lhs); 1326 | DELETE_AST_NODE_REF(_rhs); 1327 | } 1328 | 1329 | ASTNode *getLhs() { return _lhs; } 1330 | ASTNode *getRhs() { return _rhs; } 1331 | 1332 | //STType *checkType(AbstractSyntaxTree *ast); 1333 | void accept(TreeVisitor *v); 1334 | }; 1335 | 1336 | class MinusExprASTNode : public ASTNode 1337 | { 1338 | ASTNode *_type; 1339 | ASTNode *_lhs; 1340 | ASTNode *_rhs; 1341 | 1342 | public: 1343 | MinusExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1344 | { 1345 | kind = NK_MINUS_EXPR; 1346 | ASSIGN_AST_NODE_REF(_type, Type); 1347 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1348 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1349 | } 1350 | 1351 | ~MinusExprASTNode() 1352 | { 1353 | DELETE_AST_NODE_REF(_type); 1354 | DELETE_AST_NODE_REF(_lhs); 1355 | DELETE_AST_NODE_REF(_rhs); 1356 | } 1357 | 1358 | ASTNode *getLhs() { return _lhs; } 1359 | ASTNode *getRhs() { return _rhs; } 1360 | 1361 | //STType *checkType(AbstractSyntaxTree *ast); 1362 | void accept(TreeVisitor *v); 1363 | }; 1364 | 1365 | class MultExprASTNode : public ASTNode 1366 | { 1367 | ASTNode *_type; 1368 | ASTNode *_lhs; 1369 | ASTNode *_rhs; 1370 | 1371 | public: 1372 | MultExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1373 | { 1374 | kind = NK_MULT_EXPR; 1375 | ASSIGN_AST_NODE_REF(_type, Type); 1376 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1377 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1378 | } 1379 | 1380 | ~MultExprASTNode() 1381 | { 1382 | DELETE_AST_NODE_REF(_type); 1383 | DELETE_AST_NODE_REF(_lhs); 1384 | DELETE_AST_NODE_REF(_rhs); 1385 | } 1386 | 1387 | ASTNode *getLhs() { return _lhs; } 1388 | ASTNode *getRhs() { return _rhs; } 1389 | 1390 | //STType *checkType(AbstractSyntaxTree *ast); 1391 | void accept(TreeVisitor *v); 1392 | }; 1393 | 1394 | class TruncDivExprASTNode : public ASTNode 1395 | { 1396 | ASTNode *_type; 1397 | ASTNode *_lhs; 1398 | ASTNode *_rhs; 1399 | 1400 | public: 1401 | TruncDivExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1402 | { 1403 | kind = NK_TRUNC_DIV_EXPR; 1404 | ASSIGN_AST_NODE_REF(_type, Type); 1405 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1406 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1407 | } 1408 | 1409 | ~TruncDivExprASTNode() 1410 | { 1411 | DELETE_AST_NODE_REF(_type); 1412 | DELETE_AST_NODE_REF(_lhs); 1413 | DELETE_AST_NODE_REF(_rhs); 1414 | } 1415 | 1416 | ASTNode *getLhs() { return _lhs; } 1417 | ASTNode *getRhs() { return _rhs; } 1418 | 1419 | //STType *checkType(AbstractSyntaxTree *ast); 1420 | void accept(TreeVisitor *v); 1421 | }; 1422 | 1423 | class TruncModExprASTNode : public ASTNode 1424 | { 1425 | ASTNode *_type; 1426 | ASTNode *_lhs; 1427 | ASTNode *_rhs; 1428 | 1429 | public: 1430 | TruncModExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1431 | { 1432 | kind = NK_TRUNC_MOD_EXPR; 1433 | ASSIGN_AST_NODE_REF(_type, Type); 1434 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1435 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1436 | } 1437 | 1438 | ~TruncModExprASTNode() 1439 | { 1440 | DELETE_AST_NODE_REF(_type); 1441 | DELETE_AST_NODE_REF(_lhs); 1442 | DELETE_AST_NODE_REF(_rhs); 1443 | } 1444 | 1445 | ASTNode *getLhs() { return _lhs; } 1446 | ASTNode *getRhs() { return _rhs; } 1447 | 1448 | //STType *checkType(AbstractSyntaxTree *ast); 1449 | void accept(TreeVisitor *v); 1450 | }; 1451 | 1452 | class ArrayRefASTNode : public ASTNode 1453 | { 1454 | ASTNode *_type; 1455 | ASTNode *_expr; 1456 | ASTNode *_index; 1457 | 1458 | public: 1459 | ArrayRefASTNode(ASTNode *Type, ASTNode *Expr, ASTNode *Index) 1460 | { 1461 | kind = NK_ARRAY_REF; 1462 | ASSIGN_AST_NODE_REF(_type, Type); 1463 | ASSIGN_AST_NODE_REF(_expr, Expr); 1464 | ASSIGN_AST_NODE_REF(_index, Index); 1465 | } 1466 | 1467 | ~ArrayRefASTNode() 1468 | { 1469 | DELETE_AST_NODE_REF(_type); 1470 | DELETE_AST_NODE_REF(_expr); 1471 | DELETE_AST_NODE_REF(_index); 1472 | } 1473 | 1474 | ASTNode *getType() { return _type; } 1475 | ASTNode *getExpr() { return _expr; } 1476 | ASTNode *getIndex() { return _index; } 1477 | 1478 | //STType *checkType(AbstractSyntaxTree *ast); 1479 | void accept(TreeVisitor *v); 1480 | }; 1481 | 1482 | class StructRefASTNode : public ASTNode 1483 | { 1484 | ASTNode *_name; 1485 | ASTNode *_member; 1486 | 1487 | public: 1488 | StructRefASTNode(ASTNode *Name, ASTNode *Member) 1489 | { 1490 | kind = NK_STRUCT_REF; 1491 | ASSIGN_AST_NODE_REF(_name, Name); 1492 | ASSIGN_AST_NODE_REF(_member, Member); 1493 | } 1494 | 1495 | ~StructRefASTNode() 1496 | { 1497 | DELETE_AST_NODE_REF(_name); 1498 | DELETE_AST_NODE_REF(_member); 1499 | } 1500 | 1501 | void setName(ASTNode *Name) { _name = Name; } 1502 | void setMember(ASTNode *Member) { _member = Member; } 1503 | 1504 | ASTNode *getName() { return _name; } 1505 | ASTNode *getMember() { return _member; } 1506 | 1507 | //STType *checkType(AbstractSyntaxTree *ast); 1508 | void accept(TreeVisitor *v); 1509 | }; 1510 | 1511 | class LtExprASTNode : public ASTNode 1512 | { 1513 | ASTNode *_type; 1514 | ASTNode *_lhs; 1515 | ASTNode *_rhs; 1516 | 1517 | public: 1518 | LtExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1519 | { 1520 | kind = NK_LT_EXPR; 1521 | ASSIGN_AST_NODE_REF(_type, Type); 1522 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1523 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1524 | } 1525 | 1526 | ~LtExprASTNode() 1527 | { 1528 | DELETE_AST_NODE_REF(_type); 1529 | DELETE_AST_NODE_REF(_lhs); 1530 | DELETE_AST_NODE_REF(_rhs); 1531 | } 1532 | 1533 | ASTNode *getLhs() { return _lhs; } 1534 | ASTNode *getRhs() { return _rhs; } 1535 | 1536 | //STType *checkType(AbstractSyntaxTree *ast); 1537 | void accept(TreeVisitor *v); 1538 | }; 1539 | 1540 | class LeExprASTNode : public ASTNode 1541 | { 1542 | ASTNode *_type; 1543 | ASTNode *_lhs; 1544 | ASTNode *_rhs; 1545 | 1546 | public: 1547 | LeExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1548 | { 1549 | kind = NK_LE_EXPR; 1550 | ASSIGN_AST_NODE_REF(_type, Type); 1551 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1552 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1553 | } 1554 | 1555 | ~LeExprASTNode() 1556 | { 1557 | DELETE_AST_NODE_REF(_type); 1558 | DELETE_AST_NODE_REF(_lhs); 1559 | DELETE_AST_NODE_REF(_rhs); 1560 | } 1561 | 1562 | ASTNode *getLhs() { return _lhs; } 1563 | ASTNode *getRhs() { return _rhs; } 1564 | 1565 | //STType *checkType(AbstractSyntaxTree *ast); 1566 | void accept(TreeVisitor *v); 1567 | }; 1568 | 1569 | class GtExprASTNode : public ASTNode 1570 | { 1571 | ASTNode *_type; 1572 | ASTNode *_lhs; 1573 | ASTNode *_rhs; 1574 | 1575 | public: 1576 | GtExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1577 | { 1578 | kind = NK_GT_EXPR; 1579 | ASSIGN_AST_NODE_REF(_type, Type); 1580 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1581 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1582 | } 1583 | 1584 | ~GtExprASTNode() 1585 | { 1586 | DELETE_AST_NODE_REF(_type); 1587 | DELETE_AST_NODE_REF(_lhs); 1588 | DELETE_AST_NODE_REF(_rhs); 1589 | } 1590 | 1591 | ASTNode *getLhs() { return _lhs; } 1592 | ASTNode *getRhs() { return _rhs; } 1593 | 1594 | //STType *checkType(AbstractSyntaxTree *ast); 1595 | void accept(TreeVisitor *v); 1596 | }; 1597 | 1598 | class GeExprASTNode : public ASTNode 1599 | { 1600 | ASTNode *_type; 1601 | ASTNode *_lhs; 1602 | ASTNode *_rhs; 1603 | 1604 | public: 1605 | GeExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1606 | { 1607 | kind = NK_GE_EXPR; 1608 | 1609 | ASSIGN_AST_NODE_REF(_type, Type); 1610 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1611 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1612 | } 1613 | 1614 | ~GeExprASTNode() 1615 | { 1616 | DELETE_AST_NODE_REF(_type); 1617 | DELETE_AST_NODE_REF(_lhs); 1618 | DELETE_AST_NODE_REF(_rhs); 1619 | } 1620 | 1621 | ASTNode *getLhs() { return _lhs; } 1622 | ASTNode *getRhs() { return _rhs; } 1623 | 1624 | //STType *checkType(AbstractSyntaxTree *ast); 1625 | void accept(TreeVisitor *v); 1626 | }; 1627 | 1628 | class EqExprASTNode : public ASTNode 1629 | { 1630 | ASTNode *_type; 1631 | ASTNode *_lhs; 1632 | ASTNode *_rhs; 1633 | 1634 | public: 1635 | EqExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1636 | { 1637 | kind = NK_EQ_EXPR; 1638 | ASSIGN_AST_NODE_REF(_type, Type); 1639 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1640 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1641 | } 1642 | 1643 | ~EqExprASTNode() 1644 | { 1645 | DELETE_AST_NODE_REF(_type); 1646 | DELETE_AST_NODE_REF(_lhs); 1647 | DELETE_AST_NODE_REF(_rhs); 1648 | } 1649 | 1650 | ASTNode *getLhs() { return _lhs; } 1651 | ASTNode *getRhs() { return _rhs; } 1652 | 1653 | //STType *checkType(AbstractSyntaxTree *ast); 1654 | void accept(TreeVisitor *v); 1655 | }; 1656 | 1657 | class NeExprASTNode : public ASTNode 1658 | { 1659 | ASTNode *_type; 1660 | ASTNode *_lhs; 1661 | ASTNode *_rhs; 1662 | 1663 | public: 1664 | NeExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1665 | { 1666 | kind = NK_NE_EXPR; 1667 | ASSIGN_AST_NODE_REF(_type, Type); 1668 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1669 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1670 | } 1671 | 1672 | ~NeExprASTNode() 1673 | { 1674 | DELETE_AST_NODE_REF(_type); 1675 | DELETE_AST_NODE_REF(_lhs); 1676 | DELETE_AST_NODE_REF(_rhs); 1677 | } 1678 | 1679 | ASTNode *getLhs() { return _lhs; } 1680 | ASTNode *getRhs() { return _rhs; } 1681 | 1682 | //STType *checkType(AbstractSyntaxTree *ast); 1683 | void accept(TreeVisitor *v); 1684 | }; 1685 | 1686 | class AssignExprASTNode : public ASTNode 1687 | { 1688 | ASTNode *_type; 1689 | ASTNode *_lhs; 1690 | ASTNode *_rhs; 1691 | 1692 | public: 1693 | AssignExprASTNode(ASTNode *Type, ASTNode *Lhs, ASTNode *Rhs) 1694 | { 1695 | kind = NK_ASSIGN_EXPR; 1696 | ASSIGN_AST_NODE_REF(_type, Type); 1697 | ASSIGN_AST_NODE_REF(_lhs, Lhs); 1698 | ASSIGN_AST_NODE_REF(_rhs, Rhs); 1699 | } 1700 | 1701 | ~AssignExprASTNode() 1702 | { 1703 | DELETE_AST_NODE_REF(_type); 1704 | DELETE_AST_NODE_REF(_lhs); 1705 | DELETE_AST_NODE_REF(_rhs); 1706 | } 1707 | 1708 | ASTNode *getLhs() { return _lhs; } 1709 | ASTNode *getRhs() { return _rhs; } 1710 | 1711 | //STType *checkType(AbstractSyntaxTree *ast); 1712 | void accept(TreeVisitor *v); 1713 | }; 1714 | 1715 | class CondExprASTNode : public ASTNode 1716 | { 1717 | ASTNode *_condition; 1718 | ASTNode *_thenClause; 1719 | ASTNode *_elseClause; 1720 | 1721 | public: 1722 | CondExprASTNode(ASTNode *Condition, ASTNode *thenClause, ASTNode *elseClause) 1723 | { 1724 | kind = NK_COND_EXPR; 1725 | ASSIGN_AST_NODE_REF(_condition, Condition); 1726 | ASSIGN_AST_NODE_REF(_thenClause, thenClause); 1727 | ASSIGN_AST_NODE_REF(_elseClause, elseClause); 1728 | } 1729 | 1730 | ~CondExprASTNode() 1731 | { 1732 | DELETE_AST_NODE_REF(_condition); 1733 | DELETE_AST_NODE_REF(_thenClause); 1734 | DELETE_AST_NODE_REF(_elseClause); 1735 | } 1736 | 1737 | ASTNode *getCondition() { return _condition; } 1738 | ASTNode *getThenClause() { return _thenClause; } 1739 | ASTNode *getElseClause() { return _elseClause; } 1740 | 1741 | void accept(TreeVisitor *v); 1742 | }; 1743 | 1744 | class CallExprASTNode : public ASTNode 1745 | { 1746 | ASTNode *_expr; 1747 | ASTNode *_args; 1748 | 1749 | public: 1750 | CallExprASTNode(ASTNode *Expr, ASTNode *Args) 1751 | { 1752 | kind = NK_CALL_EXPR; 1753 | ASSIGN_AST_NODE_REF(_expr, Expr); 1754 | ASSIGN_AST_NODE_REF(_args, Args); 1755 | } 1756 | 1757 | ~CallExprASTNode() 1758 | { 1759 | DELETE_AST_NODE_REF(_expr); 1760 | DELETE_AST_NODE_REF(_args); 1761 | } 1762 | 1763 | ASTNode *getExpr() { return _expr; } 1764 | ASTNode *getArgs() { return _args; } 1765 | 1766 | //STType *checkType(AbstractSyntaxTree *ast); 1767 | void accept(TreeVisitor *v); 1768 | }; 1769 | 1770 | class VoidTypeASTNode : public ASTNode 1771 | { 1772 | public: 1773 | VoidTypeASTNode() { kind = NK_VOID_TYPE; } 1774 | 1775 | ~VoidTypeASTNode() {} 1776 | 1777 | void accept(TreeVisitor *v); 1778 | }; 1779 | 1780 | class IntegralTypeASTNode : public ASTNode 1781 | { 1782 | unsigned _alignment; 1783 | bool _isSigned; 1784 | 1785 | public: 1786 | IntegralTypeASTNode(unsigned Alignment, bool IsSigned) 1787 | : _alignment(Alignment), _isSigned(IsSigned) 1788 | { 1789 | kind = NK_INTEGRAL_TYPE; 1790 | } 1791 | 1792 | ~IntegralTypeASTNode() {} 1793 | 1794 | unsigned getAlignment() { return _alignment; } 1795 | bool getIsSigned() { return _isSigned; } 1796 | 1797 | void accept(TreeVisitor *v); 1798 | }; 1799 | 1800 | class RealTypeASTNode : public ASTNode 1801 | { 1802 | unsigned _alignment; 1803 | bool _isDouble; 1804 | 1805 | public: 1806 | RealTypeASTNode(unsigned Alignment, bool IsDouble) 1807 | : _alignment(Alignment), _isDouble(IsDouble) 1808 | { 1809 | kind = NK_REAL_TYPE; 1810 | } 1811 | 1812 | ~RealTypeASTNode() {} 1813 | 1814 | unsigned getAlignment() { return _alignment; } 1815 | bool getIsDouble() { return _isDouble; } 1816 | 1817 | void accept(TreeVisitor *v); 1818 | }; 1819 | 1820 | class EnumeralTypeASTNode : public ASTNode 1821 | { 1822 | ASTNode *_name; 1823 | ASTNode *_body; 1824 | 1825 | public: 1826 | EnumeralTypeASTNode(ASTNode *Name, ASTNode *Body) 1827 | { 1828 | kind = NK_ENUMERAL_TYPE; 1829 | ASSIGN_AST_NODE_REF(_name, Name); 1830 | ASSIGN_AST_NODE_REF(_body, Body); 1831 | } 1832 | 1833 | ~EnumeralTypeASTNode() 1834 | { 1835 | DELETE_AST_NODE_REF(_name); 1836 | DELETE_AST_NODE_REF(_body); 1837 | } 1838 | 1839 | ASTNode *getName() { return _name; } 1840 | ASTNode *getBody() { return _body; } 1841 | 1842 | void accept(TreeVisitor *v); 1843 | }; 1844 | 1845 | class PointerTypeASTNode : public ASTNode 1846 | { 1847 | ASTNode *_baseType; 1848 | 1849 | public: 1850 | PointerTypeASTNode(ASTNode *BaseType) 1851 | { 1852 | kind = NK_POINTER_TYPE; 1853 | ASSIGN_AST_NODE_REF(_baseType, BaseType); 1854 | } 1855 | 1856 | ~PointerTypeASTNode() { DELETE_AST_NODE_REF(_baseType); } 1857 | 1858 | ASTNode *getBaseType() { return _baseType; } 1859 | void setBaseType(ASTNode *BaseType) { _baseType = BaseType; } 1860 | 1861 | void accept(TreeVisitor *v); 1862 | }; 1863 | 1864 | class FunctionTypeASTNode : public ASTNode 1865 | { 1866 | ASTNode *_type; 1867 | ASTNode *_prms; 1868 | 1869 | public: 1870 | FunctionTypeASTNode(ASTNode *tp, ASTNode *p) 1871 | { 1872 | kind = NK_FUNCTION_TYPE; 1873 | ASSIGN_AST_NODE_REF(_type, tp); 1874 | ASSIGN_AST_NODE_REF(_prms, p); 1875 | } 1876 | 1877 | ~FunctionTypeASTNode() 1878 | { 1879 | DELETE_AST_NODE_REF(_type); 1880 | DELETE_AST_NODE_REF(_prms); 1881 | } 1882 | 1883 | ASTNode *getType() { return _type; } 1884 | ASTNode *getPrms() { return _prms; } 1885 | 1886 | void setType(ASTNode *Type) { ASSIGN_AST_NODE_REF(_type, Type); } 1887 | void setPrms(ASTNode *Prms) { ASSIGN_AST_NODE_REF(_prms, Prms); } 1888 | 1889 | void accept(TreeVisitor *v); 1890 | }; 1891 | 1892 | class ArrayTypeASTNode : public ASTNode 1893 | { 1894 | ASTNode *_type; 1895 | ASTNode *_expr; 1896 | 1897 | public: 1898 | ArrayTypeASTNode(ASTNode *Type, ASTNode *Expr) 1899 | { 1900 | kind = NK_ARRAY_TYPE; 1901 | ASSIGN_AST_NODE_REF(_type, Type); 1902 | ASSIGN_AST_NODE_REF(_expr, Expr); 1903 | } 1904 | 1905 | ~ArrayTypeASTNode() 1906 | { 1907 | DELETE_AST_NODE_REF(_type); 1908 | DELETE_AST_NODE_REF(_expr); 1909 | } 1910 | 1911 | void setType(ASTNode *Type) { _type = Type; } 1912 | ASTNode *getExpr() { return _expr; } 1913 | ASTNode *getElementType() { return _type; } 1914 | 1915 | void accept(TreeVisitor *v); 1916 | }; 1917 | 1918 | class StructTypeASTNode : public ASTNode 1919 | { 1920 | ASTNode *_name; 1921 | ASTNode *_body; 1922 | 1923 | public: 1924 | StructTypeASTNode(ASTNode *Name, ASTNode *Body) 1925 | { 1926 | kind = NK_STRUCT_TYPE; 1927 | ASSIGN_AST_NODE_REF(_name, Name); 1928 | ASSIGN_AST_NODE_REF(_body, Body); 1929 | } 1930 | 1931 | ~StructTypeASTNode() 1932 | { 1933 | DELETE_AST_NODE_REF(_name); 1934 | DELETE_AST_NODE_REF(_body); 1935 | } 1936 | 1937 | ASTNode *getName() { return _name; } 1938 | ASTNode *getBody() { return _body; } 1939 | 1940 | void accept(TreeVisitor *v); 1941 | }; 1942 | 1943 | class UnionTypeASTNode : public ASTNode 1944 | { 1945 | ASTNode *_name; 1946 | ASTNode *_body; 1947 | 1948 | public: 1949 | UnionTypeASTNode(ASTNode *Name, ASTNode *Body) 1950 | { 1951 | kind = NK_UNION_TYPE; 1952 | ASSIGN_AST_NODE_REF(_name, Name); 1953 | ASSIGN_AST_NODE_REF(_body, Body); 1954 | } 1955 | 1956 | ~UnionTypeASTNode() 1957 | { 1958 | DELETE_AST_NODE_REF(_name); 1959 | DELETE_AST_NODE_REF(_body); 1960 | } 1961 | 1962 | ASTNode *getName() { return _name; } 1963 | ASTNode *getBody() { return _body; } 1964 | 1965 | void accept(TreeVisitor *v); 1966 | }; 1967 | 1968 | // List of trees 1969 | class SequenceASTNode : public ASTNode 1970 | { 1971 | STScope *_scope; 1972 | std::vector _elements; 1973 | 1974 | public: 1975 | SequenceASTNode() 1976 | { 1977 | kind = NK_LIST; 1978 | _scope = nullptr; 1979 | } 1980 | 1981 | SequenceASTNode(ASTNode *n) 1982 | { 1983 | kind = NK_LIST; 1984 | add(n); 1985 | } 1986 | 1987 | ~SequenceASTNode() 1988 | { 1989 | for (unsigned i = 0; i < _elements.size(); i++) 1990 | DELETE_AST_NODE_REF(_elements[i]); 1991 | } 1992 | 1993 | // void setElements(ASTNode *Elements) { elements = Elements; } 1994 | std::vector &getElements() { return _elements; } 1995 | void setElements(std::vector e) { _elements = e; } 1996 | 1997 | void add(ASTNode *n) 1998 | { 1999 | // If n is a tree list, append its elements to these elements 2000 | if (n->getKind() == NK_LIST) 2001 | { 2002 | std::vector &tmpVec = 2003 | static_cast(n)->getElements(); 2004 | 2005 | for (unsigned i = 0; i < tmpVec.size(); i++) 2006 | PUSH_BACK_AST_NODE_REF(_elements, tmpVec[i]); 2007 | 2008 | // We don't need n anymore. 2009 | delete n; 2010 | } 2011 | else 2012 | { 2013 | PUSH_BACK_AST_NODE_REF(_elements, n); 2014 | } 2015 | } 2016 | 2017 | void addElement(ASTNode *e) { PUSH_BACK_AST_NODE_REF(_elements, e); } 2018 | 2019 | unsigned size() { return _elements.size(); } 2020 | void setScope(STScope *s) { _scope = s; } 2021 | STScope *getScope() { return _scope; } 2022 | 2023 | void declare(AbstractSyntaxTree *ast); 2024 | 2025 | void accept(TreeVisitor *v); 2026 | }; 2027 | 2028 | } // namespace cparser 2029 | 2030 | #endif 2031 | -------------------------------------------------------------------------------- /include/AbstractSyntaxTree.h: -------------------------------------------------------------------------------- 1 | // Abstract syntax tree - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef ABSTRACT_SYNTAX_TREE_H 9 | #define ABSTRACT_SYNTAX_TREE_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "ASTNode.h" 16 | 17 | // Declaration flags 18 | #define SCS_TYPEDEF 0x1 19 | #define SCS_EXTERN 0x2 20 | #define SCS_STATIC 0x4 21 | #define SCS_AUTO 0x8 22 | #define SCS_REGISTER 0x10 23 | 24 | #define TQ_CONST 0x20 25 | #define TQ_VOLATILE 0x40 26 | 27 | #define UNLESS(x) if (!(x)) 28 | #define TYPE(x) x->type 29 | 30 | // Match macros 31 | 32 | #define AST_MATCH_NULL(n) (n == NULL_AST_NODE) 33 | 34 | #define AST_MATCH_IDENT(n) (n->getKind() == NK_IDENT_NODE) 35 | 36 | #define AST_MATCH_LIST(n) (n->getKind() == NK_LIST) 37 | 38 | #define AST_MATCH_INTEGER_CONST(n) (n->getKind() == NK_INTEGER_CONST) 39 | 40 | #define AST_MATCH_REAL_CONST(n) (n->getKind() == NK_REAL_CONST) 41 | 42 | #define AST_MATCH_COMPLEX_CONST(n) (n->getKind() == NK_COMPLEX_CONST) 43 | 44 | #define AST_MATCH_STRING_CONST(n) (n->getKind() == NK_STRING_CONST) 45 | 46 | #define AST_MATCH_CHAR_CONST(n) (n->getKind() == NK_CHAR_CONST) 47 | 48 | #define AST_MATCH_STRUCT_REF(n) (n->getKind() == NK_STRUCT_REF) 49 | 50 | #define AST_MATCH_INDIRECT_REF(n) (n->getKind() == NK_INDIRECT_REF) 51 | 52 | #define AST_MATCH_ARRAY_REF(n) (n->getKind() == NK_ARRAY_REF) 53 | 54 | #define AST_MATCH_STRUCT_TYPE(n) (n->getKind() == NK_STRUCT_TYPE) 55 | 56 | #define AST_MATCH_VAR_DECL(n) (n->getKind() == NK_VAR_DECL) 57 | 58 | #define AST_MATCH_NOP_EXPR(n) (n->getKind() == NK_NOP_EXPR) 59 | 60 | #define AST_COMPOUND_STMT_STMTS(n) \ 61 | static_cast(n)->getStmts() 62 | #define AST_COMPOUND_STMT_DECLS(n) \ 63 | static_cast(n)->getDecls() 64 | #define AST_IDENT_VALUE(n) static_cast(n)->getValue() 65 | #define AST_IDENT_LINE_NUM(n) static_cast(n)->getLineNum() 66 | #define AST_LIST(n) static_cast(n) 67 | #define AST_LIST_ELEMENTS(n) static_cast(n)->getElements() 68 | #define AST_INTEGER_CONST_VALUE(n) \ 69 | static_cast(n)->getValue() 70 | #define AST_INTEGER_CONST_LINE_NUM(n) \ 71 | static_cast(n)->getLineNum() 72 | #define AST_ARRAY_REF_EXPR(n) static_cast(n)->getExpr() 73 | 74 | namespace cparser 75 | { 76 | 77 | class ASTNode; 78 | 79 | class AbstractSyntaxTree 80 | { 81 | ASTNode *_root; 82 | 83 | SymbolTable *_stb; 84 | 85 | STObject *_currentFuncDecl; 86 | 87 | int _errors; 88 | int _warnings; 89 | 90 | public: 91 | STObject *currentRecordObj; 92 | 93 | ASTNode *voidTypeASTNode; 94 | ASTNode *integerTypeASTNode; 95 | ASTNode *longTypeASTNode; 96 | ASTNode *unsignedTypeASTNode; 97 | ASTNode *shortTypeASTNode; 98 | ASTNode *charTypeASTNode; 99 | ASTNode *floatTypeASTNode; 100 | 101 | std::vector structTypes; 102 | std::vector unionTypes; 103 | 104 | STObject *getCurrentFuncDecl() { return _currentFuncDecl; } 105 | 106 | void setCurrentFuncDecl(STObject *currentFuncDecl) 107 | { 108 | _currentFuncDecl = currentFuncDecl; 109 | } 110 | 111 | void error(int lineNum, const char *format, ...); 112 | void warning(int lineNum, const char *format, ...); 113 | 114 | void setRoot(ASTNode *Root) { _root = Root; } 115 | ASTNode *getRoot() { return _root; } 116 | 117 | void declare(); 118 | 119 | int getErrors() { return _errors; } 120 | int getWarnings() { return _warnings; } 121 | 122 | STType *getStbType(ASTNode *typeASTNode); 123 | 124 | void visit(TreeVisitor *visitor); 125 | 126 | SymbolTable *getSymbolTable() { return _stb; } 127 | 128 | StructTypeASTNode *createStructTypeASTNode(ASTNode *typeName, 129 | ASTNode *typeBody) 130 | { 131 | StructTypeASTNode *tmp = new StructTypeASTNode(typeName, typeBody); 132 | structTypes.push_back(tmp); 133 | return tmp; 134 | } 135 | 136 | AbstractSyntaxTree(SymbolTable *STB) : _stb(STB) 137 | { 138 | ASSIGN_AST_NODE_REF(voidTypeASTNode, new VoidTypeASTNode()); 139 | ASSIGN_AST_NODE_REF(charTypeASTNode, new IntegralTypeASTNode(1, true)); 140 | ASSIGN_AST_NODE_REF(shortTypeASTNode, new IntegralTypeASTNode(2, true)); 141 | ASSIGN_AST_NODE_REF(integerTypeASTNode, 142 | new IntegralTypeASTNode(4, true)); 143 | ASSIGN_AST_NODE_REF(longTypeASTNode, 144 | new IntegralTypeASTNode(8, true)); 145 | ASSIGN_AST_NODE_REF(unsignedTypeASTNode, 146 | new IntegralTypeASTNode(4, false)); 147 | ASSIGN_AST_NODE_REF(floatTypeASTNode, new RealTypeASTNode(4, false)); 148 | 149 | _currentFuncDecl = nullptr; 150 | currentRecordObj = nullptr; 151 | _errors = 0; 152 | _warnings = 0; 153 | 154 | _root = nullptr; 155 | } 156 | 157 | ~AbstractSyntaxTree() 158 | { 159 | if (_root) 160 | delete _root; 161 | 162 | DELETE_AST_NODE_REF(voidTypeASTNode); 163 | DELETE_AST_NODE_REF(charTypeASTNode); 164 | DELETE_AST_NODE_REF(shortTypeASTNode); 165 | DELETE_AST_NODE_REF(integerTypeASTNode); 166 | DELETE_AST_NODE_REF(longTypeASTNode); 167 | DELETE_AST_NODE_REF(unsignedTypeASTNode); 168 | DELETE_AST_NODE_REF(floatTypeASTNode); 169 | 170 | for (unsigned n = 0; n < structTypes.size(); n++) 171 | delete structTypes[n]; 172 | } 173 | }; 174 | 175 | } // namespace cparser 176 | 177 | #endif 178 | -------------------------------------------------------------------------------- /include/CLexer.h: -------------------------------------------------------------------------------- 1 | // C Lexer - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef CLEXER_H 9 | #define CLEXER_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "common.h" 16 | #include "Lexer.h" 17 | #include 18 | 19 | namespace cparser 20 | { 21 | 22 | // Token Kinds 23 | 24 | enum TokenKind 25 | { 26 | TK_UNKNOWN, 27 | TK_IDENT, 28 | TK_INT_LIT, 29 | TK_CHAR_LIT, 30 | TK_FLOAT_LIT, 31 | TK_STRING_LIT, 32 | 33 | TK_SIZEOF, 34 | 35 | TK_PLUS, 36 | TK_MINUS, 37 | TK_TIMES, 38 | TK_DIV, 39 | TK_MOD, 40 | 41 | TK_PERIODS, 42 | TK_SEMICOLON, 43 | TK_COLON, 44 | TK_COMMA, 45 | TK_PERIOD, 46 | TK_LPAR, 47 | TK_RPAR, 48 | TK_LBRACK, 49 | TK_RBRACK, 50 | TK_LBRACE, 51 | TK_RBRACE, 52 | 53 | TK_TILDA, // ~ 54 | TK_COND_OP, // ? 55 | 56 | TK_AND, // & 57 | TK_LOGICAL_AND, // && 58 | TK_OR, // | 59 | TK_LOGICAL_OR, // || 60 | TK_EXCLUSIVE_OR, // ^ 61 | 62 | TK_PTR_OP, 63 | TK_INC_OP, 64 | TK_DEC_OP, 65 | TK_LSHIFT_OP, 66 | TK_RSHIFT_OP, 67 | 68 | TK_LSS, 69 | TK_GTR, 70 | TK_LEQ, 71 | TK_GEQ, 72 | TK_EQL, 73 | TK_NEQ, 74 | TK_NOT, 75 | 76 | TK_ASSIGN, 77 | TK_MUL_ASSIGN, // *= 78 | TK_DIV_ASSIGN, 79 | TK_MOD_ASSIGN, 80 | TK_ADD_ASSIGN, 81 | TK_SUB_ASSIGN, 82 | TK_LSHIFT_ASSIGN, 83 | TK_RSHIFT_ASSIGN, 84 | TK_AND_ASSIGN, 85 | TK_XOR_ASSIGN, 86 | TK_OR_ASSIGN, 87 | 88 | TK_TYPE_NAME, 89 | TK_ELLIPSIS, // ... 90 | 91 | // FirstOf Declaration 92 | TK_AUTO, 93 | TK_CHAR, 94 | TK_CONST, 95 | TK_DOUBLE, 96 | TK_ELSE, 97 | TK_ENUM, 98 | TK_EXTERN, 99 | TK_FLOAT, 100 | TK_INLINE, // C11 101 | TK_INT, 102 | TK_LONG, 103 | TK_REGISTER, 104 | TK_RESTRICT, // C11 105 | TK_SHORT, 106 | TK_SIGNED, 107 | TK_STATIC, 108 | TK_STRUCT, 109 | TK_TYPEDEF, 110 | TK_UNION, 111 | TK_UNSIGNED, 112 | TK_VOID, 113 | TK_VOLATILE, 114 | 115 | // FirstOf Statement 116 | TK_ASM, 117 | TK_BREAK, 118 | TK_CASE, 119 | TK_CONTINUE, 120 | TK_DEFAULT, 121 | TK_DO, 122 | TK_FOR, 123 | TK_GOTO, 124 | TK_IF, 125 | TK_RETURN, 126 | TK_SWITCH, 127 | TK_WHILE, 128 | 129 | // C11 keywords 130 | TK__ALIGNAS, 131 | TK__ALIGNOF, 132 | TK__ATOMIC, 133 | TK__BOOL, 134 | TK__COMPLEX, 135 | TK__GENERIC, 136 | TK__IMAGINARY, 137 | TK__NORETURN, 138 | TK__STATIC_ASSERT, 139 | TK__THREAD_LOCAL, 140 | TK___FUNC__, 141 | 142 | // GCC extension 143 | TK___ATTRIBUTE__, 144 | TK___ASM, 145 | TK__NULLABLE, 146 | 147 | TK_EOF 148 | }; 149 | 150 | #define INSERT_KEYWORD(keyword, kind) \ 151 | _kwmap.insert(TokenMap::value_type(keyword, kind)) 152 | 153 | #define INSERT_FIRST_OF_STMT_KEYWORD(keyword, kind) \ 154 | _fstmtmap.insert(TokenMap::value_type(keyword, kind)) 155 | 156 | class CLexer : public Lexer 157 | { 158 | TokenMap _kwmap; 159 | TokenMap _fstmtmap; 160 | 161 | unsigned keyword(const char *s); 162 | void readName(Token *t); 163 | void readNumberLit(Token *t); 164 | void readStringLit(Token *t); 165 | void readCharLit(Token *t); 166 | void comment(); 167 | void initialize(); 168 | 169 | public: 170 | unsigned next(Token *t); 171 | 172 | CLexer(const char *filename) : Lexer(filename) 173 | { 174 | initialize(); 175 | } 176 | }; 177 | 178 | } // namespace cparser 179 | 180 | #endif 181 | -------------------------------------------------------------------------------- /include/CParser.h: -------------------------------------------------------------------------------- 1 | // C parser - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef CPARSER_H 9 | #define CPARSER_H 10 | 11 | #include 12 | 13 | #include "AbstractSyntaxTree.h" 14 | #include "Parser.h" 15 | #include "Lexer.h" 16 | #include "CLexer.h" 17 | 18 | namespace cparser 19 | { 20 | 21 | class CParser : public Parser 22 | { 23 | bool _inTypedef; 24 | 25 | void initNames(); 26 | 27 | bool isTypeSpecifier(unsigned _kind, int n); 28 | bool isTypeQualifier(unsigned kind); 29 | bool isStorageClassSpecifier(unsigned kind); 30 | 31 | // THE PARSER RULES 32 | 33 | // Expressions 34 | ASTNode *PrimaryExpression(); 35 | ASTNode *GenericSelection(); 36 | ASTNode *GenericAssocList(); 37 | ASTNode *GenericAssociation(); 38 | ASTNode *parsePostfixExpression(ASTNode *expr); 39 | ASTNode *PostfixExpression(ASTNode *typeName); 40 | ASTNode *ArgumentExpressionList(); 41 | ASTNode *UnaryExpression(ASTNode *typeName); 42 | ASTNodeKind UnaryOperator(); 43 | ASTNode *CastExpression(); 44 | ASTNode *MultiplicativeExpression(); 45 | ASTNode *AdditiveExpression(); 46 | ASTNode *ShiftExpression(); 47 | ASTNode *RelationalExpression(); 48 | ASTNode *EqualityExpression(); 49 | ASTNode *AndExpression(); 50 | ASTNode *ExclusiveOrExpression(); 51 | ASTNode *InclusiveOrExpression(); 52 | ASTNode *LogicalAndExpression(); 53 | ASTNode *LogicalOrExpression(); 54 | ASTNode *ConditionalExpression(); 55 | ASTNode *AssignmentExpression(); 56 | ASTNode *Expression(); 57 | ASTNode *ConstantExpression(); 58 | 59 | // Declarations 60 | ASTNode *Declaration(ASTNode *declSpec); 61 | ASTNode *DeclarationSpecifiers(); 62 | SequenceASTNode *InitDeclaratorList(ASTNode *typeSpec); 63 | ASTNode *InitDeclarator(ASTNode *typeSpec); 64 | void StorageClassSpecifier(unsigned &flags); 65 | ASTNode *TypeSpecifier(); 66 | ASTNode *StructOrUnionSpecifier(); 67 | SequenceASTNode *StructDeclarationList(); 68 | ASTNode *StructDeclaration(); 69 | ASTNode *SpecifierQualifierList(); 70 | SequenceASTNode *StructDeclaratorList(ASTNode *typeSpec); 71 | ASTNode *StructDeclarator(ASTNode *typeSpec); 72 | ASTNode *EnumSpecifier(); 73 | SequenceASTNode *EnumeratorList(); 74 | void TypeQualifier(unsigned &flags); 75 | void FunctionSpecifier(); 76 | ASTNode *AlignmentSpecifier(); 77 | ASTNode *Declarator(ASTNode * &typeSpec); 78 | ASTNode *DirectDeclarator(ASTNode * &typeSpec); 79 | ASTNode *GccDeclaratorExtension(); 80 | ASTNode *GccAttributeSpecifier(); 81 | ASTNode *GccAttributeList(); 82 | ASTNode *GccAttribute(); 83 | ASTNode *ParameterTypeList(); 84 | ASTNode *ParameterList(); 85 | ASTNode *ParameterDeclaration(); 86 | ASTNode *IdentifierList(); 87 | ASTNode *TypeName(); 88 | ASTNode *AbstractDeclarator(); 89 | ASTNode *DirectAbstractDeclarator(); 90 | ASTNode *Initializer(); 91 | ASTNode *InitializerList(); 92 | 93 | // Statements 94 | ASTNode *Statement(); 95 | ASTNode *LabeledStatement(); 96 | ASTNode *CompoundStatement(); 97 | ASTNode *FunctionBody(); 98 | ASTNode *DeclarationList(); 99 | ASTNode *StmtOrDeclList(); 100 | ASTNode *SelectionStatement(); 101 | ASTNode *IterationStatement(); 102 | ASTNode *JumpStatement(); 103 | ASTNode *ExpressionStatement(); 104 | ASTNode *TranslationUnit(); 105 | ASTNode *ExternalDeclaration(); 106 | ASTNode *FunctionDefinition(ASTNode *funcType); 107 | public: 108 | void parse(const char *output); 109 | 110 | CParser(CLexer *LEX) : Parser(LEX) 111 | { 112 | _inTypedef = false; 113 | initNames(); 114 | } 115 | }; 116 | 117 | } // namespace cparser 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /include/GenCVisitor.h: -------------------------------------------------------------------------------- 1 | // Generate C visitor - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef GEN_C_VISITOR 9 | #define GEN_C_VISITOR 10 | 11 | #include "ASTNode.h" 12 | #include "TreeVisitor.h" 13 | 14 | namespace cparser 15 | { 16 | 17 | class GenCVisitor : public TreeVisitor 18 | { 19 | int _level; // Indentation level 20 | int _inList; 21 | bool _inEnum; 22 | 23 | public: 24 | GenCVisitor() { _level = 0; _inList = 0; _inEnum = false; } 25 | 26 | GenCVisitor(int L) : _level(L) { _inList = 0; _inEnum = false; } 27 | 28 | void visit(IdentASTNode *n); 29 | void visit(IntegerConstASTNode *n); 30 | void visit(StringConstASTNode *n); 31 | void visit(CharConstASTNode *n); 32 | void visit(SizeOfExprASTNode *n); 33 | void visit(AlignOfExprASTNode *n); 34 | void visit(TypeDeclASTNode *n); 35 | void visit(FunctionDeclASTNode *n); 36 | void visit(VarDeclASTNode *n); 37 | void visit(ParmDeclASTNode *n); 38 | void visit(FieldDeclASTNode *n); 39 | void visit(AsmStmtASTNode *n); 40 | void visit(BreakStmtASTNode *n); 41 | void visit(CaseLabelASTNode *n); 42 | void visit(CompoundStmtASTNode *n); 43 | void visit(ContinueStmtASTNode *n); 44 | void visit(DoStmtASTNode *n); 45 | void visit(ForStmtASTNode *n); 46 | void visit(GotoStmtASTNode *n); 47 | void visit(IfStmtASTNode *n); 48 | void visit(LabelStmtASTNode *n); 49 | void visit(ReturnStmtASTNode *n); 50 | void visit(SwitchStmtASTNode *n); 51 | void visit(WhileStmtASTNode *n); 52 | void visit(CastExprASTNode *n); 53 | void visit(BitNotExprASTNode *n); 54 | void visit(LogNotExprASTNode *n); 55 | void visit(PredecrementExprASTNode *n); 56 | void visit(PreincrementExprASTNode *n); 57 | void visit(PostdecrementExprASTNode *n); 58 | void visit(PostincrementExprASTNode *n); 59 | void visit(AddrExprASTNode *n); 60 | void visit(IndirectRefASTNode *n); 61 | void visit(NopExprASTNode *n); 62 | void visit(LShiftExprASTNode *n); 63 | void visit(RShiftExprASTNode *n); 64 | void visit(BitIorExprASTNode *n); 65 | void visit(BitXorExprASTNode *n); 66 | void visit(BitAndExprASTNode *n); 67 | void visit(LogAndExprASTNode *n); 68 | void visit(LogOrExprASTNode *n); 69 | void visit(PlusExprASTNode *n); 70 | void visit(MinusExprASTNode *n); 71 | void visit(MultExprASTNode *n); 72 | void visit(TruncDivExprASTNode *n); 73 | void visit(TruncModExprASTNode *n); 74 | void visit(ArrayRefASTNode *n); 75 | void visit(StructRefASTNode *n); 76 | void visit(LtExprASTNode *n); 77 | void visit(LeExprASTNode *n); 78 | void visit(GtExprASTNode *n); 79 | void visit(GeExprASTNode *n); 80 | void visit(EqExprASTNode *n); 81 | void visit(NeExprASTNode *n); 82 | void visit(AssignExprASTNode *n); 83 | void visit(CondExprASTNode *n); 84 | void visit(CallExprASTNode *n); 85 | void visit(VoidTypeASTNode *n); 86 | void visit(IntegralTypeASTNode *n); 87 | void visit(RealTypeASTNode *n); 88 | void visit(EnumeralTypeASTNode *n); 89 | void visit(PointerTypeASTNode *n); 90 | void visit(FunctionTypeASTNode *n); 91 | void visit(ArrayTypeASTNode *n); 92 | void visit(StructTypeASTNode *n); 93 | void visit(UnionTypeASTNode *n); 94 | void visit(NullASTNode *n); 95 | void visit(SequenceASTNode *n); 96 | }; 97 | 98 | } // namespace cparser 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /include/Lexer.h: -------------------------------------------------------------------------------- 1 | // Lexer - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef LEXER_H 9 | #define LEXER_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "common.h" 17 | #include 18 | 19 | namespace cparser 20 | { 21 | 22 | // Token type 23 | struct Token 24 | { 25 | unsigned kind; 26 | union 27 | { 28 | int ival; 29 | float fval; 30 | } info; 31 | std::string sval; 32 | int line, col; 33 | }; 34 | 35 | typedef std::map TokenMap; 36 | 37 | class Lexer 38 | { 39 | protected: 40 | FILE *_fp; 41 | int _ch; // Current character 42 | int _line; // Current line 43 | int _col; // Current column 44 | 45 | void error(int lineNum, const char *format, ...); 46 | bool isHexDigit(char c); 47 | int powr(int x, int n); 48 | 49 | virtual void readName(Token *t) {} 50 | virtual void readNumberLit(Token *t) {} 51 | virtual void readStringLit(Token *t) {} 52 | virtual void readCharLit(Token *t) {} 53 | virtual void comment() {} 54 | 55 | public: 56 | void nextCh(); 57 | virtual unsigned next(Token *t) { return 0; } 58 | 59 | Lexer(const char *filename); 60 | 61 | ~Lexer() {} 62 | }; 63 | 64 | } // namespace cparser 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /include/Parser.h: -------------------------------------------------------------------------------- 1 | // Parser - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef PARSER_H 9 | #define PARSER_H 10 | 11 | #include 12 | 13 | #include "AbstractSyntaxTree.h" 14 | #include "Lexer.h" 15 | 16 | #define TOK_BUF_LEN 4 17 | 18 | namespace cparser 19 | { 20 | 21 | enum DeclaratorKind 22 | { 23 | DK_VARIABLE, 24 | DK_PARAMETER, 25 | DK_FIELD, 26 | DK_TYPE_DECL, 27 | DK_IDENT 28 | }; 29 | 30 | class Parser 31 | { 32 | protected: 33 | Lexer *_lex; 34 | SymbolTable _stb; 35 | AbstractSyntaxTree *_ast; 36 | 37 | unsigned _sym; 38 | int _parsingErrors; 39 | 40 | std::map _name; 41 | 42 | Token *_tok, *_la; 43 | Token _tokbuf[TOK_BUF_LEN]; 44 | unsigned _tokIdx; 45 | unsigned _laIdx; 46 | unsigned _newLaIdx; 47 | 48 | void getTok(); 49 | unsigned getLATok(unsigned k); 50 | const char *getLATokInfoSval(unsigned k); 51 | void parsingError(const char *msg); 52 | void check(unsigned expected); 53 | 54 | void initTokenBuffer(); 55 | virtual void initNames() {} 56 | 57 | public: 58 | virtual void parse(const char *output) {} 59 | 60 | SymbolTable *getSymbolTable() 61 | { 62 | return &_stb; 63 | } 64 | 65 | AbstractSyntaxTree *getAST() 66 | { 67 | return _ast; 68 | } 69 | 70 | unsigned getCurrentLine() const 71 | { 72 | return _tok->line; 73 | } 74 | 75 | Parser(Lexer *lex) : _lex(lex) 76 | { 77 | _parsingErrors = 0; 78 | _ast = new AbstractSyntaxTree(&_stb); 79 | } 80 | 81 | virtual ~Parser() 82 | { 83 | delete _ast; 84 | } 85 | }; 86 | 87 | } // namespace cparser 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /include/PrintTreeVisitor.h: -------------------------------------------------------------------------------- 1 | // Print tree visitor - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef PRINT_TREE_VISITOR 9 | #define PRINT_TREE_VISITOR 10 | 11 | #include "ASTNode.h" 12 | #include "TreeVisitor.h" 13 | 14 | namespace cparser 15 | { 16 | 17 | class PrintTreeVisitor : public TreeVisitor 18 | { 19 | int _level; // Indentation level 20 | 21 | public: 22 | PrintTreeVisitor() { _level = 0; } 23 | 24 | PrintTreeVisitor(int L) : _level(L) {} 25 | 26 | void visit(IdentASTNode *n); 27 | void visit(IntegerConstASTNode *n); 28 | void visit(StringConstASTNode *n); 29 | void visit(CharConstASTNode *n); 30 | void visit(SizeOfExprASTNode *n); 31 | void visit(TypeDeclASTNode *n); 32 | void visit(FunctionDeclASTNode *n); 33 | void visit(VarDeclASTNode *n); 34 | void visit(ParmDeclASTNode *n); 35 | void visit(FieldDeclASTNode *n); 36 | void visit(AsmStmtASTNode *n); 37 | void visit(BreakStmtASTNode *n); 38 | void visit(CaseLabelASTNode *n); 39 | void visit(CompoundStmtASTNode *n); 40 | void visit(ContinueStmtASTNode *n); 41 | void visit(DoStmtASTNode *n); 42 | void visit(ForStmtASTNode *n); 43 | void visit(GotoStmtASTNode *n); 44 | void visit(IfStmtASTNode *n); 45 | void visit(LabelStmtASTNode *n); 46 | void visit(ReturnStmtASTNode *n); 47 | void visit(SwitchStmtASTNode *n); 48 | void visit(WhileStmtASTNode *n); 49 | void visit(CastExprASTNode *n); 50 | void visit(BitNotExprASTNode *n); 51 | void visit(LogNotExprASTNode *n); 52 | void visit(PredecrementExprASTNode *n); 53 | void visit(PreincrementExprASTNode *n); 54 | void visit(PostdecrementExprASTNode *n); 55 | void visit(PostincrementExprASTNode *n); 56 | void visit(AddrExprASTNode *n); 57 | void visit(IndirectRefASTNode *n); 58 | void visit(NopExprASTNode *n); 59 | void visit(LShiftExprASTNode *n); 60 | void visit(RShiftExprASTNode *n); 61 | void visit(BitIorExprASTNode *n); 62 | void visit(BitXorExprASTNode *n); 63 | void visit(BitAndExprASTNode *n); 64 | void visit(LogAndExprASTNode *n); 65 | void visit(LogOrExprASTNode *n); 66 | void visit(PlusExprASTNode *n); 67 | void visit(MinusExprASTNode *n); 68 | void visit(MultExprASTNode *n); 69 | void visit(TruncDivExprASTNode *n); 70 | void visit(TruncModExprASTNode *n); 71 | void visit(ArrayRefASTNode *n); 72 | void visit(StructRefASTNode *n); 73 | void visit(LtExprASTNode *n); 74 | void visit(LeExprASTNode *n); 75 | void visit(GtExprASTNode *n); 76 | void visit(GeExprASTNode *n); 77 | void visit(EqExprASTNode *n); 78 | void visit(NeExprASTNode *n); 79 | void visit(AssignExprASTNode *n); 80 | void visit(CondExprASTNode *n); 81 | void visit(CallExprASTNode *n); 82 | void visit(VoidTypeASTNode *n); 83 | void visit(IntegralTypeASTNode *n); 84 | void visit(RealTypeASTNode *n); 85 | void visit(EnumeralTypeASTNode *n); 86 | void visit(PointerTypeASTNode *n); 87 | void visit(FunctionTypeASTNode *n); 88 | void visit(ArrayTypeASTNode *n); 89 | void visit(StructTypeASTNode *n); 90 | void visit(UnionTypeASTNode *n); 91 | void visit(NullASTNode *n); 92 | void visit(SequenceASTNode *n); 93 | }; 94 | 95 | class CountCallExprVisitor : public TreeVisitor 96 | { 97 | int callExprCount; // Number of call expressions 98 | 99 | public: 100 | CountCallExprVisitor() { callExprCount = 0; } 101 | 102 | int getCallExprCount() { return callExprCount; } 103 | 104 | void visit(CallExprASTNode *n); 105 | }; 106 | 107 | } // namespace cparser 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /include/SymbolTable.h: -------------------------------------------------------------------------------- 1 | // Symbol table - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef SYMBOL_TABLE_H 9 | #define SYMBOL_TABLE_H 10 | 11 | #include "common.h" 12 | #include 13 | #include 14 | 15 | namespace cparser 16 | { 17 | 18 | // Object kinds 19 | enum STObjectKind 20 | { 21 | STOK_CON, 22 | STOK_VAR, 23 | STOK_VAR_STATIC, 24 | STOK_TYPE, 25 | STOK_FUNC, 26 | STOK_PAR, 27 | STOK_LAB, 28 | STOK_PTR 29 | }; 30 | 31 | // Type kinds 32 | enum STTypeKind 33 | { 34 | STTK_NONE, 35 | STTK_CHAR, 36 | STTK_SHORT, 37 | STTK_INT, 38 | STTK_UNSIGNED, 39 | STTK_LONG, 40 | STTK_FLOAT, 41 | STTK_DOUBLE, 42 | STTK_VOID, 43 | STTK_ARRAY, 44 | STTK_STRUCT, 45 | STTK_UNION, 46 | STTK_BOOL, 47 | STTK_REAL, 48 | STTK_POINTER, 49 | STTK_ENUM, 50 | STTK_FUNCTION 51 | }; 52 | 53 | struct STType; 54 | struct STObject; 55 | struct STScope; 56 | 57 | struct STType 58 | { 59 | STTypeKind kind; 60 | struct STType *elemType; // Array element type 61 | struct STType *baseType; // Base type of pointer type 62 | struct STType *funcType; // Function pointer type 63 | unsigned nFields; // Number of struct fields 64 | unsigned length; // Array length 65 | struct STObject *fields; // Struct fields 66 | unsigned size; 67 | bool isSigned; 68 | 69 | STType(STTypeKind Kind) 70 | : kind(Kind), elemType(nullptr), baseType(nullptr), 71 | funcType(nullptr), nFields(0), length(0), fields(nullptr), 72 | size(0), isSigned(false) 73 | { 74 | } 75 | }; 76 | 77 | struct STObject 78 | { 79 | STObjectKind kind; 80 | char name[IDLEN]; 81 | STType *type; 82 | 83 | int ival; // Integer constant value. 84 | int level; // Scope level 85 | 86 | // Function specific attributes 87 | unsigned prmc; // Function parameter count 88 | struct STObject *locals; // Function parameters and local variables 89 | 90 | bool isConstant; 91 | 92 | // Next object in a list 93 | struct STObject *next; 94 | 95 | STObject(const char *Name, STObjectKind Kind, STType *Type) 96 | : ival(0), level(0), prmc(0), locals(nullptr), 97 | isConstant(false), next(nullptr) 98 | { 99 | strcpy(name, Name); 100 | kind = Kind; 101 | type = Type; 102 | } 103 | }; 104 | 105 | struct STScope 106 | { 107 | struct STScope *outer; // Pointer to the next outer scope 108 | STObject *locals; // Pointer to the objects in this scope 109 | int nVars; // Number of variables in this scope 110 | int nPars; // Number of variables in this scope 111 | int size; // Size of scope in bytes 112 | 113 | STScope() : outer(nullptr), locals(nullptr), nVars(0), nPars(0), size(0) {} 114 | }; 115 | 116 | class SymbolTable 117 | { 118 | STScope *topScope; // Current scope 119 | STScope *globalScope; // Current scope 120 | int level; // (0 = global, 1 >= local) 121 | std::vector scopePool; 122 | std::vector objectPool; 123 | std::vector typePool; 124 | 125 | public: 126 | // Predefined types 127 | STType *charType; 128 | STType *shortType; 129 | STType *intType; 130 | STType *unsignedType; 131 | STType *longType; 132 | STType *floatType; 133 | STType *doubleType; 134 | STType *voidType; 135 | STType *nullType; 136 | STType *noType; 137 | 138 | STObject *noObj; 139 | 140 | // Allocators 141 | STType *allocType(STTypeKind kind); 142 | STObject *allocObject(const char *, STObjectKind, STType *); 143 | STScope *allocScope(); 144 | 145 | // Symbol table interface 146 | STObject *insert(const char *, STObjectKind, STType *); 147 | STObject *insertGlobalVariable(const char *, STType *, const char *); 148 | STObject *find(const char *); 149 | 150 | int getLevel() { return level; } 151 | 152 | void openScope(void); 153 | void closeScope(void); 154 | void setTopScope(STScope *s); 155 | STScope *getTopScope(); 156 | 157 | bool isIntegralType(STType *); 158 | bool isRealType(STType *); 159 | bool isArithmeticType(STType *); 160 | bool isPointerType(STType *); 161 | bool isScalarType(STType *); 162 | bool isFunctionPointerType(STType *); 163 | bool equalFunctionPointerTypes(STType *, STType *); 164 | bool equalBasePointerTypes(STType *, STType *); 165 | 166 | bool compatible(STType *, STType *); 167 | bool assignable(STType *, STType *); 168 | bool convertible(STType *, STType *); 169 | 170 | SymbolTable(); 171 | ~SymbolTable(); 172 | }; 173 | 174 | } // namespace cparser 175 | 176 | #endif 177 | -------------------------------------------------------------------------------- /include/TreeVisitor.h: -------------------------------------------------------------------------------- 1 | // Tree visitor - header file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef TREE_VISITOR_H 9 | #define TREE_VISITOR_H 10 | 11 | #include "ASTNode.h" 12 | 13 | namespace cparser 14 | { 15 | 16 | class TreeVisitor 17 | { 18 | public: 19 | // Virtual destructor 20 | virtual ~TreeVisitor() {} 21 | 22 | virtual void visit(IdentASTNode *n); 23 | virtual void visit(IntegerConstASTNode *n); 24 | virtual void visit(RealConstASTNode *n); 25 | virtual void visit(StringConstASTNode *n); 26 | virtual void visit(CharConstASTNode *n); 27 | virtual void visit(SizeOfExprASTNode *n); 28 | virtual void visit(AlignOfExprASTNode *n); 29 | virtual void visit(TypeDeclASTNode *n); 30 | virtual void visit(FunctionDeclASTNode *n); 31 | virtual void visit(VarDeclASTNode *n); 32 | virtual void visit(ParmDeclASTNode *n); 33 | virtual void visit(FieldDeclASTNode *n); 34 | virtual void visit(AsmStmtASTNode *n); 35 | virtual void visit(BreakStmtASTNode *n); 36 | virtual void visit(CaseLabelASTNode *n); 37 | virtual void visit(CompoundStmtASTNode *n); 38 | virtual void visit(ContinueStmtASTNode *n); 39 | virtual void visit(DoStmtASTNode *n); 40 | virtual void visit(ForStmtASTNode *n); 41 | virtual void visit(GotoStmtASTNode *n); 42 | virtual void visit(IfStmtASTNode *n); 43 | virtual void visit(LabelStmtASTNode *n); 44 | virtual void visit(ReturnStmtASTNode *n); 45 | virtual void visit(SwitchStmtASTNode *n); 46 | virtual void visit(WhileStmtASTNode *n); 47 | virtual void visit(CastExprASTNode *n); 48 | virtual void visit(BitNotExprASTNode *n); 49 | virtual void visit(LogNotExprASTNode *n); 50 | virtual void visit(PredecrementExprASTNode *n); 51 | virtual void visit(PreincrementExprASTNode *n); 52 | virtual void visit(PostdecrementExprASTNode *n); 53 | virtual void visit(PostincrementExprASTNode *n); 54 | virtual void visit(AddrExprASTNode *n); 55 | virtual void visit(IndirectRefASTNode *n); 56 | virtual void visit(NopExprASTNode *n); 57 | virtual void visit(LShiftExprASTNode *n); 58 | virtual void visit(RShiftExprASTNode *n); 59 | virtual void visit(BitIorExprASTNode *n); 60 | virtual void visit(BitXorExprASTNode *n); 61 | virtual void visit(BitAndExprASTNode *n); 62 | virtual void visit(LogAndExprASTNode *n); 63 | virtual void visit(LogOrExprASTNode *n); 64 | virtual void visit(PlusExprASTNode *n); 65 | virtual void visit(MinusExprASTNode *n); 66 | virtual void visit(MultExprASTNode *n); 67 | virtual void visit(TruncDivExprASTNode *n); 68 | virtual void visit(TruncModExprASTNode *n); 69 | virtual void visit(ArrayRefASTNode *n); 70 | virtual void visit(StructRefASTNode *n); 71 | virtual void visit(LtExprASTNode *n); 72 | virtual void visit(LeExprASTNode *n); 73 | virtual void visit(GtExprASTNode *n); 74 | virtual void visit(GeExprASTNode *n); 75 | virtual void visit(EqExprASTNode *n); 76 | virtual void visit(NeExprASTNode *n); 77 | virtual void visit(AssignExprASTNode *n); 78 | virtual void visit(CondExprASTNode *n); 79 | virtual void visit(CallExprASTNode *n); 80 | virtual void visit(VoidTypeASTNode *n); 81 | virtual void visit(IntegralTypeASTNode *n); 82 | virtual void visit(RealTypeASTNode *n); 83 | virtual void visit(EnumeralTypeASTNode *n); 84 | virtual void visit(PointerTypeASTNode *n); 85 | virtual void visit(FunctionTypeASTNode *n); 86 | virtual void visit(ArrayTypeASTNode *n); 87 | virtual void visit(StructTypeASTNode *n); 88 | virtual void visit(UnionTypeASTNode *n); 89 | virtual void visit(NullASTNode *n); 90 | virtual void visit(SequenceASTNode *n); 91 | }; 92 | 93 | } // namespace cparser 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /include/common.h: -------------------------------------------------------------------------------- 1 | // Common stuff. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #ifndef COMMON_H 9 | #define COMMON_H 10 | 11 | #include 12 | 13 | #define IDLEN 256 14 | #define MAXSTR 1024 15 | 16 | #define FAIL -1 17 | 18 | namespace cparser 19 | { 20 | 21 | typedef unsigned char uint8_t; 22 | typedef unsigned short uint16_t; 23 | typedef unsigned int uint32_t; 24 | 25 | class CharCompare 26 | { 27 | public: 28 | bool operator()(const char *a, const char *b) const 29 | { 30 | return strcmp(a, b) < 0; 31 | } 32 | }; 33 | 34 | } // namespace cparser 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/ASTNode.cpp: -------------------------------------------------------------------------------- 1 | // ASTNode - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/ASTNode.h" 9 | #include "../include/TreeVisitor.h" 10 | 11 | namespace cparser 12 | { 13 | 14 | NullASTNode *NullASTNode::s_instance = 0; 15 | 16 | void IdentASTNode::accept(TreeVisitor *v) { v->visit(this); } 17 | 18 | void IntegerConstASTNode::accept(TreeVisitor *v) { v->visit(this); } 19 | 20 | void RealConstASTNode::accept(TreeVisitor *v) { v->visit(this); } 21 | 22 | void StringConstASTNode::accept(TreeVisitor *v) { v->visit(this); } 23 | 24 | void CharConstASTNode::accept(TreeVisitor *v) { v->visit(this); } 25 | 26 | void SizeOfExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 27 | 28 | void AlignOfExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 29 | 30 | void TypeDeclASTNode::accept(TreeVisitor *v) { v->visit(this); } 31 | 32 | void FunctionDeclASTNode::accept(TreeVisitor *v) { v->visit(this); } 33 | 34 | void VarDeclASTNode::accept(TreeVisitor *v) { v->visit(this); } 35 | 36 | void ParmDeclASTNode::accept(TreeVisitor *v) { v->visit(this); } 37 | 38 | void FieldDeclASTNode::accept(TreeVisitor *v) { v->visit(this); } 39 | 40 | void AsmStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 41 | 42 | void BreakStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 43 | 44 | void CaseLabelASTNode::accept(TreeVisitor *v) { v->visit(this); } 45 | 46 | void CompoundStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 47 | 48 | void ContinueStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 49 | 50 | void DoStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 51 | 52 | void ForStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 53 | 54 | void GotoStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 55 | 56 | void IfStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 57 | 58 | void LabelStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 59 | 60 | void ReturnStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 61 | 62 | void SwitchStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 63 | 64 | void WhileStmtASTNode::accept(TreeVisitor *v) { v->visit(this); } 65 | 66 | void CastExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 67 | 68 | void BitNotExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 69 | 70 | void LogNotExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 71 | 72 | void PredecrementExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 73 | 74 | void PreincrementExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 75 | 76 | void PostdecrementExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 77 | 78 | void PostincrementExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 79 | 80 | void AddrExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 81 | 82 | void IndirectRefASTNode::accept(TreeVisitor *v) { v->visit(this); } 83 | 84 | void NopExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 85 | 86 | void LShiftExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 87 | 88 | void RShiftExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 89 | 90 | void BitIorExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 91 | 92 | void BitXorExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 93 | 94 | void BitAndExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 95 | 96 | void LogAndExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 97 | 98 | void LogOrExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 99 | 100 | void PlusExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 101 | 102 | void MinusExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 103 | 104 | void MultExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 105 | 106 | void TruncDivExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 107 | 108 | void TruncModExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 109 | 110 | void ArrayRefASTNode::accept(TreeVisitor *v) { v->visit(this); } 111 | 112 | void StructRefASTNode::accept(TreeVisitor *v) { v->visit(this); } 113 | 114 | void LtExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 115 | 116 | void LeExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 117 | 118 | void GtExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 119 | 120 | void GeExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 121 | 122 | void EqExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 123 | 124 | void NeExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 125 | 126 | void AssignExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 127 | 128 | void CondExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 129 | 130 | void CallExprASTNode::accept(TreeVisitor *v) { v->visit(this); } 131 | 132 | void VoidTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 133 | 134 | void IntegralTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 135 | 136 | void RealTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 137 | 138 | void EnumeralTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 139 | 140 | void PointerTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 141 | 142 | void FunctionTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 143 | 144 | void ArrayTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 145 | 146 | void StructTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 147 | 148 | void UnionTypeASTNode::accept(TreeVisitor *v) { v->visit(this); } 149 | 150 | void NullASTNode::accept(TreeVisitor *v) { v->visit(this); } 151 | 152 | void SequenceASTNode::accept(TreeVisitor *v) { v->visit(this); } 153 | 154 | } // namespace cparser 155 | -------------------------------------------------------------------------------- /src/AbstractSyntaxTree.cpp: -------------------------------------------------------------------------------- 1 | // Abstract syntax tree - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/AbstractSyntaxTree.h" 9 | #include "../include/ASTNode.h" 10 | #include "../include/PrintTreeVisitor.h" 11 | #include "../include/TreeVisitor.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | namespace cparser 21 | { 22 | 23 | void AbstractSyntaxTree::error(int lineNum, const char *format, ...) 24 | { 25 | char dest[4096]; 26 | 27 | va_list argptr; 28 | va_start(argptr, format); 29 | vsprintf(dest, format, argptr); 30 | va_end(argptr); 31 | printf("error: %s; line %d\n", dest, lineNum); 32 | 33 | exit(1); 34 | } 35 | 36 | void AbstractSyntaxTree::warning(int lineNum, const char *format, ...) 37 | { 38 | char dest[4096]; 39 | 40 | va_list argptr; 41 | va_start(argptr, format); 42 | vsprintf(dest, format, argptr); 43 | va_end(argptr); 44 | printf("warning: %s; line %d\n", dest, lineNum); 45 | _warnings++; 46 | } 47 | 48 | void AbstractSyntaxTree::visit(TreeVisitor *visitor) 49 | { 50 | if (_root->getKind() == NK_LIST) 51 | _stb->setTopScope(static_cast(_root)->getScope()); 52 | 53 | visitor->visit(static_cast(_root)); 54 | 55 | if (_root->getKind() == NK_LIST) 56 | _stb->setTopScope(nullptr); 57 | } 58 | 59 | STType *AbstractSyntaxTree::getStbType(ASTNode *typeASTNode) 60 | { 61 | switch (typeASTNode->getKind()) 62 | { 63 | case NK_VOID_TYPE: 64 | return _stb->voidType; 65 | case NK_INTEGRAL_TYPE: 66 | { 67 | IntegralTypeASTNode *intTypeASTNode = 68 | static_cast(typeASTNode); 69 | 70 | if (intTypeASTNode->getIsSigned()) 71 | { 72 | switch (intTypeASTNode->getAlignment()) 73 | { 74 | case 1: 75 | return _stb->charType; 76 | case 2: 77 | return _stb->shortType; 78 | case 4: 79 | return _stb->intType; 80 | case 8: 81 | return _stb->longType; 82 | default: 83 | return _stb->noType; 84 | } 85 | } 86 | else 87 | { 88 | switch (intTypeASTNode->getAlignment()) 89 | { 90 | // case 1: return stb->charType; 91 | // case 2: return stb->shortType; 92 | case 4: 93 | return _stb->unsignedType; 94 | default: 95 | return _stb->noType; 96 | } 97 | } 98 | } 99 | break; 100 | case NK_REAL_TYPE: 101 | { 102 | RealTypeASTNode *realTypeASTNode = 103 | static_cast(typeASTNode); 104 | 105 | return realTypeASTNode->getIsDouble() ? _stb->doubleType 106 | : _stb->floatType; 107 | } 108 | case NK_COMPLEX_TYPE: 109 | return _stb->noType; 110 | case NK_ENUMERAL_TYPE: 111 | return _stb->noType; 112 | case NK_BOOLEAN_TYPE: 113 | return _stb->noType; 114 | case NK_POINTER_TYPE: 115 | { 116 | STType *type = _stb->allocType(STTK_POINTER); 117 | PointerTypeASTNode *ptrTypeASTNode = 118 | static_cast(typeASTNode); 119 | type->baseType = getStbType(ptrTypeASTNode->getBaseType()); 120 | type->size = 4; // Pointer type size is 4 bytes. 121 | return type; 122 | } 123 | case NK_REFERENCE_TYPE: 124 | return _stb->noType; 125 | case NK_FUNCTION_TYPE: 126 | { 127 | STType *type = _stb->allocType(STTK_FUNCTION); 128 | FunctionDeclASTNode *funcTypeASTNode = 129 | static_cast(typeASTNode); 130 | 131 | type->funcType = getStbType(funcTypeASTNode->getType()); 132 | type->size = 4; 133 | return type; 134 | } 135 | case NK_ARRAY_TYPE: 136 | { 137 | STType *type = _stb->allocType(STTK_ARRAY); 138 | ArrayTypeASTNode *arrTypeASTNode = 139 | static_cast(typeASTNode); 140 | type->elemType = getStbType(arrTypeASTNode->getElementType()); 141 | 142 | if (AST_MATCH_INTEGER_CONST(arrTypeASTNode->getExpr())) 143 | type->size = type->elemType->size * 144 | AST_INTEGER_CONST_VALUE(arrTypeASTNode->getExpr()); 145 | 146 | return type; 147 | } 148 | case NK_STRUCT_TYPE: 149 | { 150 | STType *type = nullptr; 151 | // FIXME: At this point a record type should already be in the 152 | // symbol table. 153 | StructTypeASTNode *recTypeASTNode = 154 | static_cast(typeASTNode); 155 | 156 | if (AST_MATCH_IDENT(recTypeASTNode->getName())) 157 | { 158 | const char *recordName = 159 | AST_IDENT_VALUE(recTypeASTNode->getName()); 160 | unsigned recordLineNum = 161 | AST_IDENT_LINE_NUM(recTypeASTNode->getName()); 162 | STObject *obj = _stb->find(recordName); 163 | 164 | if (obj == _stb->noObj) 165 | // Record type declaration is not found in symbol table. 166 | error(recordLineNum, 167 | "struct type '%s' not declared", 168 | recordName); 169 | else 170 | type = obj->type; 171 | } 172 | return type; 173 | } 174 | case NK_UNION_TYPE: 175 | { 176 | STType *type = nullptr; 177 | // FIXME: At this point a union type should already be in the 178 | // symbol table. 179 | UnionTypeASTNode *unionTypeASTNode = 180 | static_cast(typeASTNode); 181 | 182 | if (AST_MATCH_IDENT(unionTypeASTNode->getName())) 183 | { 184 | const char *unionName = 185 | AST_IDENT_VALUE(unionTypeASTNode->getName()); 186 | unsigned unionLineNum = 187 | AST_IDENT_LINE_NUM(unionTypeASTNode->getName()); 188 | STObject *obj = _stb->find(unionName); 189 | 190 | if (obj == _stb->noObj) 191 | // Union type declaration is not found in symbol table. 192 | error(unionLineNum, 193 | "union type '%s' not declared", 194 | unionName); 195 | else 196 | type = obj->type; 197 | } 198 | return type; 199 | } 200 | case NK_UNKNOWN_TYPE: 201 | return _stb->noType; 202 | default: 203 | return _stb->noType; 204 | } 205 | } 206 | 207 | void AbstractSyntaxTree::declare() 208 | { 209 | if (_root->getKind() == NK_LIST) 210 | _stb->setTopScope(static_cast(_root)->getScope()); 211 | 212 | _root->declare(this); 213 | 214 | if (_root->getKind() == NK_LIST) 215 | _stb->setTopScope(nullptr); 216 | } 217 | 218 | void TypeDeclASTNode::declare(AbstractSyntaxTree *ast) 219 | { 220 | assert(_name != NULL_AST_NODE && "invalid type declaration"); 221 | 222 | SymbolTable *stb = ast->getSymbolTable(); 223 | const char *typeName = AST_IDENT_VALUE(_name); 224 | unsigned typeNameLineNum = AST_IDENT_LINE_NUM(_name); 225 | 226 | // FIXME: Using noType is only temporary solution 227 | STObject *obj = stb->insert(typeName, STOK_TYPE, stb->noType); 228 | 229 | if (obj == stb->noObj) 230 | ast->error(typeNameLineNum, 231 | "type name '%s' already exists", 232 | typeName); 233 | } 234 | 235 | void CompoundStmtASTNode::declare(AbstractSyntaxTree *ast) 236 | { 237 | _decls->declare(ast); 238 | } 239 | 240 | void SequenceASTNode::declare(AbstractSyntaxTree *ast) 241 | { 242 | for (unsigned i = 0; i < _elements.size(); i++) 243 | _elements[i]->declare(ast); 244 | } 245 | 246 | } // namespace cparser 247 | -------------------------------------------------------------------------------- /src/CLexer.cpp: -------------------------------------------------------------------------------- 1 | // C Lexer - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/Lexer.h" 9 | #include "../include/CLexer.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace cparser 17 | { 18 | 19 | // Search of keyword 20 | unsigned CLexer::keyword(const char *s) 21 | { 22 | TokenMap::iterator it = _kwmap.find(s); 23 | 24 | if (it != _kwmap.end()) 25 | { 26 | return it->second; 27 | } 28 | else 29 | { 30 | // Search of keyword that can be first in a statement 31 | it = _fstmtmap.find(s); 32 | return (it != _fstmtmap.end()) ? (it->second) : TK_IDENT; 33 | } 34 | } 35 | 36 | void CLexer::readName(Token *t) 37 | { 38 | t->sval.clear(); 39 | t->sval.push_back(_ch); 40 | nextCh(); 41 | 42 | while (isalnum(_ch) || _ch == '_') 43 | { 44 | t->sval.push_back(_ch); 45 | nextCh(); 46 | } 47 | 48 | t->kind = keyword(t->sval.c_str()); 49 | } 50 | 51 | void CLexer::readNumberLit(Token *t) 52 | { 53 | char buffer[32]; 54 | int n = 1; 55 | bool hex = false, real = false; 56 | 57 | t->kind = TK_INT_LIT; 58 | buffer[0] = _ch; 59 | nextCh(); 60 | 61 | if (_ch == 'x' && buffer[0] == '0') 62 | { 63 | nextCh(); 64 | hex = true; 65 | while (isdigit(_ch) || isHexDigit(_ch)) 66 | { 67 | buffer[n++] = _ch; 68 | nextCh(); 69 | } 70 | // TODO: Handle this 71 | if (_ch == 'L') 72 | nextCh(); 73 | } 74 | else 75 | { 76 | while (isdigit(_ch)) 77 | { 78 | buffer[n++] = _ch; 79 | nextCh(); 80 | } 81 | } 82 | 83 | if (_ch == '.') 84 | { 85 | real = true; 86 | nextCh(); 87 | } 88 | 89 | if (hex) 90 | { 91 | int currentDigit, result = 0, power = 0; 92 | 93 | n--; 94 | while (n >= 0) 95 | { 96 | if (isdigit(buffer[n])) 97 | currentDigit = buffer[n] - '0'; 98 | else 99 | currentDigit = buffer[n] - '7'; 100 | 101 | result += currentDigit * powr(16, power); 102 | power++; 103 | n--; 104 | } 105 | t->info.ival = result; 106 | } 107 | else 108 | { 109 | int i, digitcnt = 10; 110 | 111 | t->info.ival = buffer[0] - '0'; 112 | for (i = 1; i < n; i++) 113 | t->info.ival = t->info.ival * 10 + buffer[i] - '0'; 114 | 115 | if (real) 116 | { 117 | int mantissa = _ch - '0'; 118 | 119 | t->kind = TK_FLOAT_LIT; 120 | nextCh(); 121 | while (isdigit(_ch)) 122 | { 123 | mantissa = mantissa * 10 + _ch - '0'; 124 | digitcnt *= 10; 125 | nextCh(); 126 | } 127 | t->info.fval = 128 | ((float)t->info.ival) + ((float)mantissa / (float)digitcnt); 129 | } 130 | } 131 | } 132 | 133 | // TODO: Handle escape characters like: \", \n, \t, ... 134 | void CLexer::readStringLit(Token *t) 135 | { 136 | // Skip the " 137 | nextCh(); 138 | t->kind = TK_STRING_LIT; 139 | t->sval.clear(); 140 | t->sval.push_back(_ch); 141 | nextCh(); 142 | 143 | while (_ch != '"') 144 | { 145 | t->sval.push_back(_ch); 146 | nextCh(); 147 | } 148 | 149 | // Skip again the " 150 | nextCh(); 151 | 152 | bool searchNextStringLit = true; 153 | 154 | do 155 | { 156 | while (isspace(_ch)) 157 | nextCh(); 158 | 159 | if (_ch == '"') 160 | { 161 | nextCh(); 162 | while (_ch != '"') 163 | { 164 | t->sval.push_back(_ch); 165 | nextCh(); 166 | } 167 | // Skip again the " 168 | nextCh(); 169 | } 170 | else 171 | { 172 | searchNextStringLit = false; 173 | } 174 | } 175 | while (searchNextStringLit); 176 | } 177 | 178 | void CLexer::readCharLit(Token *t) 179 | { 180 | // Skip the ' 181 | nextCh(); 182 | t->kind = TK_CHAR_LIT; 183 | 184 | if (_ch == '\\') 185 | { 186 | nextCh(); 187 | switch (_ch) 188 | { 189 | case '0': 190 | t->info.ival = 0; 191 | break; // Null char 192 | case 'b': 193 | t->info.ival = 8; 194 | break; // Backspace 195 | case 't': 196 | t->info.ival = 9; 197 | break; // Horizontal tab 198 | case 'n': 199 | t->info.ival = 10; 200 | break; // New line 201 | case 'v': 202 | t->info.ival = 11; 203 | break; // Vertical tab 204 | case 'f': 205 | t->info.ival = 12; 206 | break; // Form feed 207 | case 'r': 208 | t->info.ival = 13; 209 | break; // Carriage return 210 | case '\'': 211 | t->info.ival = 39; 212 | break; // Single quote 213 | case '\\': 214 | t->info.ival = 92; 215 | break; // Backslash 216 | default: 217 | error(_line, "invalid character constant"); 218 | break; 219 | } 220 | nextCh(); 221 | } 222 | else 223 | { 224 | t->info.ival = _ch; 225 | nextCh(); 226 | } 227 | 228 | if (_ch != '\'') 229 | { 230 | error(_line, "character expected"); 231 | while (_ch != '\'' && _ch != EOF) 232 | { 233 | // error 234 | nextCh(); 235 | } 236 | } 237 | 238 | // Skip ' 239 | nextCh(); 240 | } 241 | 242 | void CLexer::comment() 243 | { 244 | while (_ch != EOF) 245 | { 246 | nextCh(); 247 | if (_ch == '*') 248 | { 249 | nextCh(); 250 | if (_ch == '/') 251 | break; 252 | } 253 | else if (_ch == '/') 254 | { 255 | nextCh(); 256 | if (_ch == '*') 257 | comment(); 258 | } 259 | } 260 | nextCh(); 261 | } 262 | 263 | unsigned CLexer::next(Token *t) 264 | { 265 | while (isspace(_ch)) 266 | nextCh(); 267 | 268 | t->line = _line; 269 | t->col = _col; 270 | 271 | if (isalpha(_ch) || _ch == '_') 272 | { 273 | readName(t); 274 | } 275 | else if (isdigit(_ch)) 276 | { 277 | readNumberLit(t); 278 | } 279 | else 280 | { 281 | switch (_ch) 282 | { 283 | case '"': 284 | readStringLit(t); 285 | break; 286 | case '\'': 287 | readCharLit(t); 288 | break; 289 | case '#': 290 | while (_ch != '\n') 291 | nextCh(); 292 | return next(t); 293 | case '&': 294 | nextCh(); 295 | if (_ch == '&') 296 | { 297 | nextCh(); 298 | t->kind = TK_LOGICAL_AND; 299 | } 300 | else if (_ch == '=') 301 | { 302 | nextCh(); 303 | t->kind = TK_AND_ASSIGN; 304 | } 305 | else 306 | { 307 | t->kind = TK_AND; 308 | } 309 | break; 310 | case '!': 311 | nextCh(); 312 | if (_ch == '=') 313 | { 314 | nextCh(); 315 | t->kind = TK_NEQ; 316 | } 317 | else 318 | { 319 | t->kind = TK_NOT; 320 | } 321 | break; 322 | case '|': 323 | nextCh(); 324 | if (_ch == '|') 325 | { 326 | nextCh(); 327 | t->kind = TK_LOGICAL_OR; 328 | } 329 | else if (_ch == '=') 330 | { 331 | nextCh(); 332 | t->kind = TK_OR_ASSIGN; 333 | } 334 | else 335 | { 336 | t->kind = TK_OR; 337 | } 338 | break; 339 | case '{': 340 | nextCh(); 341 | t->kind = TK_LBRACE; 342 | break; 343 | case '}': 344 | nextCh(); 345 | t->kind = TK_RBRACE; 346 | break; 347 | case '(': 348 | nextCh(); 349 | t->kind = TK_LPAR; 350 | break; 351 | case ')': 352 | nextCh(); 353 | t->kind = TK_RPAR; 354 | break; 355 | case '*': 356 | nextCh(); 357 | if (_ch == '=') 358 | { 359 | nextCh(); 360 | t->kind = TK_MUL_ASSIGN; 361 | } 362 | else 363 | { 364 | t->kind = TK_TIMES; 365 | } 366 | break; 367 | case '+': 368 | nextCh(); 369 | if (_ch == '+') 370 | { 371 | nextCh(); 372 | t->kind = TK_INC_OP; 373 | } 374 | else if (_ch == '=') 375 | { 376 | nextCh(); 377 | t->kind = TK_ADD_ASSIGN; 378 | } 379 | else 380 | { 381 | t->kind = TK_PLUS; 382 | } 383 | break; 384 | case '-': 385 | nextCh(); 386 | if (_ch == '-') 387 | { 388 | nextCh(); 389 | t->kind = TK_DEC_OP; 390 | } 391 | else if (_ch == '>') 392 | { 393 | nextCh(); 394 | t->kind = TK_PTR_OP; 395 | } 396 | else if (_ch == '=') 397 | { 398 | nextCh(); 399 | t->kind = TK_SUB_ASSIGN; 400 | } 401 | else 402 | { 403 | t->kind = TK_MINUS; 404 | } 405 | break; 406 | case '%': 407 | nextCh(); 408 | if (_ch == '=') 409 | { 410 | nextCh(); 411 | t->kind = TK_MOD_ASSIGN; 412 | } 413 | else 414 | { 415 | t->kind = TK_MOD; 416 | } 417 | break; 418 | case ',': 419 | nextCh(); 420 | t->kind = TK_COMMA; 421 | break; 422 | case '/': 423 | nextCh(); 424 | if (_ch == '/') 425 | { 426 | while (_ch != '\n') 427 | nextCh(); 428 | return next(t); 429 | } 430 | else if (_ch == '*') 431 | { 432 | comment(); 433 | return next(t); 434 | } 435 | else if (_ch == '=') 436 | { 437 | nextCh(); 438 | t->kind = TK_DIV_ASSIGN; 439 | } 440 | else 441 | { 442 | t->kind = TK_DIV; 443 | } 444 | break; 445 | case ';': 446 | nextCh(); 447 | t->kind = TK_SEMICOLON; 448 | break; 449 | case '=': 450 | nextCh(); 451 | if (_ch == '=') 452 | { 453 | nextCh(); 454 | t->kind = TK_EQL; 455 | } 456 | else 457 | { 458 | t->kind = TK_ASSIGN; 459 | } 460 | break; 461 | case '[': 462 | nextCh(); 463 | t->kind = TK_LBRACK; 464 | break; 465 | case ']': 466 | nextCh(); 467 | t->kind = TK_RBRACK; 468 | break; 469 | case '^': 470 | nextCh(); 471 | if (_ch == '=') 472 | { 473 | nextCh(); 474 | t->kind = TK_XOR_ASSIGN; 475 | } 476 | else 477 | { 478 | t->kind = TK_EXCLUSIVE_OR; 479 | } 480 | break; 481 | case '~': 482 | nextCh(); 483 | t->kind = TK_TILDA; 484 | break; 485 | case '?': 486 | nextCh(); 487 | t->kind = TK_COND_OP; 488 | break; 489 | case ':': 490 | nextCh(); 491 | t->kind = TK_COLON; 492 | break; 493 | case '<': 494 | nextCh(); 495 | if (_ch == '=') 496 | { 497 | nextCh(); 498 | t->kind = TK_LEQ; 499 | } 500 | else if (_ch == '<') 501 | { 502 | nextCh(); 503 | if (_ch == '=') 504 | { 505 | nextCh(); 506 | t->kind = TK_LSHIFT_ASSIGN; 507 | } 508 | else 509 | { 510 | t->kind = TK_LSHIFT_OP; 511 | } 512 | } 513 | else 514 | { 515 | t->kind = TK_LSS; 516 | } 517 | break; 518 | case '>': 519 | nextCh(); 520 | if (_ch == '=') 521 | { 522 | nextCh(); 523 | t->kind = TK_GEQ; 524 | } 525 | else if (_ch == '>') 526 | { 527 | nextCh(); 528 | if (_ch == '=') 529 | { 530 | nextCh(); 531 | t->kind = TK_RSHIFT_ASSIGN; 532 | } 533 | else 534 | { 535 | t->kind = TK_RSHIFT_OP; 536 | } 537 | } 538 | else 539 | { 540 | t->kind = TK_GTR; 541 | } 542 | break; 543 | case '.': 544 | nextCh(); 545 | if (_ch == '.') 546 | { 547 | nextCh(); 548 | if (_ch == '.') 549 | { 550 | nextCh(); 551 | t->kind = TK_ELLIPSIS; 552 | } 553 | else 554 | { 555 | t->kind = TK_UNKNOWN; 556 | } 557 | } 558 | else 559 | t->kind = TK_PERIOD; 560 | break; 561 | case EOF: 562 | t->kind = TK_EOF; 563 | break; 564 | default: 565 | nextCh(); 566 | t->kind = TK_UNKNOWN; 567 | break; 568 | } 569 | } 570 | 571 | return t->kind; 572 | } 573 | 574 | void CLexer::initialize() 575 | { 576 | // Insert reserved words 577 | INSERT_KEYWORD("_Alignas", TK__ALIGNAS); 578 | INSERT_KEYWORD("_Alignof", TK__ALIGNOF); 579 | INSERT_KEYWORD("_Atomic", TK__ATOMIC); 580 | INSERT_KEYWORD("_Bool", TK__BOOL); 581 | INSERT_KEYWORD("_Complex", TK__COMPLEX); 582 | INSERT_KEYWORD("_Generic", TK__GENERIC); 583 | INSERT_KEYWORD("_Imaginary", TK__IMAGINARY); 584 | INSERT_KEYWORD("_Noreturn", TK__NORETURN); 585 | INSERT_KEYWORD("_Nullable", TK__NULLABLE); 586 | INSERT_KEYWORD("_Static_assert", TK__STATIC_ASSERT); 587 | INSERT_KEYWORD("_Thread_local", TK__THREAD_LOCAL); 588 | INSERT_KEYWORD("__func__", TK___FUNC__); 589 | 590 | INSERT_KEYWORD("__attribute__", TK___ATTRIBUTE__); 591 | INSERT_KEYWORD("__asm", TK___ASM); 592 | 593 | INSERT_KEYWORD("auto", TK_AUTO); 594 | INSERT_KEYWORD("char", TK_CHAR); 595 | INSERT_KEYWORD("const", TK_CONST); 596 | INSERT_KEYWORD("double", TK_DOUBLE); 597 | INSERT_KEYWORD("else", TK_ELSE); 598 | INSERT_KEYWORD("enum", TK_ENUM); 599 | INSERT_KEYWORD("extern", TK_EXTERN); 600 | INSERT_KEYWORD("float", TK_FLOAT); 601 | INSERT_KEYWORD("inline", TK_INLINE); 602 | INSERT_KEYWORD("int", TK_INT); 603 | INSERT_KEYWORD("long", TK_LONG); 604 | INSERT_KEYWORD("register", TK_REGISTER); 605 | INSERT_KEYWORD("restrict", TK_RESTRICT); 606 | INSERT_KEYWORD("short", TK_SHORT); 607 | INSERT_KEYWORD("signed", TK_SIGNED); 608 | INSERT_KEYWORD("sizeof", TK_SIZEOF); 609 | INSERT_KEYWORD("static", TK_STATIC); 610 | INSERT_KEYWORD("struct", TK_STRUCT); 611 | INSERT_KEYWORD("typedef", TK_TYPEDEF); 612 | INSERT_KEYWORD("union", TK_UNION); 613 | INSERT_KEYWORD("unsigned", TK_UNSIGNED); 614 | INSERT_KEYWORD("void", TK_VOID); 615 | INSERT_KEYWORD("volatile", TK_VOLATILE); 616 | 617 | INSERT_FIRST_OF_STMT_KEYWORD("_Generic", TK__GENERIC); 618 | INSERT_FIRST_OF_STMT_KEYWORD("asm", TK_ASM); 619 | INSERT_FIRST_OF_STMT_KEYWORD("break", TK_BREAK); 620 | INSERT_FIRST_OF_STMT_KEYWORD("case", TK_CASE); 621 | INSERT_FIRST_OF_STMT_KEYWORD("continue", TK_CONTINUE); 622 | INSERT_FIRST_OF_STMT_KEYWORD("default", TK_DEFAULT); 623 | INSERT_FIRST_OF_STMT_KEYWORD("do", TK_DO); 624 | INSERT_FIRST_OF_STMT_KEYWORD("for", TK_FOR); 625 | INSERT_FIRST_OF_STMT_KEYWORD("goto", TK_GOTO); 626 | INSERT_FIRST_OF_STMT_KEYWORD("if", TK_IF); 627 | INSERT_FIRST_OF_STMT_KEYWORD("return", TK_RETURN); 628 | INSERT_FIRST_OF_STMT_KEYWORD("switch", TK_SWITCH); 629 | INSERT_FIRST_OF_STMT_KEYWORD("while", TK_WHILE); 630 | } 631 | 632 | } // namespace cparser 633 | -------------------------------------------------------------------------------- /src/GenCVisitor.cpp: -------------------------------------------------------------------------------- 1 | // Generate C visitor - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/GenCVisitor.h" 9 | #include "../include/ASTNode.h" 10 | #include "../include/TreeVisitor.h" 11 | 12 | #include 13 | 14 | #define TAB_SIZE 4 15 | 16 | namespace cparser 17 | { 18 | 19 | static void printTab(int n) 20 | { 21 | int i, x; 22 | 23 | x = n * TAB_SIZE; 24 | for (i = 0; i < x; i++) 25 | std::cout << " "; 26 | } 27 | 28 | void GenCVisitor::visit(IdentASTNode *n) 29 | { 30 | std::cout << n->getValue(); 31 | } 32 | 33 | void GenCVisitor::visit(IntegerConstASTNode *n) 34 | { 35 | std::cout << n->getValue(); 36 | } 37 | 38 | void GenCVisitor::visit(StringConstASTNode *n) 39 | { 40 | std::cout << "\"" << n->getValue() << "\""; 41 | } 42 | 43 | void GenCVisitor::visit(CharConstASTNode *n) 44 | { 45 | if (n->getValue() == '\n') 46 | std::cout << "'\\n'"; 47 | else 48 | std::cout << "'" << (char) n->getValue() << "'"; 49 | } 50 | 51 | void GenCVisitor::visit(SizeOfExprASTNode *n) 52 | { 53 | std::cout << "sizeof("; 54 | if (n->getExpr() != NULL_AST_NODE) 55 | n->getExpr()->accept(this); 56 | 57 | std::cout << ")"; 58 | } 59 | 60 | void GenCVisitor::visit(AlignOfExprASTNode *n) 61 | { 62 | std::cout << "_Alignof("; 63 | if (n->getExpr() != NULL_AST_NODE) 64 | n->getExpr()->accept(this); 65 | 66 | std::cout << ")"; 67 | } 68 | 69 | void GenCVisitor::visit(TypeDeclASTNode *n) 70 | { 71 | std::cout << "typedef "; 72 | n->getBody()->accept(this); 73 | std::cout << " "; 74 | n->getName()->accept(this); 75 | } 76 | 77 | void GenCVisitor::visit(FunctionDeclASTNode *n) 78 | { 79 | n->getType()->accept(this); 80 | 81 | std::cout << " "; 82 | 83 | n->getName()->accept(this); 84 | 85 | std::cout << "("; 86 | _inList++; 87 | n->getPrms()->accept(this); 88 | _inList--; 89 | std::cout << ")" << std::endl; 90 | 91 | n->getBody()->accept(this); 92 | } 93 | 94 | void GenCVisitor::visit(VarDeclASTNode *n) 95 | { 96 | // if (n->getType()->getKind() == NK_FUNCTION_TYPE) 97 | // { 98 | // static_cast(n->getType())->getType()->accept(this); 99 | // std::cout << "(*"; 100 | // n->getName()->accept(this); 101 | // std::cout << ")"; 102 | // std::cout << "("; 103 | // _inList++; 104 | // static_cast(n->getType())->getPrms()->accept(this); 105 | // _inList--; 106 | // std::cout << ")"; 107 | // } 108 | // else 109 | // { 110 | 111 | n->getType()->accept(this); 112 | 113 | std::cout << " "; 114 | 115 | // if (n->getType()->getKind() == NK_POINTER_TYPE) 116 | // std::cout << "*"; 117 | 118 | n->getName()->accept(this); 119 | 120 | if (n->getType()->getKind() == NK_ARRAY_TYPE) 121 | { 122 | std::cout << "["; 123 | // Print out type expression 124 | static_cast(n->getType())->getExpr()->accept(this); 125 | std::cout << "]"; 126 | } 127 | 128 | if (n->getInit() != NULL_AST_NODE) 129 | { 130 | std::cout << " = "; 131 | n->getInit()->accept(this); 132 | } 133 | 134 | // } 135 | } 136 | 137 | void GenCVisitor::visit(ParmDeclASTNode *n) 138 | { 139 | if (n->getType() != NULL_AST_NODE) 140 | n->getType()->accept(this); 141 | 142 | std::cout << " "; 143 | 144 | // if (n->getType()->getKind() == NK_POINTER_TYPE) 145 | // std::cout << "*"; 146 | 147 | if (n->getName() != NULL_AST_NODE) 148 | n->getName()->accept(this); 149 | } 150 | 151 | void GenCVisitor::visit(FieldDeclASTNode *n) 152 | { 153 | // _level++; 154 | // printTab(_level); 155 | // std::cout << "NK_FIELD_DECL" << std::endl; 156 | // if (n->getName() != NULL_AST_NODE) 157 | // { 158 | // printTab(_level); 159 | // std::cout << "Name:" << std::endl; 160 | // n->getName()->accept(this); 161 | // } 162 | // if (n->getType() != NULL_AST_NODE) 163 | // { 164 | // printTab(_level); 165 | // std::cout << "Type:" << std::endl; 166 | // n->getType()->accept(this); 167 | // } 168 | // _level--; 169 | 170 | if (n->getType() != NULL_AST_NODE) 171 | n->getType()->accept(this); 172 | 173 | std::cout << " "; 174 | 175 | if (n->getName() != NULL_AST_NODE) 176 | n->getName()->accept(this); 177 | 178 | } 179 | 180 | void GenCVisitor::visit(AsmStmtASTNode *n) 181 | { 182 | printTab(_level + 1); 183 | std::cout << "NK_ASM_STMT" << std::endl; 184 | printTab(_level + 1); 185 | std::cout << "Data:" << std::endl; 186 | printTab(_level + 2); 187 | std::cout << n->getData() << std::endl; 188 | } 189 | 190 | void GenCVisitor::visit(BreakStmtASTNode *n) 191 | { 192 | std::cout << "break"; 193 | } 194 | 195 | void GenCVisitor::visit(CaseLabelASTNode *n) 196 | { 197 | _level++; 198 | printTab(_level); 199 | std::cout << "CASE_LABEL" << std::endl; 200 | if (n->getExpr() != NULL_AST_NODE) 201 | { 202 | printTab(_level); 203 | std::cout << "Expression:" << std::endl; 204 | n->getExpr()->accept(this); 205 | } 206 | if (n->getStmt() != NULL_AST_NODE) 207 | { 208 | printTab(_level); 209 | std::cout << "Statement:" << std::endl; 210 | n->getStmt()->accept(this); 211 | } 212 | _level--; 213 | } 214 | 215 | void GenCVisitor::visit(CompoundStmtASTNode *n) 216 | { 217 | printTab(_level); 218 | std::cout << "{" << std::endl; 219 | 220 | _level++; 221 | 222 | if (n->getDecls() != NULL_AST_NODE) 223 | { 224 | n->getDecls()->accept(this); 225 | } 226 | 227 | if (n->getStmts() != NULL_AST_NODE) 228 | { 229 | n->getStmts()->accept(this); 230 | } 231 | 232 | _level--; 233 | 234 | printTab(_level); 235 | std::cout << "}" << std::endl; 236 | } 237 | 238 | void GenCVisitor::visit(ContinueStmtASTNode *n) 239 | { 240 | std::cout << "continue"; 241 | } 242 | 243 | void GenCVisitor::visit(DoStmtASTNode *n) 244 | { 245 | std::cout << "do" << std::endl; 246 | n->getBody()->accept(this); 247 | printTab(_level); 248 | std::cout << "while ("; 249 | n->getCondition()->accept(this); 250 | std::cout << ");" << std::endl; 251 | } 252 | 253 | void GenCVisitor::visit(ForStmtASTNode *n) 254 | { 255 | std::cout << "for ("; 256 | if (n->getInit() != NULL_AST_NODE) 257 | n->getInit()->accept(this); 258 | 259 | std::cout << ";"; 260 | if (n->getCondition() != NULL_AST_NODE) 261 | { 262 | std::cout << " "; 263 | n->getCondition()->accept(this); 264 | } 265 | std::cout << ";"; 266 | if (n->getStep() != NULL_AST_NODE) 267 | { 268 | std::cout << " "; 269 | n->getStep()->accept(this); 270 | } 271 | 272 | std::cout << ")" << std::endl; 273 | n->getBody()->accept(this); 274 | } 275 | 276 | void GenCVisitor::visit(GotoStmtASTNode *n) 277 | { 278 | std::cout << "goto "; 279 | n->getLabel()->accept(this); 280 | } 281 | 282 | void GenCVisitor::visit(IfStmtASTNode *n) 283 | { 284 | std::cout << "if ("; 285 | if (n->getCondition() != NULL_AST_NODE) 286 | n->getCondition()->accept(this); 287 | std::cout << ")" << std::endl; 288 | 289 | if (n->getThenClause() != NULL_AST_NODE) 290 | { 291 | if (n->getThenClause()->getKind() != NK_COMPOUND_STMT) 292 | printTab(_level+1); 293 | n->getThenClause()->accept(this); 294 | } 295 | 296 | if (n->getElseClause() != NULL_AST_NODE) 297 | { 298 | printTab(_level); 299 | std::cout << "else"; 300 | if (n->getElseClause()->getKind() == NK_IF_STMT) 301 | std::cout << " "; 302 | else 303 | std::cout << std::endl; 304 | if (n->getElseClause()->getKind() != NK_COMPOUND_STMT && 305 | n->getElseClause()->getKind() != NK_IF_STMT) 306 | printTab(_level+1); 307 | n->getElseClause()->accept(this); 308 | } 309 | std::cout << std::endl; 310 | } 311 | 312 | void GenCVisitor::visit(LabelStmtASTNode *n) 313 | { 314 | int prevLevel = _level; 315 | _level = 0; 316 | n->getLabel()->accept(this); 317 | _level = prevLevel; 318 | std::cout << ":" << std::endl; 319 | printTab(_level); 320 | n->getStmt()->accept(this); 321 | } 322 | 323 | void GenCVisitor::visit(ReturnStmtASTNode *n) 324 | { 325 | std::cout << "return"; 326 | if (n->getExpr() != NULL_AST_NODE) 327 | { 328 | std::cout << " "; 329 | n->getExpr()->accept(this); 330 | } 331 | } 332 | 333 | void GenCVisitor::visit(SwitchStmtASTNode *n) 334 | { 335 | _level++; 336 | printTab(_level); 337 | std::cout << "SWITCH_STMT" << std::endl; 338 | if (n->getExpr() != NULL_AST_NODE) 339 | { 340 | printTab(_level); 341 | std::cout << "Expression:" << std::endl; 342 | n->getExpr()->accept(this); 343 | } 344 | if (n->getStmt() != NULL_AST_NODE) 345 | { 346 | printTab(_level); 347 | std::cout << "Statement:" << std::endl; 348 | n->getStmt()->accept(this); 349 | } 350 | _level--; 351 | } 352 | 353 | void GenCVisitor::visit(WhileStmtASTNode *n) 354 | { 355 | std::cout << "while ("; 356 | if (n->getCondition() != NULL_AST_NODE) 357 | n->getCondition()->accept(this); 358 | std::cout << ")" << std::endl; 359 | 360 | if (n->getBody() != NULL_AST_NODE) 361 | n->getBody()->accept(this); 362 | } 363 | 364 | void GenCVisitor::visit(CastExprASTNode *n) 365 | { 366 | // _level++; 367 | // printTab(_level); 368 | // std::cout << "NK_CAST_EXPR" << std::endl; 369 | // if (n->getExpr() != NULL_AST_NODE) 370 | // { 371 | // printTab(_level); 372 | // std::cout << "Expression:" << std::endl; 373 | // n->getExpr()->accept(this); 374 | // } 375 | // if (n->getType() != NULL_AST_NODE) 376 | // { 377 | // printTab(_level); 378 | // std::cout << "Type:" << std::endl; 379 | // n->getType()->accept(this); 380 | // } 381 | // _level--; 382 | 383 | std::cout << "("; 384 | n->getType()->accept(this); 385 | std::cout << ") "; 386 | n->getExpr()->accept(this); 387 | } 388 | 389 | void GenCVisitor::visit(BitNotExprASTNode *n) 390 | { 391 | std::cout << "~"; 392 | n->getExpr()->accept(this); 393 | } 394 | 395 | void GenCVisitor::visit(LogNotExprASTNode *n) 396 | { 397 | std::cout << "!"; 398 | n->getExpr()->accept(this); 399 | } 400 | 401 | void GenCVisitor::visit(PredecrementExprASTNode *n) 402 | { 403 | std::cout << "--"; 404 | n->getExpr()->accept(this); 405 | } 406 | 407 | void GenCVisitor::visit(PreincrementExprASTNode *n) 408 | { 409 | std::cout << "++"; 410 | n->getExpr()->accept(this); 411 | } 412 | 413 | void GenCVisitor::visit(PostdecrementExprASTNode *n) 414 | { 415 | n->getExpr()->accept(this); 416 | std::cout << "--"; 417 | } 418 | 419 | void GenCVisitor::visit(PostincrementExprASTNode *n) 420 | { 421 | n->getExpr()->accept(this); 422 | std::cout << "++"; 423 | } 424 | 425 | void GenCVisitor::visit(AddrExprASTNode *n) 426 | { 427 | std::cout << "&"; 428 | n->getExpr()->accept(this); 429 | } 430 | 431 | void GenCVisitor::visit(IndirectRefASTNode *n) 432 | { 433 | if (n->getField() == NULL_AST_NODE) 434 | std::cout << "*"; 435 | 436 | if (n->getExpr() != NULL_AST_NODE) 437 | n->getExpr()->accept(this); 438 | 439 | if (n->getField() != NULL_AST_NODE) 440 | { 441 | std::cout << "->"; 442 | n->getField()->accept(this); 443 | } 444 | 445 | // if (n->getType() != NULL_AST_NODE) 446 | // { 447 | // printTab(_level); 448 | // std::cout << "Type:" << std::endl; 449 | // n->getType()->accept(this); 450 | // } 451 | // _level--; 452 | } 453 | 454 | void GenCVisitor::visit(NopExprASTNode *n) 455 | { 456 | _level++; 457 | printTab(_level); 458 | std::cout << "NK_NOP_EXPR" << std::endl; 459 | _level--; 460 | } 461 | 462 | void GenCVisitor::visit(LShiftExprASTNode *n) 463 | { 464 | n->getLhs()->accept(this); 465 | std::cout << " << "; 466 | n->getRhs()->accept(this); 467 | } 468 | 469 | void GenCVisitor::visit(RShiftExprASTNode *n) 470 | { 471 | n->getLhs()->accept(this); 472 | std::cout << " >> "; 473 | n->getRhs()->accept(this); 474 | } 475 | 476 | void GenCVisitor::visit(BitIorExprASTNode *n) 477 | { 478 | n->getLhs()->accept(this); 479 | std::cout << " | "; 480 | n->getRhs()->accept(this); 481 | } 482 | 483 | void GenCVisitor::visit(BitXorExprASTNode *n) 484 | { 485 | n->getLhs()->accept(this); 486 | std::cout << " ^ "; 487 | n->getRhs()->accept(this); 488 | } 489 | 490 | void GenCVisitor::visit(BitAndExprASTNode *n) 491 | { 492 | n->getLhs()->accept(this); 493 | std::cout << " & "; 494 | n->getRhs()->accept(this); 495 | } 496 | 497 | void GenCVisitor::visit(LogAndExprASTNode *n) 498 | { 499 | n->getLhs()->accept(this); 500 | std::cout << " && "; 501 | n->getRhs()->accept(this); 502 | } 503 | 504 | void GenCVisitor::visit(LogOrExprASTNode *n) 505 | { 506 | n->getLhs()->accept(this); 507 | std::cout << " || "; 508 | n->getRhs()->accept(this); 509 | } 510 | 511 | void GenCVisitor::visit(PlusExprASTNode *n) 512 | { 513 | n->getLhs()->accept(this); 514 | std::cout << " + "; 515 | n->getRhs()->accept(this); 516 | } 517 | 518 | void GenCVisitor::visit(MinusExprASTNode *n) 519 | { 520 | n->getLhs()->accept(this); 521 | std::cout << " - "; 522 | n->getRhs()->accept(this); 523 | } 524 | 525 | void GenCVisitor::visit(MultExprASTNode *n) 526 | { 527 | n->getLhs()->accept(this); 528 | std::cout << " * "; 529 | n->getRhs()->accept(this); 530 | } 531 | 532 | void GenCVisitor::visit(TruncDivExprASTNode *n) 533 | { 534 | n->getLhs()->accept(this); 535 | std::cout << " / "; 536 | n->getRhs()->accept(this); 537 | } 538 | 539 | void GenCVisitor::visit(TruncModExprASTNode *n) 540 | { 541 | n->getLhs()->accept(this); 542 | std::cout << " % "; 543 | n->getRhs()->accept(this); 544 | } 545 | 546 | void GenCVisitor::visit(ArrayRefASTNode *n) 547 | { 548 | // _level++; 549 | // printTab(_level); 550 | // std::cout << "ARRAY_REF" << std::endl; 551 | // if (n->getExpr() != NULL_AST_NODE) 552 | // { 553 | // printTab(_level); 554 | // std::cout << "Expression:" << std::endl; 555 | // n->getExpr()->accept(this); 556 | // } 557 | // if (n->getIndex() != NULL_AST_NODE) 558 | // { 559 | // printTab(_level); 560 | // std::cout << "Index:" << std::endl; 561 | // n->getIndex()->accept(this); 562 | // } 563 | // if (n->getType() != NULL_AST_NODE) 564 | // { 565 | // printTab(_level); 566 | // std::cout << "Element type:" << std::endl; 567 | // n->getType()->accept(this); 568 | // } 569 | // _level--; 570 | 571 | if (n->getExpr() != NULL_AST_NODE) 572 | n->getExpr()->accept(this); 573 | 574 | std::cout << "["; 575 | 576 | if (n->getIndex() != NULL_AST_NODE) 577 | n->getIndex()->accept(this); 578 | 579 | std::cout << "]"; 580 | } 581 | 582 | void GenCVisitor::visit(StructRefASTNode *n) 583 | { 584 | // _level++; 585 | // printTab(_level); 586 | // std::cout << "STRUCT_REF" << std::endl; 587 | // if (n->getName() != NULL_AST_NODE) 588 | // { 589 | // printTab(_level); 590 | // std::cout << "Name:" << std::endl; 591 | // n->getName()->accept(this); 592 | // } 593 | // if (n->getMember() != NULL_AST_NODE) 594 | // { 595 | // printTab(_level); 596 | // std::cout << "Member:" << std::endl; 597 | // n->getMember()->accept(this); 598 | // } 599 | // _level--; 600 | 601 | if (n->getName() != NULL_AST_NODE) 602 | n->getName()->accept(this); 603 | 604 | std::cout << "."; 605 | 606 | if (n->getMember() != NULL_AST_NODE) 607 | n->getMember()->accept(this); 608 | } 609 | 610 | void GenCVisitor::visit(LtExprASTNode *n) 611 | { 612 | n->getLhs()->accept(this); 613 | std::cout << " < "; 614 | n->getRhs()->accept(this); 615 | } 616 | 617 | void GenCVisitor::visit(LeExprASTNode *n) 618 | { 619 | n->getLhs()->accept(this); 620 | std::cout << " <= "; 621 | n->getRhs()->accept(this); 622 | } 623 | 624 | void GenCVisitor::visit(GtExprASTNode *n) 625 | { 626 | n->getLhs()->accept(this); 627 | std::cout << " > "; 628 | n->getRhs()->accept(this); 629 | } 630 | 631 | void GenCVisitor::visit(GeExprASTNode *n) 632 | { 633 | n->getLhs()->accept(this); 634 | std::cout << " >= "; 635 | n->getRhs()->accept(this); 636 | } 637 | 638 | void GenCVisitor::visit(EqExprASTNode *n) 639 | { 640 | n->getLhs()->accept(this); 641 | std::cout << " == "; 642 | n->getRhs()->accept(this); 643 | } 644 | 645 | void GenCVisitor::visit(NeExprASTNode *n) 646 | { 647 | n->getLhs()->accept(this); 648 | std::cout << " != "; 649 | n->getRhs()->accept(this); 650 | } 651 | 652 | void GenCVisitor::visit(AssignExprASTNode *n) 653 | { 654 | n->getLhs()->accept(this); 655 | std::cout << " = "; 656 | n->getRhs()->accept(this); 657 | } 658 | 659 | void GenCVisitor::visit(CondExprASTNode *n) 660 | { 661 | n->getCondition()->accept(this); 662 | std::cout << " ? "; 663 | n->getThenClause()->accept(this); 664 | std::cout << " : "; 665 | n->getElseClause()->accept(this); 666 | } 667 | 668 | void GenCVisitor::visit(CallExprASTNode *n) 669 | { 670 | n->getExpr()->accept(this); 671 | 672 | std::cout << "("; 673 | 674 | _inList++; 675 | n->getArgs()->accept(this); 676 | _inList--; 677 | 678 | std::cout << ")"; 679 | } 680 | 681 | void GenCVisitor::visit(VoidTypeASTNode *n) 682 | { 683 | std::cout << "void"; 684 | } 685 | 686 | void GenCVisitor::visit(IntegralTypeASTNode *n) 687 | { 688 | if (!n->getIsSigned()) 689 | std::cout << "unsigned "; 690 | 691 | switch (n->getAlignment()) 692 | { 693 | case 1: 694 | std::cout << "char"; 695 | break; 696 | case 2: 697 | std::cout << "short"; 698 | break; 699 | case 4: 700 | std::cout << "int"; 701 | break; 702 | case 8: 703 | std::cout << "long"; 704 | break; 705 | default: 706 | std::cout << "int"; 707 | break; 708 | } 709 | } 710 | 711 | void GenCVisitor::visit(RealTypeASTNode *n) 712 | { 713 | if (n->getIsDouble()) 714 | std::cout << "double"; 715 | else 716 | std::cout << "float"; 717 | } 718 | 719 | void GenCVisitor::visit(EnumeralTypeASTNode *n) 720 | { 721 | std::cout << "enum "; 722 | n->getName()->accept(this); 723 | printTab(_level); 724 | std::cout << std::endl << "{" << std::endl; 725 | _level++; 726 | _inList++; 727 | n->getBody()->accept(this); 728 | _inList--; 729 | _level--; 730 | printTab(_level); 731 | std::cout << "}"; 732 | } 733 | 734 | void GenCVisitor::visit(PointerTypeASTNode *n) 735 | { 736 | // std::cout << "* "; 737 | n->getBaseType()->accept(this); 738 | std::cout << "*"; 739 | } 740 | 741 | void GenCVisitor::visit(FunctionTypeASTNode *n) 742 | { 743 | // n->getType()->accept(this); 744 | // std::cout << "(*"; 745 | // // Name 746 | // std::cout << ")"; 747 | std::cout << "("; 748 | _inList++; 749 | n->getPrms()->accept(this); 750 | _inList--; 751 | std::cout << ")"; 752 | } 753 | 754 | void GenCVisitor::visit(ArrayTypeASTNode *n) 755 | { 756 | // std::cout << "["; 757 | // n->getExpr()->accept(this); 758 | // std::cout << "]" << std::endl; 759 | n->getElementType()->accept(this); 760 | } 761 | 762 | void GenCVisitor::visit(StructTypeASTNode *n) 763 | { 764 | std::cout << "struct "; 765 | 766 | if (n->getName() != NULL_AST_NODE) 767 | n->getName()->accept(this); 768 | 769 | if (n->getBody() != NULL_AST_NODE) 770 | { 771 | std::cout << std::endl; 772 | printTab(_level); 773 | std::cout << "{" << std::endl; 774 | 775 | _level++; 776 | n->getBody()->accept(this); 777 | _level--; 778 | 779 | printTab(_level); 780 | std::cout << "}"; 781 | } 782 | } 783 | 784 | void GenCVisitor::visit(UnionTypeASTNode *n) 785 | { 786 | // TODO: Implement 787 | } 788 | 789 | void GenCVisitor::visit(NullASTNode *n) 790 | { 791 | // Print nothing 792 | } 793 | 794 | static bool isNonSemi(ASTNodeKind n) 795 | { 796 | return n == NK_IF_STMT || n == NK_WHILE_STMT || n == NK_DO_STMT || 797 | n == NK_FUNCTION_DECL || n == NK_COMPOUND_STMT || 798 | n == NK_INTEGRAL_TYPE; 799 | } 800 | 801 | void GenCVisitor::visit(SequenceASTNode *n) 802 | { 803 | std::vector &elements = n->getElements(); 804 | 805 | if (elements.size() > 0) 806 | { 807 | if (!_inList) 808 | printTab(_level); 809 | elements[0]->accept(this); 810 | if (!_inList) 811 | { 812 | if (!isNonSemi(elements[0]->getKind())) 813 | std::cout << ";" << std::endl; 814 | } 815 | } 816 | 817 | for (unsigned i = 1; i < elements.size(); i++) 818 | { 819 | if (elements[i] == NULL_AST_NODE) 820 | continue; 821 | 822 | if (!_inList) 823 | printTab(_level); 824 | else 825 | std::cout << ", "; 826 | elements[i]->accept(this); 827 | if (!_inList) 828 | { 829 | if (!isNonSemi(elements[i]->getKind())) 830 | std::cout << ";" << std::endl; 831 | } 832 | } 833 | } 834 | 835 | } // namespace cparser 836 | -------------------------------------------------------------------------------- /src/Lexer.cpp: -------------------------------------------------------------------------------- 1 | // Lexer - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/Lexer.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace cparser 16 | { 17 | 18 | void Lexer::error(int lineNum, const char *format, ...) 19 | { 20 | char dest[4096]; 21 | 22 | va_list argptr; 23 | va_start(argptr, format); 24 | vsprintf(dest, format, argptr); 25 | va_end(argptr); 26 | printf("error: %s; line %d\n", dest, lineNum); 27 | 28 | exit(1); 29 | } 30 | 31 | bool Lexer::isHexDigit(char c) 32 | { 33 | if (c >= 'A' && c <= 'F') 34 | return true; 35 | return false; 36 | } 37 | 38 | int Lexer::powr(int x, int n) 39 | { 40 | if (n == 0) 41 | { 42 | return 1; 43 | } 44 | else if (n == 1) 45 | { 46 | return x; 47 | } 48 | else 49 | { 50 | int res = 1; 51 | 52 | for (int i = 0; i < n; i++) 53 | res = res * x; 54 | 55 | return res; 56 | } 57 | } 58 | 59 | void Lexer::nextCh() 60 | { 61 | _ch = getc(_fp); 62 | _col++; 63 | if (_ch == '\n') 64 | { 65 | _line++; 66 | _col = 0; 67 | } 68 | } 69 | 70 | Lexer::Lexer(const char *filename) 71 | { 72 | _line = 1; 73 | _col = 0; 74 | _ch = 0; 75 | 76 | // Load source file 77 | if (filename == NULL) 78 | _fp = stdin; 79 | else 80 | _fp = fopen(filename, "r"); 81 | 82 | if (_fp == NULL) 83 | { 84 | printf("Fatal error: file '%s' does not exists!\n", filename); 85 | exit(1); 86 | } 87 | } 88 | 89 | } // namespace cparser 90 | -------------------------------------------------------------------------------- /src/Parser.cpp: -------------------------------------------------------------------------------- 1 | // Parser - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/Parser.h" 9 | #include "../include/Lexer.h" 10 | #include 11 | #include 12 | 13 | namespace cparser 14 | { 15 | 16 | void Parser::getTok() 17 | { 18 | _tokIdx = _laIdx; 19 | _laIdx = (_laIdx + 1) % TOK_BUF_LEN; 20 | _newLaIdx = (_laIdx + 2) % TOK_BUF_LEN; 21 | 22 | // Get the current token 23 | _tok = &_tokbuf[_tokIdx]; 24 | 25 | // Get symbol type of first lookahead token 26 | _sym = _tokbuf[_laIdx].kind; 27 | 28 | // Allocate a new third lookahead token 29 | _lex->next(&_tokbuf[_newLaIdx]); 30 | } 31 | 32 | unsigned Parser::getLATok(unsigned k) 33 | { 34 | assert((k < TOK_BUF_LEN) && 35 | "k is greater than number of possible lookahead tokens"); 36 | 37 | return _tokbuf[(_tokIdx + k) % TOK_BUF_LEN].kind; 38 | } 39 | 40 | const char *Parser::getLATokInfoSval(unsigned k) 41 | { 42 | assert((k < TOK_BUF_LEN) && 43 | "k is greater than number of possible lookahead tokens"); 44 | 45 | const Token &token = _tokbuf[(_tokIdx + k) % TOK_BUF_LEN]; 46 | return token.sval.c_str(); 47 | } 48 | 49 | void Parser::parsingError(const char *msg) 50 | { 51 | std::cout << "line: " << _tok->line << "; col: " << _tok->col 52 | << "; error: " << msg << std::endl; 53 | _parsingErrors++; 54 | exit(1); 55 | } 56 | 57 | void Parser::check(unsigned expected) 58 | { 59 | if (_sym == expected) 60 | { 61 | getTok(); 62 | } 63 | else 64 | { 65 | char msg[MAXSTR]; 66 | 67 | sprintf(msg, "expected '%s'", _name[expected]); 68 | parsingError(msg); 69 | } 70 | } 71 | 72 | void Parser::initTokenBuffer() 73 | { 74 | _sym = _lex->next(&_tokbuf[0]); 75 | _lex->next(&_tokbuf[1]); 76 | _lex->next(&_tokbuf[2]); 77 | _laIdx = 0; 78 | } 79 | 80 | } // namespace cparser 81 | -------------------------------------------------------------------------------- /src/PrintTreeVisitor.cpp: -------------------------------------------------------------------------------- 1 | // Print tree visitor - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/PrintTreeVisitor.h" 9 | #include "../include/ASTNode.h" 10 | #include "../include/TreeVisitor.h" 11 | 12 | #include 13 | 14 | #define TAB_SIZE 4 15 | 16 | namespace cparser 17 | { 18 | 19 | static void printTab(int n) 20 | { 21 | int i, x; 22 | 23 | x = n * TAB_SIZE; 24 | for (i = 0; i < x; i++) 25 | std::cout << " "; 26 | } 27 | 28 | void PrintTreeVisitor::visit(IdentASTNode *n) 29 | { 30 | _level++; 31 | printTab(_level); 32 | std::cout << "NK_IDENT_NODE" << std::endl; 33 | printTab(_level); 34 | std::cout << "Value: " << n->getValue() << std::endl; 35 | _level--; 36 | } 37 | 38 | void PrintTreeVisitor::visit(IntegerConstASTNode *n) 39 | { 40 | _level++; 41 | printTab(_level); 42 | std::cout << "NK_INTEGER_CONST" << std::endl; 43 | printTab(_level); 44 | std::cout << "Value: " << n->getValue() << std::endl; 45 | _level--; 46 | } 47 | 48 | void PrintTreeVisitor::visit(StringConstASTNode *n) 49 | { 50 | _level++; 51 | printTab(_level); 52 | std::cout << "NK_STRING_CONST" << std::endl; 53 | printTab(_level); 54 | std::cout << "Value: " << n->getValue() << std::endl; 55 | _level--; 56 | } 57 | 58 | void PrintTreeVisitor::visit(CharConstASTNode *n) 59 | { 60 | _level++; 61 | printTab(_level); 62 | std::cout << "NK_CHAR_CONST" << std::endl; 63 | printTab(_level); 64 | if (n->getValue() == '\n') 65 | std::cout << "Value: newline character" << std::endl; 66 | else 67 | std::cout << "Value: " << (char) n->getValue() << std::endl; 68 | _level--; 69 | } 70 | 71 | void PrintTreeVisitor::visit(SizeOfExprASTNode *n) 72 | { 73 | _level++; 74 | printTab(_level); 75 | std::cout << "NK_SIZEOF_EXPR" << std::endl; 76 | if (n->getExpr() != NULL_AST_NODE) 77 | { 78 | printTab(_level); 79 | std::cout << "Expression:" << std::endl; 80 | n->getExpr()->accept(this); 81 | } 82 | _level--; 83 | } 84 | 85 | void PrintTreeVisitor::visit(TypeDeclASTNode *n) 86 | { 87 | _level++; 88 | printTab(_level); 89 | std::cout << "NK_TYPE_DECL" << std::endl; 90 | if (n->getName() != NULL_AST_NODE) 91 | { 92 | printTab(_level); 93 | std::cout << "Type name:" << std::endl; 94 | n->getName()->accept(this); 95 | } 96 | if (n->getBody() != NULL_AST_NODE) 97 | { 98 | printTab(_level); 99 | std::cout << "Body:" << std::endl; 100 | n->getBody()->accept(this); 101 | } 102 | _level--; 103 | } 104 | 105 | void PrintTreeVisitor::visit(FunctionDeclASTNode *n) 106 | { 107 | _level++; 108 | printTab(_level); 109 | std::cout << "NK_FUNCTION_DECL" << std::endl; 110 | if (n->getName() != NULL_AST_NODE) 111 | { 112 | printTab(_level); 113 | std::cout << "Function name:" << std::endl; 114 | n->getName()->accept(this); 115 | } 116 | if (n->getType() != NULL_AST_NODE) 117 | { 118 | printTab(_level); 119 | std::cout << "Type:" << std::endl; 120 | n->getType()->accept(this); 121 | } 122 | if (n->getPrms() != NULL_AST_NODE) 123 | { 124 | printTab(_level); 125 | std::cout << "Parameters:" << std::endl; 126 | n->getPrms()->accept(this); 127 | } 128 | if (n->getBody() != NULL_AST_NODE) 129 | { 130 | printTab(_level); 131 | std::cout << "Body:" << std::endl; 132 | n->getBody()->accept(this); 133 | } 134 | _level--; 135 | } 136 | 137 | void PrintTreeVisitor::visit(VarDeclASTNode *n) 138 | { 139 | _level++; 140 | printTab(_level); 141 | std::cout << "NK_VAR_DECL" << std::endl; 142 | if (n->getName() != NULL_AST_NODE) 143 | { 144 | printTab(_level); 145 | std::cout << "Name:" << std::endl; 146 | n->getName()->accept(this); 147 | } 148 | if (n->getType() != NULL_AST_NODE) 149 | { 150 | printTab(_level); 151 | std::cout << "Type:" << std::endl; 152 | n->getType()->accept(this); 153 | } 154 | if (n->getInit() != NULL_AST_NODE) 155 | { 156 | printTab(_level); 157 | std::cout << "Init:" << std::endl; 158 | n->getInit()->accept(this); 159 | } 160 | _level--; 161 | } 162 | 163 | void PrintTreeVisitor::visit(ParmDeclASTNode *n) 164 | { 165 | _level++; 166 | printTab(_level); 167 | std::cout << "NK_PARM_DECL" << std::endl; 168 | if (n->getName() != NULL_AST_NODE) 169 | { 170 | printTab(_level); 171 | std::cout << "Name:" << std::endl; 172 | n->getName()->accept(this); 173 | } 174 | if (n->getType() != NULL_AST_NODE) 175 | { 176 | printTab(_level); 177 | std::cout << "Type:" << std::endl; 178 | n->getType()->accept(this); 179 | } 180 | _level--; 181 | } 182 | 183 | void PrintTreeVisitor::visit(FieldDeclASTNode *n) 184 | { 185 | _level++; 186 | printTab(_level); 187 | std::cout << "NK_FIELD_DECL" << std::endl; 188 | if (n->getName() != NULL_AST_NODE) 189 | { 190 | printTab(_level); 191 | std::cout << "Name:" << std::endl; 192 | n->getName()->accept(this); 193 | } 194 | if (n->getType() != NULL_AST_NODE) 195 | { 196 | printTab(_level); 197 | std::cout << "Type:" << std::endl; 198 | n->getType()->accept(this); 199 | } 200 | _level--; 201 | } 202 | 203 | void PrintTreeVisitor::visit(AsmStmtASTNode *n) 204 | { 205 | printTab(_level + 1); 206 | std::cout << "NK_ASM_STMT" << std::endl; 207 | printTab(_level + 1); 208 | std::cout << "Data:" << std::endl; 209 | printTab(_level + 2); 210 | std::cout << n->getData() << std::endl; 211 | } 212 | 213 | void PrintTreeVisitor::visit(BreakStmtASTNode *n) 214 | { 215 | printTab(_level + 1); 216 | std::cout << "NK_BREAK_STMT" << std::endl; 217 | } 218 | 219 | void PrintTreeVisitor::visit(CaseLabelASTNode *n) 220 | { 221 | _level++; 222 | printTab(_level); 223 | std::cout << "CASE_LABEL" << std::endl; 224 | if (n->getExpr() != NULL_AST_NODE) 225 | { 226 | printTab(_level); 227 | std::cout << "Expression:" << std::endl; 228 | n->getExpr()->accept(this); 229 | } 230 | if (n->getStmt() != NULL_AST_NODE) 231 | { 232 | printTab(_level); 233 | std::cout << "Statement:" << std::endl; 234 | n->getStmt()->accept(this); 235 | } 236 | _level--; 237 | } 238 | 239 | void PrintTreeVisitor::visit(CompoundStmtASTNode *n) 240 | { 241 | _level++; 242 | printTab(_level); 243 | std::cout << "NK_COMPOUND_STMT" << std::endl; 244 | if (n->getDecls() != NULL_AST_NODE) 245 | { 246 | printTab(_level); 247 | std::cout << "Declarations:" << std::endl; 248 | n->getDecls()->accept(this); 249 | } 250 | if (n->getStmts() != NULL_AST_NODE) 251 | { 252 | printTab(_level); 253 | std::cout << "Statements:" << std::endl; 254 | n->getStmts()->accept(this); 255 | } 256 | _level--; 257 | } 258 | 259 | void PrintTreeVisitor::visit(ContinueStmtASTNode *n) 260 | { 261 | printTab(_level + 1); 262 | std::cout << "NK_CONTINUE_STMT" << std::endl; 263 | } 264 | 265 | void PrintTreeVisitor::visit(DoStmtASTNode *n) 266 | { 267 | _level++; 268 | printTab(_level); 269 | std::cout << "NK_DO_STMT" << std::endl; 270 | if (n->getCondition() != NULL_AST_NODE) 271 | { 272 | printTab(_level); 273 | std::cout << "condition:" << std::endl; 274 | n->getCondition()->accept(this); 275 | } 276 | if (n->getBody() != NULL_AST_NODE) 277 | { 278 | printTab(_level); 279 | std::cout << "body:" << std::endl; 280 | n->getBody()->accept(this); 281 | } 282 | _level--; 283 | } 284 | 285 | void PrintTreeVisitor::visit(ForStmtASTNode *n) 286 | { 287 | _level++; 288 | printTab(_level); 289 | std::cout << "NK_FOR_STMT" << std::endl; 290 | if (n->getInit() != NULL_AST_NODE) 291 | { 292 | printTab(_level); 293 | std::cout << "Init:" << std::endl; 294 | n->getInit()->accept(this); 295 | } 296 | if (n->getCondition() != NULL_AST_NODE) 297 | { 298 | printTab(_level); 299 | std::cout << "Condition:" << std::endl; 300 | n->getCondition()->accept(this); 301 | } 302 | if (n->getStep() != NULL_AST_NODE) 303 | { 304 | printTab(_level); 305 | std::cout << "Step:" << std::endl; 306 | n->getStep()->accept(this); 307 | } 308 | if (n->getBody() != NULL_AST_NODE) 309 | { 310 | printTab(_level); 311 | std::cout << "Body:" << std::endl; 312 | n->getBody()->accept(this); 313 | } 314 | _level--; 315 | } 316 | 317 | void PrintTreeVisitor::visit(GotoStmtASTNode *n) 318 | { 319 | // 320 | } 321 | 322 | void PrintTreeVisitor::visit(IfStmtASTNode *n) 323 | { 324 | _level++; 325 | printTab(_level); 326 | std::cout << "NK_IF_STMT" << std::endl; 327 | if (n->getCondition() != NULL_AST_NODE) 328 | { 329 | printTab(_level); 330 | std::cout << "Condition:" << std::endl; 331 | n->getCondition()->accept(this); 332 | } 333 | if (n->getThenClause() != NULL_AST_NODE) 334 | { 335 | printTab(_level); 336 | std::cout << "If clause:" << std::endl; 337 | n->getThenClause()->accept(this); 338 | } 339 | if (n->getElseClause() != NULL_AST_NODE) 340 | { 341 | printTab(_level); 342 | std::cout << "Else clause:" << std::endl; 343 | n->getElseClause()->accept(this); 344 | } 345 | _level--; 346 | } 347 | 348 | void PrintTreeVisitor::visit(LabelStmtASTNode *n) 349 | { 350 | _level++; 351 | printTab(_level); 352 | std::cout << "LABEL_STMT" << std::endl; 353 | if (n->getLabel() != NULL_AST_NODE) 354 | { 355 | printTab(_level); 356 | std::cout << "Label:" << std::endl; 357 | n->getLabel()->accept(this); 358 | } 359 | if (n->getStmt() != NULL_AST_NODE) 360 | { 361 | printTab(_level); 362 | std::cout << "Statement:" << std::endl; 363 | n->getStmt()->accept(this); 364 | } 365 | _level--; 366 | } 367 | 368 | void PrintTreeVisitor::visit(ReturnStmtASTNode *n) 369 | { 370 | _level++; 371 | printTab(_level); 372 | std::cout << "RETURN_STMT" << std::endl; 373 | if (n->getExpr() != NULL_AST_NODE) 374 | { 375 | printTab(_level); 376 | std::cout << "Expression:" << std::endl; 377 | n->getExpr()->accept(this); 378 | } 379 | _level--; 380 | } 381 | 382 | void PrintTreeVisitor::visit(SwitchStmtASTNode *n) 383 | { 384 | _level++; 385 | printTab(_level); 386 | std::cout << "SWITCH_STMT" << std::endl; 387 | if (n->getExpr() != NULL_AST_NODE) 388 | { 389 | printTab(_level); 390 | std::cout << "Expression:" << std::endl; 391 | n->getExpr()->accept(this); 392 | } 393 | if (n->getStmt() != NULL_AST_NODE) 394 | { 395 | printTab(_level); 396 | std::cout << "Statement:" << std::endl; 397 | n->getStmt()->accept(this); 398 | } 399 | _level--; 400 | } 401 | 402 | void PrintTreeVisitor::visit(WhileStmtASTNode *n) 403 | { 404 | _level++; 405 | printTab(_level); 406 | std::cout << "WHILE_STMT" << std::endl; 407 | if (n->getCondition() != NULL_AST_NODE) 408 | { 409 | printTab(_level); 410 | std::cout << "Condition:" << std::endl; 411 | n->getCondition()->accept(this); 412 | } 413 | if (n->getBody() != NULL_AST_NODE) 414 | { 415 | printTab(_level); 416 | std::cout << "Body:" << std::endl; 417 | n->getBody()->accept(this); 418 | } 419 | _level--; 420 | } 421 | 422 | void PrintTreeVisitor::visit(CastExprASTNode *n) 423 | { 424 | _level++; 425 | printTab(_level); 426 | std::cout << "NK_CAST_EXPR" << std::endl; 427 | if (n->getExpr() != NULL_AST_NODE) 428 | { 429 | printTab(_level); 430 | std::cout << "Expression:" << std::endl; 431 | n->getExpr()->accept(this); 432 | } 433 | if (n->getType() != NULL_AST_NODE) 434 | { 435 | printTab(_level); 436 | std::cout << "Type:" << std::endl; 437 | n->getType()->accept(this); 438 | } 439 | _level--; 440 | } 441 | 442 | void PrintTreeVisitor::visit(BitNotExprASTNode *n) 443 | { 444 | _level++; 445 | printTab(_level); 446 | std::cout << "NK_BIT_NOT_EXPR" << std::endl; 447 | if (n->getExpr() != NULL_AST_NODE) 448 | { 449 | printTab(_level); 450 | std::cout << "Expression:" << std::endl; 451 | n->getExpr()->accept(this); 452 | } 453 | _level--; 454 | } 455 | 456 | void PrintTreeVisitor::visit(LogNotExprASTNode *n) 457 | { 458 | _level++; 459 | printTab(_level); 460 | std::cout << "NK_LOG_NOT_EXPR" << std::endl; 461 | printTab(_level); 462 | std::cout << "Expression:" << std::endl; 463 | n->getExpr()->accept(this); 464 | _level--; 465 | } 466 | 467 | void PrintTreeVisitor::visit(PredecrementExprASTNode *n) 468 | { 469 | // TODO: Implement. 470 | } 471 | 472 | void PrintTreeVisitor::visit(PreincrementExprASTNode *n) 473 | { 474 | // TODO: Implement. 475 | } 476 | 477 | void PrintTreeVisitor::visit(PostdecrementExprASTNode *n) 478 | { 479 | _level++; 480 | printTab(_level); 481 | std::cout << "NK_POSTDECREMENT_EXPR" << std::endl; 482 | printTab(_level); 483 | std::cout << "Expression:" << std::endl; 484 | n->getExpr()->accept(this); 485 | _level--; 486 | } 487 | 488 | void PrintTreeVisitor::visit(PostincrementExprASTNode *n) 489 | { 490 | _level++; 491 | printTab(_level); 492 | std::cout << "NK_POSTINCREMENT_EXPR" << std::endl; 493 | printTab(_level); 494 | std::cout << "Expression:" << std::endl; 495 | n->getExpr()->accept(this); 496 | _level--; 497 | } 498 | 499 | void PrintTreeVisitor::visit(AddrExprASTNode *n) 500 | { 501 | _level++; 502 | printTab(_level); 503 | std::cout << "NK_ADDR_EXPR" << std::endl; 504 | printTab(_level); 505 | std::cout << "Expression:" << std::endl; 506 | n->getExpr()->accept(this); 507 | _level--; 508 | } 509 | 510 | void PrintTreeVisitor::visit(IndirectRefASTNode *n) 511 | { 512 | _level++; 513 | printTab(_level); 514 | std::cout << "NK_INDIRECT_REF" << std::endl; 515 | if (n->getExpr() != NULL_AST_NODE) 516 | { 517 | printTab(_level); 518 | std::cout << "Expression:" << std::endl; 519 | n->getExpr()->accept(this); 520 | } 521 | if (n->getField() != NULL_AST_NODE) 522 | { 523 | printTab(_level); 524 | std::cout << "Field:" << std::endl; 525 | n->getField()->accept(this); 526 | } 527 | if (n->getType() != NULL_AST_NODE) 528 | { 529 | printTab(_level); 530 | std::cout << "Type:" << std::endl; 531 | n->getType()->accept(this); 532 | } 533 | _level--; 534 | } 535 | 536 | void PrintTreeVisitor::visit(NopExprASTNode *n) 537 | { 538 | _level++; 539 | printTab(_level); 540 | std::cout << "NK_NOP_EXPR" << std::endl; 541 | _level--; 542 | } 543 | 544 | void PrintTreeVisitor::visit(LShiftExprASTNode *n) 545 | { 546 | _level++; 547 | 548 | printTab(_level); 549 | std::cout << "NK_LSHIFT_EXPR" << std::endl; 550 | 551 | printTab(_level); 552 | std::cout << "Lhs:" << std::endl; 553 | n->getLhs()->accept(this); 554 | 555 | printTab(_level); 556 | std::cout << "Rhs:" << std::endl; 557 | n->getRhs()->accept(this); 558 | 559 | _level--; 560 | } 561 | 562 | void PrintTreeVisitor::visit(RShiftExprASTNode *n) 563 | { 564 | _level++; 565 | 566 | printTab(_level); 567 | std::cout << "NK_RSHIFT_EXPR" << std::endl; 568 | 569 | printTab(_level); 570 | std::cout << "Lhs:" << std::endl; 571 | n->getLhs()->accept(this); 572 | 573 | printTab(_level); 574 | std::cout << "Rhs:" << std::endl; 575 | n->getRhs()->accept(this); 576 | 577 | _level--; 578 | } 579 | 580 | void PrintTreeVisitor::visit(BitIorExprASTNode *n) 581 | { 582 | _level++; 583 | 584 | printTab(_level); 585 | std::cout << "NK_BIT_IOR_EXPR" << std::endl; 586 | 587 | printTab(_level); 588 | std::cout << "Lhs:" << std::endl; 589 | n->getLhs()->accept(this); 590 | 591 | printTab(_level); 592 | std::cout << "Rhs:" << std::endl; 593 | n->getRhs()->accept(this); 594 | 595 | _level--; 596 | } 597 | 598 | void PrintTreeVisitor::visit(BitXorExprASTNode *n) 599 | { 600 | _level++; 601 | 602 | printTab(_level); 603 | std::cout << "NK_BIT_XOR_EXPR" << std::endl; 604 | 605 | printTab(_level); 606 | std::cout << "Lhs:" << std::endl; 607 | n->getLhs()->accept(this); 608 | 609 | printTab(_level); 610 | std::cout << "Rhs:" << std::endl; 611 | n->getRhs()->accept(this); 612 | 613 | _level--; 614 | } 615 | 616 | void PrintTreeVisitor::visit(BitAndExprASTNode *n) 617 | { 618 | _level++; 619 | 620 | printTab(_level); 621 | std::cout << "NK_BIT_AND_EXPR" << std::endl; 622 | 623 | printTab(_level); 624 | std::cout << "Lhs:" << std::endl; 625 | n->getLhs()->accept(this); 626 | 627 | printTab(_level); 628 | std::cout << "Rhs:" << std::endl; 629 | n->getRhs()->accept(this); 630 | 631 | _level--; 632 | } 633 | 634 | void PrintTreeVisitor::visit(LogAndExprASTNode *n) 635 | { 636 | _level++; 637 | 638 | printTab(_level); 639 | std::cout << "NK_LOG_AND_EXPR" << std::endl; 640 | 641 | printTab(_level); 642 | std::cout << "Lhs:" << std::endl; 643 | n->getLhs()->accept(this); 644 | 645 | printTab(_level); 646 | std::cout << "Rhs:" << std::endl; 647 | n->getRhs()->accept(this); 648 | 649 | _level--; 650 | } 651 | 652 | void PrintTreeVisitor::visit(LogOrExprASTNode *n) 653 | { 654 | _level++; 655 | 656 | printTab(_level); 657 | std::cout << "NK_LOG_OR_EXPR" << std::endl; 658 | 659 | printTab(_level); 660 | std::cout << "Lhs:" << std::endl; 661 | n->getLhs()->accept(this); 662 | 663 | printTab(_level); 664 | std::cout << "Rhs:" << std::endl; 665 | n->getRhs()->accept(this); 666 | 667 | _level--; 668 | } 669 | 670 | void PrintTreeVisitor::visit(PlusExprASTNode *n) 671 | { 672 | _level++; 673 | 674 | printTab(_level); 675 | std::cout << "NK_PLUS_EXPR" << std::endl; 676 | 677 | printTab(_level); 678 | std::cout << "Lhs:" << std::endl; 679 | n->getLhs()->accept(this); 680 | 681 | printTab(_level); 682 | std::cout << "Rhs:" << std::endl; 683 | n->getRhs()->accept(this); 684 | 685 | _level--; 686 | } 687 | 688 | void PrintTreeVisitor::visit(MinusExprASTNode *n) 689 | { 690 | _level++; 691 | 692 | printTab(_level); 693 | std::cout << "NK_MINUS_EXPR" << std::endl; 694 | 695 | printTab(_level); 696 | std::cout << "Lhs:" << std::endl; 697 | n->getLhs()->accept(this); 698 | 699 | printTab(_level); 700 | std::cout << "Rhs:" << std::endl; 701 | n->getRhs()->accept(this); 702 | 703 | _level--; 704 | } 705 | 706 | void PrintTreeVisitor::visit(MultExprASTNode *n) 707 | { 708 | _level++; 709 | 710 | printTab(_level); 711 | std::cout << "NK_MULT_EXPR" << std::endl; 712 | 713 | printTab(_level); 714 | std::cout << "Lhs:" << std::endl; 715 | n->getLhs()->accept(this); 716 | 717 | printTab(_level); 718 | std::cout << "Rhs:" << std::endl; 719 | n->getRhs()->accept(this); 720 | 721 | _level--; 722 | } 723 | 724 | void PrintTreeVisitor::visit(TruncDivExprASTNode *n) 725 | { 726 | _level++; 727 | 728 | printTab(_level); 729 | std::cout << "NK_TRUNC_DIV_EXPR" << std::endl; 730 | 731 | printTab(_level); 732 | std::cout << "Lhs:" << std::endl; 733 | n->getLhs()->accept(this); 734 | 735 | printTab(_level); 736 | std::cout << "Rhs:" << std::endl; 737 | n->getRhs()->accept(this); 738 | 739 | _level--; 740 | } 741 | 742 | void PrintTreeVisitor::visit(TruncModExprASTNode *n) 743 | { 744 | _level++; 745 | 746 | printTab(_level); 747 | std::cout << "NK_TRUNC_MOD_EXPR" << std::endl; 748 | 749 | printTab(_level); 750 | std::cout << "Lhs:" << std::endl; 751 | n->getLhs()->accept(this); 752 | 753 | printTab(_level); 754 | std::cout << "Rhs:" << std::endl; 755 | n->getRhs()->accept(this); 756 | 757 | _level--; 758 | } 759 | 760 | void PrintTreeVisitor::visit(ArrayRefASTNode *n) 761 | { 762 | _level++; 763 | printTab(_level); 764 | std::cout << "ARRAY_REF" << std::endl; 765 | if (n->getExpr() != NULL_AST_NODE) 766 | { 767 | printTab(_level); 768 | std::cout << "Expression:" << std::endl; 769 | n->getExpr()->accept(this); 770 | } 771 | if (n->getIndex() != NULL_AST_NODE) 772 | { 773 | printTab(_level); 774 | std::cout << "Index:" << std::endl; 775 | n->getIndex()->accept(this); 776 | } 777 | if (n->getType() != NULL_AST_NODE) 778 | { 779 | printTab(_level); 780 | std::cout << "Element type:" << std::endl; 781 | n->getType()->accept(this); 782 | } 783 | _level--; 784 | } 785 | 786 | void PrintTreeVisitor::visit(StructRefASTNode *n) 787 | { 788 | _level++; 789 | printTab(_level); 790 | std::cout << "STRUCT_REF" << std::endl; 791 | if (n->getName() != NULL_AST_NODE) 792 | { 793 | printTab(_level); 794 | std::cout << "Name:" << std::endl; 795 | n->getName()->accept(this); 796 | } 797 | if (n->getMember() != NULL_AST_NODE) 798 | { 799 | printTab(_level); 800 | std::cout << "Member:" << std::endl; 801 | n->getMember()->accept(this); 802 | } 803 | _level--; 804 | } 805 | 806 | void PrintTreeVisitor::visit(LtExprASTNode *n) 807 | { 808 | _level++; 809 | 810 | printTab(_level); 811 | std::cout << "NK_LT_EXPR" << std::endl; 812 | 813 | printTab(_level); 814 | std::cout << "Lhs:" << std::endl; 815 | n->getLhs()->accept(this); 816 | 817 | printTab(_level); 818 | std::cout << "Rhs:" << std::endl; 819 | n->getRhs()->accept(this); 820 | 821 | _level--; 822 | } 823 | 824 | void PrintTreeVisitor::visit(LeExprASTNode *n) 825 | { 826 | _level++; 827 | 828 | printTab(_level); 829 | std::cout << "NK_LE_EXPR" << std::endl; 830 | 831 | printTab(_level); 832 | std::cout << "Lhs:" << std::endl; 833 | n->getLhs()->accept(this); 834 | 835 | printTab(_level); 836 | std::cout << "Rhs:" << std::endl; 837 | n->getRhs()->accept(this); 838 | 839 | _level--; 840 | } 841 | 842 | void PrintTreeVisitor::visit(GtExprASTNode *n) 843 | { 844 | _level++; 845 | 846 | printTab(_level); 847 | std::cout << "NK_GT_EXPR" << std::endl; 848 | 849 | printTab(_level); 850 | std::cout << "Lhs:" << std::endl; 851 | n->getLhs()->accept(this); 852 | 853 | printTab(_level); 854 | std::cout << "Rhs:" << std::endl; 855 | n->getRhs()->accept(this); 856 | 857 | _level--; 858 | } 859 | 860 | void PrintTreeVisitor::visit(GeExprASTNode *n) 861 | { 862 | _level++; 863 | 864 | printTab(_level); 865 | std::cout << "NK_GE_EXPR" << std::endl; 866 | 867 | printTab(_level); 868 | std::cout << "Lhs:" << std::endl; 869 | n->getLhs()->accept(this); 870 | 871 | printTab(_level); 872 | std::cout << "Rhs:" << std::endl; 873 | n->getRhs()->accept(this); 874 | 875 | _level--; 876 | } 877 | 878 | void PrintTreeVisitor::visit(EqExprASTNode *n) 879 | { 880 | _level++; 881 | 882 | printTab(_level); 883 | std::cout << "NK_EQ_EXPR" << std::endl; 884 | 885 | printTab(_level); 886 | std::cout << "Lhs:" << std::endl; 887 | n->getLhs()->accept(this); 888 | 889 | printTab(_level); 890 | std::cout << "Rhs:" << std::endl; 891 | n->getRhs()->accept(this); 892 | 893 | _level--; 894 | } 895 | 896 | void PrintTreeVisitor::visit(NeExprASTNode *n) 897 | { 898 | _level++; 899 | 900 | printTab(_level); 901 | std::cout << "NK_NE_EXPR" << std::endl; 902 | 903 | printTab(_level); 904 | std::cout << "Lhs:" << std::endl; 905 | n->getLhs()->accept(this); 906 | 907 | printTab(_level); 908 | std::cout << "Rhs:" << std::endl; 909 | n->getRhs()->accept(this); 910 | 911 | _level--; 912 | } 913 | 914 | void PrintTreeVisitor::visit(AssignExprASTNode *n) 915 | { 916 | _level++; 917 | 918 | printTab(_level); 919 | std::cout << "NK_ASSIGN_EXPR" << std::endl; 920 | 921 | printTab(_level); 922 | std::cout << "Lhs:" << std::endl; 923 | n->getLhs()->accept(this); 924 | 925 | printTab(_level); 926 | std::cout << "Rhs:" << std::endl; 927 | n->getRhs()->accept(this); 928 | 929 | _level--; 930 | } 931 | 932 | void PrintTreeVisitor::visit(CondExprASTNode *n) { /* TODO: Implement. */} 933 | 934 | void PrintTreeVisitor::visit(CallExprASTNode *n) 935 | { 936 | _level++; 937 | printTab(_level); 938 | std::cout << "NK_CALL_EXPR" << std::endl; 939 | if (n->getExpr() != NULL_AST_NODE) 940 | { 941 | printTab(_level); 942 | std::cout << "Function name:" << std::endl; 943 | n->getExpr()->accept(this); 944 | } 945 | if (n->getArgs() != NULL_AST_NODE) 946 | { 947 | printTab(_level); 948 | std::cout << "Actual parameters:" << std::endl; 949 | n->getArgs()->accept(this); 950 | } 951 | _level--; 952 | } 953 | 954 | void PrintTreeVisitor::visit(VoidTypeASTNode *n) 955 | { 956 | _level++; 957 | printTab(_level); 958 | std::cout << "NK_VOID_TYPE" << std::endl; 959 | _level--; 960 | } 961 | 962 | void PrintTreeVisitor::visit(IntegralTypeASTNode *n) 963 | { 964 | _level++; 965 | printTab(_level); 966 | std::cout << "NK_INTEGRAL_TYPE" << std::endl; 967 | printTab(_level); 968 | std::cout << "Alignment: " << n->getAlignment() << std::endl; 969 | printTab(_level); 970 | if (n->getIsSigned()) 971 | std::cout << "Signed: true" << std::endl; 972 | else 973 | std::cout << "Signed: false" << std::endl; 974 | _level--; 975 | } 976 | 977 | void PrintTreeVisitor::visit(RealTypeASTNode *n) 978 | { 979 | _level++; 980 | printTab(_level); 981 | std::cout << "NK_REAL_TYPE" << std::endl; 982 | printTab(_level); 983 | std::cout << "Alignment: " << n->getAlignment() << std::endl; 984 | printTab(_level); 985 | if (n->getIsDouble()) 986 | std::cout << "Double: true" << std::endl; 987 | else 988 | std::cout << "Double: false" << std::endl; 989 | _level--; 990 | } 991 | 992 | void PrintTreeVisitor::visit(EnumeralTypeASTNode *n) 993 | { 994 | _level++; 995 | printTab(_level); 996 | std::cout << "NK_ENUMERAL_TYPE" << std::endl; 997 | if (n->getName() != NULL_AST_NODE) 998 | { 999 | printTab(_level); 1000 | std::cout << "Name:" << std::endl; 1001 | n->getName()->accept(this); 1002 | } 1003 | if (n->getBody() != NULL_AST_NODE) 1004 | { 1005 | printTab(_level); 1006 | std::cout << "Body:" << std::endl; 1007 | n->getBody()->accept(this); 1008 | } 1009 | _level--; 1010 | } 1011 | 1012 | void PrintTreeVisitor::visit(PointerTypeASTNode *n) 1013 | { 1014 | _level++; 1015 | printTab(_level); 1016 | std::cout << "NK_POINTER_TYPE" << std::endl; 1017 | if (n->getBaseType() != NULL_AST_NODE) 1018 | { 1019 | printTab(_level); 1020 | std::cout << "Base type:" << std::endl; 1021 | n->getBaseType()->accept(this); 1022 | } 1023 | _level--; 1024 | } 1025 | 1026 | void PrintTreeVisitor::visit(FunctionTypeASTNode *n) 1027 | { 1028 | _level++; 1029 | printTab(_level); 1030 | std::cout << "NK_FUNCTION_TYPE" << std::endl; 1031 | if (n->getType() != NULL_AST_NODE) 1032 | { 1033 | printTab(_level); 1034 | std::cout << "Type:" << std::endl; 1035 | n->getType()->accept(this); 1036 | } 1037 | if (n->getPrms() != NULL_AST_NODE) 1038 | { 1039 | printTab(_level); 1040 | std::cout << "Parameters:" << std::endl; 1041 | n->getPrms()->accept(this); 1042 | } 1043 | _level--; 1044 | } 1045 | 1046 | void PrintTreeVisitor::visit(ArrayTypeASTNode *n) 1047 | { 1048 | _level++; 1049 | printTab(_level); 1050 | std::cout << "NK_ARRAY_TYPE" << std::endl; 1051 | if (n->getExpr() != NULL_AST_NODE) 1052 | { 1053 | printTab(_level); 1054 | std::cout << "Expression:" << std::endl; 1055 | n->getExpr()->accept(this); 1056 | } 1057 | if (n->getElementType() != NULL_AST_NODE) 1058 | { 1059 | printTab(_level); 1060 | std::cout << "Element type:" << std::endl; 1061 | n->getElementType()->accept(this); 1062 | } 1063 | _level--; 1064 | } 1065 | 1066 | void PrintTreeVisitor::visit(StructTypeASTNode *n) 1067 | { 1068 | _level++; 1069 | printTab(_level); 1070 | std::cout << "NK_STRUCT_TYPE" << std::endl; 1071 | if (n->getName() != NULL_AST_NODE) 1072 | { 1073 | printTab(_level); 1074 | std::cout << "Name:" << std::endl; 1075 | n->getName()->accept(this); 1076 | } 1077 | if (n->getBody() != NULL_AST_NODE) 1078 | { 1079 | printTab(_level); 1080 | std::cout << "Body:" << std::endl; 1081 | n->getBody()->accept(this); 1082 | } 1083 | _level--; 1084 | } 1085 | 1086 | void PrintTreeVisitor::visit(UnionTypeASTNode *n) { /* TODO: Implement. */} 1087 | 1088 | void PrintTreeVisitor::visit(NullASTNode *n) 1089 | { 1090 | printTab(_level + 1); 1091 | std::cout << "NK_UNKNOWN" << std::endl; 1092 | } 1093 | 1094 | void PrintTreeVisitor::visit(SequenceASTNode *n) 1095 | { 1096 | _level++; 1097 | printTab(_level); 1098 | std::cout << "NK_LIST" << std::endl; 1099 | std::vector &elements = n->getElements(); 1100 | 1101 | for (unsigned i = 0; i < elements.size(); i++) 1102 | { 1103 | printTab(_level); 1104 | std::cout << "Element "<< i << ":" << std::endl; 1105 | if (elements[i] != nullptr && elements[i] != NULL_AST_NODE) 1106 | elements[i]->accept(this); 1107 | } 1108 | _level--; 1109 | } 1110 | 1111 | void CountCallExprVisitor::visit(CallExprASTNode *n) { callExprCount++; } 1112 | 1113 | } // namespace cparser 1114 | -------------------------------------------------------------------------------- /src/SymbolTable.cpp: -------------------------------------------------------------------------------- 1 | // Symbol table - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/SymbolTable.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace cparser 16 | { 17 | 18 | STType *SymbolTable::allocType(STTypeKind kind) 19 | { 20 | STType *type = new STType(kind); 21 | typePool.push_back(type); 22 | return type; 23 | } 24 | 25 | STObject * 26 | SymbolTable::allocObject(const char *name, STObjectKind kind, STType *type) 27 | { 28 | STObject *obj = new STObject(name, kind, type); 29 | objectPool.push_back(obj); 30 | return obj; 31 | } 32 | 33 | STScope *SymbolTable::allocScope() 34 | { 35 | STScope *scope = new STScope(); 36 | scopePool.push_back(scope); 37 | return scope; 38 | } 39 | 40 | SymbolTable::SymbolTable() 41 | { 42 | level = -1; 43 | topScope = allocScope(); 44 | topScope->outer = nullptr; 45 | globalScope = topScope; 46 | 47 | // Built-in types 48 | 49 | // char: 1 byte 50 | charType = allocType(STTK_CHAR); 51 | charType->size = 1; 52 | charType->isSigned = true; 53 | 54 | // char: 2 bytes 55 | shortType = allocType(STTK_SHORT); 56 | shortType->size = 2; 57 | shortType->isSigned = true; 58 | 59 | // int: 4 bytes 60 | intType = allocType(STTK_INT); 61 | intType->size = 4; 62 | intType->isSigned = true; 63 | 64 | // int: 4 bytes 65 | unsignedType = allocType(STTK_UNSIGNED); 66 | unsignedType->size = 4; 67 | unsignedType->isSigned = false; 68 | 69 | // int: 4 bytes 70 | longType = allocType(STTK_LONG); 71 | longType->size = 4; 72 | longType->isSigned = true; 73 | 74 | // float: 4 bytes 75 | floatType = allocType(STTK_FLOAT); 76 | floatType->size = 4; 77 | 78 | // double: 8 bytes 79 | doubleType = allocType(STTK_DOUBLE); 80 | doubleType->size = 8; 81 | 82 | // int: 4 bytes 83 | voidType = allocType(STTK_VOID); 84 | voidType->size = 4; 85 | 86 | noType = allocType(STTK_NONE); 87 | insert("NOTYPE", STOK_TYPE, noType); 88 | 89 | nullType = allocType(STTK_POINTER); 90 | 91 | // Dummy object 92 | noObj = allocObject("noObj", STOK_VAR, noType); 93 | 94 | // Built in types 95 | insert("__builtin_va_list", STOK_TYPE, noType); 96 | } 97 | 98 | SymbolTable::~SymbolTable() 99 | { 100 | for (unsigned i = 0; i < scopePool.size(); i++) 101 | delete scopePool[i]; 102 | 103 | for (unsigned i = 0; i < objectPool.size(); i++) 104 | delete objectPool[i]; 105 | 106 | for (unsigned i = 0; i < typePool.size(); i++) 107 | delete typePool[i]; 108 | } 109 | 110 | STObject *SymbolTable::insert(const char *name, STObjectKind kind, STType *type) 111 | { 112 | // Create object node 113 | STObject *obj = allocObject(name, kind, type); 114 | STObject *p = nullptr, *last = nullptr; 115 | 116 | if (kind == STOK_VAR) 117 | topScope->nVars++; 118 | else if (kind == STOK_PAR) 119 | topScope->nPars++; 120 | 121 | obj->level = level; 122 | 123 | // Append object node 124 | p = topScope->locals; 125 | last = nullptr; 126 | while (p != nullptr) 127 | { 128 | if (strcmp(p->name, name) == 0) 129 | return noObj; 130 | last = p; 131 | p = p->next; 132 | } 133 | 134 | if (last == nullptr) 135 | topScope->locals = obj; 136 | else 137 | last->next = obj; 138 | 139 | return obj; 140 | } 141 | 142 | STObject *SymbolTable::find(const char *name) 143 | { 144 | for (STScope *s = topScope; s != nullptr; s = s->outer) 145 | for (STObject *p = s->locals; p != nullptr; p = p->next) 146 | if (strcmp(p->name, name) == 0) 147 | return p; 148 | 149 | return noObj; 150 | } 151 | 152 | void SymbolTable::openScope(void) 153 | { 154 | STScope *s = allocScope(); 155 | 156 | s->outer = topScope; 157 | topScope = s; 158 | topScope->size = 0; 159 | level++; 160 | } 161 | 162 | void SymbolTable::closeScope(void) 163 | { 164 | topScope = topScope->outer; 165 | level--; 166 | } 167 | 168 | void SymbolTable::setTopScope(STScope *s) { topScope = s; } 169 | 170 | STScope *SymbolTable::getTopScope() { return topScope; } 171 | 172 | bool SymbolTable::isIntegralType(STType *t) 173 | { 174 | assert(t != nullptr && "Unexpected null pointer!"); 175 | 176 | return (t == charType || t == intType || t == unsignedType || 177 | t == shortType || t == longType); 178 | } 179 | 180 | bool SymbolTable::isRealType(STType *t) 181 | { 182 | assert(t != nullptr && "Unexpected null pointer!"); 183 | 184 | return (t == floatType || t == doubleType); 185 | } 186 | 187 | bool SymbolTable::isArithmeticType(STType *t) 188 | { 189 | assert(t != nullptr && "Unexpected null pointer!"); 190 | 191 | return (isIntegralType(t) || isRealType(t)); 192 | } 193 | 194 | bool SymbolTable::isPointerType(STType *t) 195 | { 196 | assert(t != nullptr && "Unexpected null pointer!"); 197 | 198 | return t->kind == STTK_POINTER; 199 | } 200 | 201 | bool SymbolTable::isScalarType(STType *t) 202 | { 203 | return isPointerType(t) || isArithmeticType(t); 204 | } 205 | 206 | bool SymbolTable::isFunctionPointerType(STType *t) 207 | { 208 | return t->kind == STTK_POINTER && 209 | t->baseType->kind == STTK_FUNCTION; 210 | } 211 | 212 | bool SymbolTable::equalFunctionPointerTypes(STType *t1, STType *t2) 213 | { 214 | // TODO: Check if parameters of the function types match. 215 | return (isFunctionPointerType(t1) && isFunctionPointerType(t2) && 216 | (t1->baseType->funcType == t2->baseType->funcType)); 217 | } 218 | 219 | bool SymbolTable::equalBasePointerTypes(STType *t1, STType *t2) 220 | { 221 | return (t1->kind == STTK_POINTER && t2->kind == STTK_POINTER && 222 | (t1->baseType == t2->baseType)); 223 | } 224 | 225 | // Two pointer types with the same type qualifiers are compatible if they 226 | // point to objects of compatible type. The composite type for two compatible 227 | // pointer types is the similarly qualified pointer to the composite type. 228 | 229 | bool SymbolTable::compatible(STType *t1, STType *t2) 230 | { 231 | assert(t1 != nullptr && t2 == nullptr && "Unexpected null pointer!"); 232 | 233 | return ((t1 == t2) || (isIntegralType(t1) && isIntegralType(t2)) || 234 | (isIntegralType(t1) && t2->kind == STTK_POINTER) || 235 | (isIntegralType(t2) && t1->kind == STTK_POINTER) || 236 | (t1->kind == STTK_POINTER && t2->baseType == noType) || 237 | (t2->kind == STTK_POINTER && t1->baseType == noType) || 238 | ((t1->kind == STTK_POINTER && t2->kind == STTK_POINTER) && 239 | compatible(t1->baseType, t2->baseType))); 240 | } 241 | 242 | bool SymbolTable::assignable(STType *t1, STType *t2) 243 | { 244 | assert(t1 != nullptr && t2 == nullptr && "Unexpected null pointer!"); 245 | 246 | return ((isArithmeticType(t1) && isArithmeticType(t2)) || 247 | (t1->kind == STTK_POINTER && t2->baseType == noType) || 248 | (t2->kind == STTK_POINTER && t1->baseType == noType) || 249 | ((t1->kind == STTK_POINTER && t2->kind == STTK_POINTER) && 250 | (t1->baseType == t2->baseType))); 251 | } 252 | 253 | bool SymbolTable::convertible(STType *t1, STType *t2) { return true; } 254 | 255 | } // namespace cparser 256 | -------------------------------------------------------------------------------- /src/TreeVisitor.cpp: -------------------------------------------------------------------------------- 1 | // Tree visitor - implementation file. 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include "../include/TreeVisitor.h" 9 | #include "../include/ASTNode.h" 10 | 11 | namespace cparser 12 | { 13 | 14 | void TreeVisitor::visit(IdentASTNode *n) {} 15 | void TreeVisitor::visit(IntegerConstASTNode *n) {} 16 | void TreeVisitor::visit(RealConstASTNode *n) {} 17 | void TreeVisitor::visit(StringConstASTNode *n) {} 18 | void TreeVisitor::visit(CharConstASTNode *n) {} 19 | 20 | void TreeVisitor::visit(SizeOfExprASTNode *n) { n->getExpr()->accept(this); } 21 | void TreeVisitor::visit(AlignOfExprASTNode *n) { n->getExpr()->accept(this); } 22 | 23 | void TreeVisitor::visit(TypeDeclASTNode *n) 24 | { 25 | n->getName()->accept(this); 26 | n->getBody()->accept(this); 27 | } 28 | 29 | void TreeVisitor::visit(FunctionDeclASTNode *n) 30 | { 31 | n->getName()->accept(this); 32 | n->getType()->accept(this); 33 | n->getPrms()->accept(this); 34 | n->getBody()->accept(this); 35 | } 36 | 37 | void TreeVisitor::visit(VarDeclASTNode *n) 38 | { 39 | n->getName()->accept(this); 40 | n->getType()->accept(this); 41 | n->getInit()->accept(this); 42 | } 43 | 44 | void TreeVisitor::visit(ParmDeclASTNode *n) 45 | { 46 | n->getName()->accept(this); 47 | n->getType()->accept(this); 48 | } 49 | 50 | void TreeVisitor::visit(FieldDeclASTNode *n) 51 | { 52 | n->getName()->accept(this); 53 | n->getType()->accept(this); 54 | } 55 | 56 | void TreeVisitor::visit(AsmStmtASTNode *n) {} 57 | 58 | void TreeVisitor::visit(BreakStmtASTNode *n) {} 59 | 60 | void TreeVisitor::visit(CaseLabelASTNode *n) 61 | { 62 | n->getExpr()->accept(this); 63 | n->getStmt()->accept(this); 64 | } 65 | 66 | void TreeVisitor::visit(CompoundStmtASTNode *n) 67 | { 68 | n->getDecls()->accept(this); 69 | n->getStmts()->accept(this); 70 | } 71 | 72 | void TreeVisitor::visit(ContinueStmtASTNode *n) {} 73 | 74 | void TreeVisitor::visit(DoStmtASTNode *n) 75 | { 76 | n->getCondition()->accept(this); 77 | n->getBody()->accept(this); 78 | } 79 | 80 | void TreeVisitor::visit(ForStmtASTNode *n) 81 | { 82 | n->getInit()->accept(this); 83 | n->getCondition()->accept(this); 84 | n->getBody()->accept(this); 85 | n->getStep()->accept(this); 86 | } 87 | 88 | void TreeVisitor::visit(GotoStmtASTNode *n) {} 89 | 90 | void TreeVisitor::visit(IfStmtASTNode *n) 91 | { 92 | n->getCondition()->accept(this); 93 | n->getThenClause()->accept(this); 94 | n->getElseClause()->accept(this); 95 | } 96 | 97 | void TreeVisitor::visit(LabelStmtASTNode *n) 98 | { 99 | n->getLabel()->accept(this); 100 | n->getStmt()->accept(this); 101 | } 102 | 103 | void TreeVisitor::visit(ReturnStmtASTNode *n) { n->getExpr()->accept(this); } 104 | 105 | void TreeVisitor::visit(SwitchStmtASTNode *n) 106 | { 107 | n->getExpr()->accept(this); 108 | n->getStmt()->accept(this); 109 | } 110 | 111 | void TreeVisitor::visit(WhileStmtASTNode *n) 112 | { 113 | n->getCondition()->accept(this); 114 | n->getBody()->accept(this); 115 | } 116 | 117 | void TreeVisitor::visit(CastExprASTNode *n) { n->getExpr()->accept(this); } 118 | 119 | void TreeVisitor::visit(BitNotExprASTNode *n) { n->getExpr()->accept(this); } 120 | 121 | void TreeVisitor::visit(LogNotExprASTNode *n) {} 122 | 123 | void TreeVisitor::visit(PredecrementExprASTNode *n) 124 | { 125 | n->getExpr()->accept(this); 126 | } 127 | 128 | void TreeVisitor::visit(PreincrementExprASTNode *n) 129 | { 130 | n->getExpr()->accept(this); 131 | } 132 | 133 | void TreeVisitor::visit(PostdecrementExprASTNode *n) 134 | { 135 | n->getExpr()->accept(this); 136 | } 137 | 138 | void TreeVisitor::visit(PostincrementExprASTNode *n) 139 | { 140 | n->getExpr()->accept(this); 141 | } 142 | 143 | void TreeVisitor::visit(AddrExprASTNode *n) { n->getExpr()->accept(this); } 144 | 145 | void TreeVisitor::visit(IndirectRefASTNode *n) {} 146 | 147 | void TreeVisitor::visit(NopExprASTNode *n) {} 148 | 149 | void TreeVisitor::visit(LShiftExprASTNode *n) 150 | { 151 | n->getLhs()->accept(this); 152 | n->getRhs()->accept(this); 153 | } 154 | 155 | void TreeVisitor::visit(RShiftExprASTNode *n) 156 | { 157 | n->getLhs()->accept(this); 158 | n->getRhs()->accept(this); 159 | } 160 | 161 | void TreeVisitor::visit(BitIorExprASTNode *n) 162 | { 163 | n->getLhs()->accept(this); 164 | n->getRhs()->accept(this); 165 | } 166 | 167 | void TreeVisitor::visit(BitXorExprASTNode *n) 168 | { 169 | n->getLhs()->accept(this); 170 | n->getRhs()->accept(this); 171 | } 172 | 173 | void TreeVisitor::visit(BitAndExprASTNode *n) 174 | { 175 | n->getLhs()->accept(this); 176 | n->getRhs()->accept(this); 177 | } 178 | 179 | void TreeVisitor::visit(LogAndExprASTNode *n) 180 | { 181 | n->getLhs()->accept(this); 182 | n->getRhs()->accept(this); 183 | } 184 | 185 | void TreeVisitor::visit(LogOrExprASTNode *n) 186 | { 187 | n->getLhs()->accept(this); 188 | n->getRhs()->accept(this); 189 | } 190 | 191 | void TreeVisitor::visit(PlusExprASTNode *n) 192 | { 193 | n->getLhs()->accept(this); 194 | n->getRhs()->accept(this); 195 | } 196 | 197 | void TreeVisitor::visit(MinusExprASTNode *n) 198 | { 199 | n->getLhs()->accept(this); 200 | n->getRhs()->accept(this); 201 | } 202 | 203 | void TreeVisitor::visit(MultExprASTNode *n) 204 | { 205 | n->getLhs()->accept(this); 206 | n->getRhs()->accept(this); 207 | } 208 | 209 | void TreeVisitor::visit(TruncDivExprASTNode *n) 210 | { 211 | n->getLhs()->accept(this); 212 | n->getRhs()->accept(this); 213 | } 214 | 215 | void TreeVisitor::visit(TruncModExprASTNode *n) 216 | { 217 | n->getLhs()->accept(this); 218 | n->getRhs()->accept(this); 219 | } 220 | 221 | void TreeVisitor::visit(ArrayRefASTNode *n) {} 222 | void TreeVisitor::visit(StructRefASTNode *n) {} 223 | 224 | void TreeVisitor::visit(LtExprASTNode *n) 225 | { 226 | n->getLhs()->accept(this); 227 | n->getRhs()->accept(this); 228 | } 229 | 230 | void TreeVisitor::visit(LeExprASTNode *n) 231 | { 232 | n->getLhs()->accept(this); 233 | n->getRhs()->accept(this); 234 | } 235 | 236 | void TreeVisitor::visit(GtExprASTNode *n) 237 | { 238 | n->getLhs()->accept(this); 239 | n->getRhs()->accept(this); 240 | } 241 | 242 | void TreeVisitor::visit(GeExprASTNode *n) 243 | { 244 | n->getLhs()->accept(this); 245 | n->getRhs()->accept(this); 246 | } 247 | 248 | void TreeVisitor::visit(EqExprASTNode *n) 249 | { 250 | n->getLhs()->accept(this); 251 | n->getRhs()->accept(this); 252 | } 253 | 254 | void TreeVisitor::visit(NeExprASTNode *n) 255 | { 256 | n->getLhs()->accept(this); 257 | n->getRhs()->accept(this); 258 | } 259 | 260 | void TreeVisitor::visit(AssignExprASTNode *n) 261 | { 262 | n->getLhs()->accept(this); 263 | n->getRhs()->accept(this); 264 | } 265 | 266 | void TreeVisitor::visit(CondExprASTNode *n) {} 267 | 268 | void TreeVisitor::visit(CallExprASTNode *n) 269 | { 270 | n->getExpr()->accept(this); 271 | n->getArgs()->accept(this); 272 | } 273 | 274 | void TreeVisitor::visit(VoidTypeASTNode *n) {} 275 | void TreeVisitor::visit(IntegralTypeASTNode *n) {} 276 | void TreeVisitor::visit(RealTypeASTNode *n) {} 277 | 278 | void TreeVisitor::visit(EnumeralTypeASTNode *n) 279 | { 280 | n->getName()->accept(this); 281 | n->getBody()->accept(this); 282 | } 283 | 284 | void TreeVisitor::visit(PointerTypeASTNode *n) 285 | { 286 | n->getBaseType()->accept(this); 287 | } 288 | 289 | void TreeVisitor::visit(FunctionTypeASTNode *n) 290 | { 291 | n->getType()->accept(this); 292 | n->getPrms()->accept(this); 293 | } 294 | 295 | void TreeVisitor::visit(ArrayTypeASTNode *n) {} 296 | 297 | void TreeVisitor::visit(StructTypeASTNode *n) 298 | { 299 | n->getName()->accept(this); 300 | n->getBody()->accept(this); 301 | } 302 | 303 | void TreeVisitor::visit(UnionTypeASTNode *n) {} 304 | void TreeVisitor::visit(NullASTNode *n) {} 305 | 306 | void TreeVisitor::visit(SequenceASTNode *n) 307 | { 308 | std::vector elements = n->getElements(); 309 | for (unsigned i = 0; i < elements.size(); i++) 310 | elements[i]->accept(this); 311 | } 312 | 313 | } // namespace cparser 314 | -------------------------------------------------------------------------------- /src/cformat.cpp: -------------------------------------------------------------------------------- 1 | // cformat 2 | // Copyright (C) 2017, 2018 Jozef Kolek 3 | // 4 | // All rights reserved. 5 | // 6 | // See the LICENSE file for more details. 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "../include/CLexer.h" 14 | #include "../include/CParser.h" 15 | #include "../include/PrintTreeVisitor.h" 16 | #include "../include/GenCVisitor.h" 17 | 18 | #define VERSION "0.1" 19 | 20 | #define INFO_STR \ 21 | "cformat " VERSION "\n" \ 22 | "Copyright (C) 2017, 2018 Jozef Kolek . " \ 23 | "All Rights Reserved.\n\n" 24 | 25 | #define HELP_STR \ 26 | "INPUT and OUTPUT stands for input and output files respectively\n\n" \ 27 | " -o, --output Output file\n" \ 28 | " -h, --help Print out this help information\n" \ 29 | " -v, --version Print out only version information\n\n" 30 | 31 | void print_info() { std::cout << INFO_STR; } 32 | 33 | void print_help() { std::cout << HELP_STR; } 34 | 35 | int main(int argc, char **argv) 36 | { 37 | if (argc <= 1) 38 | { 39 | print_info(); 40 | std::cout << "Try -h option for more info." << std::endl; 41 | exit(1); 42 | } 43 | 44 | char *input = NULL; 45 | char output[256]; 46 | // bool outputOk = false; 47 | bool printHelp = false; 48 | bool printVersion = false; 49 | int n = 1; 50 | 51 | while (n < argc) 52 | { 53 | if (strcmp(argv[n], "-o") == 0 || strcmp(argv[n], "--output") == 0) 54 | { 55 | strcpy(output, argv[++n]); 56 | // outputOk = true; 57 | } 58 | else if (strcmp(argv[n], "-h") == 0 || strcmp(argv[n], "--help") == 0) 59 | { 60 | printHelp = true; 61 | } 62 | else if (strcmp(argv[n], "-v") == 0 || 63 | strcmp(argv[n], "--version") == 0) 64 | { 65 | printVersion = true; 66 | } 67 | else 68 | { 69 | input = argv[n]; 70 | } 71 | n++; 72 | } 73 | 74 | if (printHelp) 75 | { 76 | print_info(); 77 | print_help(); 78 | exit(0); 79 | } 80 | 81 | if (printVersion) 82 | { 83 | print_info(); 84 | exit(0); 85 | } 86 | 87 | if (input == NULL) 88 | { 89 | std::cerr << "cformat: fatal error: no input file" << std::endl; 90 | exit(1); 91 | } 92 | 93 | cparser::CLexer lexer(input); 94 | cparser::CParser parser(&lexer); 95 | parser.parse(output); 96 | 97 | cparser::AbstractSyntaxTree *ast = parser.getAST(); 98 | 99 | // std::cout << std::endl << "Abstract syntax tree:" << std::endl << std::endl; 100 | // cparser::TreeVisitor *visitor = new cparser::PrintTreeVisitor(); 101 | // ast->visit(visitor); 102 | // std::cout << std::endl; 103 | 104 | // std::cout << "===============================================" << std::endl; 105 | 106 | cparser::TreeVisitor *genCVisitor = new cparser::GenCVisitor(); 107 | ast->visit(genCVisitor); 108 | 109 | // delete visitor; 110 | delete genCVisitor; 111 | 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /test/cpp_out_example.c: -------------------------------------------------------------------------------- 1 | # 1 "test123.c" 2 | # 1 "" 1 3 | # 1 "" 3 4 | # 331 "" 3 5 | # 1 "" 1 6 | # 1 "" 2 7 | # 1 "test123.c" 2 8 | # 1 "/usr/include/stdio.h" 1 3 4 9 | # 64 "/usr/include/stdio.h" 3 4 10 | # 1 "/usr/include/_stdio.h" 1 3 4 11 | # 68 "/usr/include/_stdio.h" 3 4 12 | # 1 "/usr/include/sys/cdefs.h" 1 3 4 13 | # 587 "/usr/include/sys/cdefs.h" 3 4 14 | # 1 "/usr/include/sys/_symbol_aliasing.h" 1 3 4 15 | # 588 "/usr/include/sys/cdefs.h" 2 3 4 16 | # 653 "/usr/include/sys/cdefs.h" 3 4 17 | # 1 "/usr/include/sys/_posix_availability.h" 1 3 4 18 | # 654 "/usr/include/sys/cdefs.h" 2 3 4 19 | # 69 "/usr/include/_stdio.h" 2 3 4 20 | # 1 "/usr/include/Availability.h" 1 3 4 21 | # 206 "/usr/include/Availability.h" 3 4 22 | # 1 "/usr/include/AvailabilityInternal.h" 1 3 4 23 | # 207 "/usr/include/Availability.h" 2 3 4 24 | # 70 "/usr/include/_stdio.h" 2 3 4 25 | 26 | # 1 "/usr/include/_types.h" 1 3 4 27 | # 27 "/usr/include/_types.h" 3 4 28 | # 1 "/usr/include/sys/_types.h" 1 3 4 29 | # 33 "/usr/include/sys/_types.h" 3 4 30 | # 1 "/usr/include/machine/_types.h" 1 3 4 31 | # 32 "/usr/include/machine/_types.h" 3 4 32 | # 1 "/usr/include/i386/_types.h" 1 3 4 33 | # 37 "/usr/include/i386/_types.h" 3 4 34 | typedef signed char __int8_t; 35 | 36 | 37 | 38 | typedef unsigned char __uint8_t; 39 | typedef short __int16_t; 40 | typedef unsigned short __uint16_t; 41 | typedef int __int32_t; 42 | typedef unsigned int __uint32_t; 43 | typedef long long __int64_t; 44 | typedef unsigned long long __uint64_t; 45 | 46 | typedef long __darwin_intptr_t; 47 | typedef unsigned int __darwin_natural_t; 48 | # 70 "/usr/include/i386/_types.h" 3 4 49 | typedef int __darwin_ct_rune_t; 50 | 51 | 52 | 53 | 54 | 55 | typedef union { 56 | char __mbstate8[128]; 57 | long long _mbstateL; 58 | } __mbstate_t; 59 | 60 | typedef __mbstate_t __darwin_mbstate_t; 61 | 62 | 63 | typedef long int __darwin_ptrdiff_t; 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | typedef long unsigned int __darwin_size_t; 72 | 73 | 74 | 75 | 76 | 77 | typedef __builtin_va_list __darwin_va_list; 78 | 79 | 80 | 81 | 82 | 83 | typedef int __darwin_wchar_t; 84 | 85 | 86 | 87 | 88 | typedef __darwin_wchar_t __darwin_rune_t; 89 | 90 | 91 | typedef int __darwin_wint_t; 92 | 93 | 94 | 95 | 96 | typedef unsigned long __darwin_clock_t; 97 | typedef __uint32_t __darwin_socklen_t; 98 | typedef long __darwin_ssize_t; 99 | typedef long __darwin_time_t; 100 | # 33 "/usr/include/machine/_types.h" 2 3 4 101 | # 34 "/usr/include/sys/_types.h" 2 3 4 102 | # 55 "/usr/include/sys/_types.h" 3 4 103 | typedef __int64_t __darwin_blkcnt_t; 104 | typedef __int32_t __darwin_blksize_t; 105 | typedef __int32_t __darwin_dev_t; 106 | typedef unsigned int __darwin_fsblkcnt_t; 107 | typedef unsigned int __darwin_fsfilcnt_t; 108 | typedef __uint32_t __darwin_gid_t; 109 | typedef __uint32_t __darwin_id_t; 110 | typedef __uint64_t __darwin_ino64_t; 111 | 112 | typedef __darwin_ino64_t __darwin_ino_t; 113 | 114 | 115 | 116 | typedef __darwin_natural_t __darwin_mach_port_name_t; 117 | typedef __darwin_mach_port_name_t __darwin_mach_port_t; 118 | typedef __uint16_t __darwin_mode_t; 119 | typedef __int64_t __darwin_off_t; 120 | typedef __int32_t __darwin_pid_t; 121 | typedef __uint32_t __darwin_sigset_t; 122 | typedef __int32_t __darwin_suseconds_t; 123 | typedef __uint32_t __darwin_uid_t; 124 | typedef __uint32_t __darwin_useconds_t; 125 | typedef unsigned char __darwin_uuid_t[16]; 126 | typedef char __darwin_uuid_string_t[37]; 127 | 128 | 129 | # 1 "/usr/include/sys/_pthread/_pthread_types.h" 1 3 4 130 | # 57 "/usr/include/sys/_pthread/_pthread_types.h" 3 4 131 | struct __darwin_pthread_handler_rec { 132 | void (*__routine)(void *); 133 | void *__arg; 134 | struct __darwin_pthread_handler_rec *__next; 135 | }; 136 | 137 | struct _opaque_pthread_attr_t { 138 | long __sig; 139 | char __opaque[56]; 140 | }; 141 | 142 | struct _opaque_pthread_cond_t { 143 | long __sig; 144 | char __opaque[40]; 145 | }; 146 | 147 | struct _opaque_pthread_condattr_t { 148 | long __sig; 149 | char __opaque[8]; 150 | }; 151 | 152 | struct _opaque_pthread_mutex_t { 153 | long __sig; 154 | char __opaque[56]; 155 | }; 156 | 157 | struct _opaque_pthread_mutexattr_t { 158 | long __sig; 159 | char __opaque[8]; 160 | }; 161 | 162 | struct _opaque_pthread_once_t { 163 | long __sig; 164 | char __opaque[8]; 165 | }; 166 | 167 | struct _opaque_pthread_rwlock_t { 168 | long __sig; 169 | char __opaque[192]; 170 | }; 171 | 172 | struct _opaque_pthread_rwlockattr_t { 173 | long __sig; 174 | char __opaque[16]; 175 | }; 176 | 177 | struct _opaque_pthread_t { 178 | long __sig; 179 | struct __darwin_pthread_handler_rec *__cleanup_stack; 180 | char __opaque[8176]; 181 | }; 182 | 183 | typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; 184 | typedef struct _opaque_pthread_cond_t __darwin_pthread_cond_t; 185 | typedef struct _opaque_pthread_condattr_t __darwin_pthread_condattr_t; 186 | typedef unsigned long __darwin_pthread_key_t; 187 | typedef struct _opaque_pthread_mutex_t __darwin_pthread_mutex_t; 188 | typedef struct _opaque_pthread_mutexattr_t __darwin_pthread_mutexattr_t; 189 | typedef struct _opaque_pthread_once_t __darwin_pthread_once_t; 190 | typedef struct _opaque_pthread_rwlock_t __darwin_pthread_rwlock_t; 191 | typedef struct _opaque_pthread_rwlockattr_t __darwin_pthread_rwlockattr_t; 192 | typedef struct _opaque_pthread_t *__darwin_pthread_t; 193 | # 81 "/usr/include/sys/_types.h" 2 3 4 194 | # 28 "/usr/include/_types.h" 2 3 4 195 | # 40 "/usr/include/_types.h" 3 4 196 | typedef int __darwin_nl_item; 197 | typedef int __darwin_wctrans_t; 198 | 199 | typedef __uint32_t __darwin_wctype_t; 200 | # 72 "/usr/include/_stdio.h" 2 3 4 201 | 202 | 203 | 204 | # 1 "/usr/include/sys/_types/_va_list.h" 1 3 4 205 | # 31 "/usr/include/sys/_types/_va_list.h" 3 4 206 | # 1 "/usr/include/machine/types.h" 1 3 4 207 | # 35 "/usr/include/machine/types.h" 3 4 208 | # 1 "/usr/include/i386/types.h" 1 3 4 209 | # 76 "/usr/include/i386/types.h" 3 4 210 | # 1 "/usr/include/sys/_types/_int8_t.h" 1 3 4 211 | # 30 "/usr/include/sys/_types/_int8_t.h" 3 4 212 | typedef signed char int8_t; 213 | # 77 "/usr/include/i386/types.h" 2 3 4 214 | # 1 "/usr/include/sys/_types/_int16_t.h" 1 3 4 215 | # 30 "/usr/include/sys/_types/_int16_t.h" 3 4 216 | typedef short int16_t; 217 | # 78 "/usr/include/i386/types.h" 2 3 4 218 | # 1 "/usr/include/sys/_types/_int32_t.h" 1 3 4 219 | # 30 "/usr/include/sys/_types/_int32_t.h" 3 4 220 | typedef int int32_t; 221 | # 79 "/usr/include/i386/types.h" 2 3 4 222 | # 1 "/usr/include/sys/_types/_int64_t.h" 1 3 4 223 | # 30 "/usr/include/sys/_types/_int64_t.h" 3 4 224 | typedef long long int64_t; 225 | # 80 "/usr/include/i386/types.h" 2 3 4 226 | 227 | # 1 "/usr/include/sys/_types/_u_int8_t.h" 1 3 4 228 | # 30 "/usr/include/sys/_types/_u_int8_t.h" 3 4 229 | typedef unsigned char u_int8_t; 230 | # 82 "/usr/include/i386/types.h" 2 3 4 231 | # 1 "/usr/include/sys/_types/_u_int16_t.h" 1 3 4 232 | # 30 "/usr/include/sys/_types/_u_int16_t.h" 3 4 233 | typedef unsigned short u_int16_t; 234 | # 83 "/usr/include/i386/types.h" 2 3 4 235 | # 1 "/usr/include/sys/_types/_u_int32_t.h" 1 3 4 236 | # 30 "/usr/include/sys/_types/_u_int32_t.h" 3 4 237 | typedef unsigned int u_int32_t; 238 | # 84 "/usr/include/i386/types.h" 2 3 4 239 | # 1 "/usr/include/sys/_types/_u_int64_t.h" 1 3 4 240 | # 30 "/usr/include/sys/_types/_u_int64_t.h" 3 4 241 | typedef unsigned long long u_int64_t; 242 | # 85 "/usr/include/i386/types.h" 2 3 4 243 | 244 | 245 | typedef int64_t register_t; 246 | 247 | 248 | 249 | 250 | 251 | # 1 "/usr/include/sys/_types/_intptr_t.h" 1 3 4 252 | # 30 "/usr/include/sys/_types/_intptr_t.h" 3 4 253 | # 1 "/usr/include/machine/types.h" 1 3 4 254 | # 31 "/usr/include/sys/_types/_intptr_t.h" 2 3 4 255 | 256 | typedef __darwin_intptr_t intptr_t; 257 | # 93 "/usr/include/i386/types.h" 2 3 4 258 | # 1 "/usr/include/sys/_types/_uintptr_t.h" 1 3 4 259 | # 30 "/usr/include/sys/_types/_uintptr_t.h" 3 4 260 | typedef unsigned long uintptr_t; 261 | # 94 "/usr/include/i386/types.h" 2 3 4 262 | 263 | 264 | 265 | typedef u_int64_t user_addr_t; 266 | typedef u_int64_t user_size_t; 267 | typedef int64_t user_ssize_t; 268 | typedef int64_t user_long_t; 269 | typedef u_int64_t user_ulong_t; 270 | typedef int64_t user_time_t; 271 | typedef int64_t user_off_t; 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | typedef u_int64_t syscall_arg_t; 280 | # 36 "/usr/include/machine/types.h" 2 3 4 281 | # 32 "/usr/include/sys/_types/_va_list.h" 2 3 4 282 | typedef __darwin_va_list va_list; 283 | # 76 "/usr/include/_stdio.h" 2 3 4 284 | # 1 "/usr/include/sys/_types/_size_t.h" 1 3 4 285 | # 31 "/usr/include/sys/_types/_size_t.h" 3 4 286 | typedef __darwin_size_t size_t; 287 | # 77 "/usr/include/_stdio.h" 2 3 4 288 | # 1 "/usr/include/sys/_types/_null.h" 1 3 4 289 | # 78 "/usr/include/_stdio.h" 2 3 4 290 | 291 | # 1 "/usr/include/sys/stdio.h" 1 3 4 292 | # 39 "/usr/include/sys/stdio.h" 3 4 293 | int renameat(int, const char *, int, const char *) __attribute__((availability(macosx,introduced=10.10))); 294 | 295 | 296 | 297 | 298 | 299 | 300 | int renamex_np(const char *, const char *, unsigned int) __attribute__((availability(macosx,introduced=10.12))) __attribute__((availability(ios,introduced=10.0))) __attribute__((availability(tvos,introduced=10.0))) __attribute__((availability(watchos,introduced=3.0))); 301 | int renameatx_np(int, const char *, int, const char *, unsigned int) __attribute__((availability(macosx,introduced=10.12))) __attribute__((availability(ios,introduced=10.0))) __attribute__((availability(tvos,introduced=10.0))) __attribute__((availability(watchos,introduced=3.0))); 302 | # 80 "/usr/include/_stdio.h" 2 3 4 303 | 304 | typedef __darwin_off_t fpos_t; 305 | # 92 "/usr/include/_stdio.h" 3 4 306 | struct __sbuf { 307 | unsigned char *_base; 308 | int _size; 309 | }; 310 | 311 | 312 | struct __sFILEX; 313 | # 126 "/usr/include/_stdio.h" 3 4 314 | typedef struct __sFILE { 315 | unsigned char *_p; 316 | int _r; 317 | int _w; 318 | short _flags; 319 | short _file; 320 | struct __sbuf _bf; 321 | int _lbfsize; 322 | 323 | 324 | void *_cookie; 325 | int (* _Nullable _close)(void *); 326 | int (* _Nullable _read) (void *, char *, int); 327 | fpos_t (* _Nullable _seek) (void *, fpos_t, int); 328 | int (* _Nullable _write)(void *, const char *, int); 329 | 330 | 331 | struct __sbuf _ub; 332 | struct __sFILEX *_extra; 333 | int _ur; 334 | 335 | 336 | unsigned char _ubuf[3]; 337 | unsigned char _nbuf[1]; 338 | 339 | 340 | struct __sbuf _lb; 341 | 342 | 343 | int _blksize; 344 | fpos_t _offset; 345 | } FILE; 346 | # 65 "/usr/include/stdio.h" 2 3 4 347 | 348 | 349 | extern FILE *__stdinp; 350 | extern FILE *__stdoutp; 351 | extern FILE *__stderrp; 352 | # 142 "/usr/include/stdio.h" 3 4 353 | void clearerr(FILE *); 354 | int fclose(FILE *); 355 | int feof(FILE *); 356 | int ferror(FILE *); 357 | int fflush(FILE *); 358 | int fgetc(FILE *); 359 | int fgetpos(FILE * restrict, fpos_t *); 360 | char *fgets(char * restrict, int, FILE *); 361 | 362 | 363 | 364 | FILE *fopen(const char * restrict __filename, const char * restrict __mode) __asm("_" "fopen" ); 365 | 366 | int fprintf(FILE * restrict, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3))); 367 | int fputc(int, FILE *); 368 | int fputs(const char * restrict, FILE * restrict) __asm("_" "fputs" ); 369 | size_t fread(void * restrict __ptr, size_t __size, size_t __nitems, FILE * restrict __stream); 370 | FILE *freopen(const char * restrict, const char * restrict, 371 | FILE * restrict) __asm("_" "freopen" ); 372 | int fscanf(FILE * restrict, const char * restrict, ...) __attribute__((__format__ (__scanf__, 2, 3))); 373 | int fseek(FILE *, long, int); 374 | int fsetpos(FILE *, const fpos_t *); 375 | long ftell(FILE *); 376 | size_t fwrite(const void * restrict __ptr, size_t __size, size_t __nitems, FILE * restrict __stream) __asm("_" "fwrite" ); 377 | int getc(FILE *); 378 | int getchar(void); 379 | char *gets(char *); 380 | void perror(const char *); 381 | int printf(const char * restrict, ...) __attribute__((__format__ (__printf__, 1, 2))); 382 | int putc(int, FILE *); 383 | int putchar(int); 384 | int puts(const char *); 385 | int remove(const char *); 386 | int rename (const char *__old, const char *__new); 387 | void rewind(FILE *); 388 | int scanf(const char * restrict, ...) __attribute__((__format__ (__scanf__, 1, 2))); 389 | void setbuf(FILE * restrict, char * restrict); 390 | int setvbuf(FILE * restrict, char * restrict, int, size_t); 391 | int sprintf(char * restrict, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3))) __attribute__((__availability__(swift, unavailable, message="Use snprintf instead."))); 392 | int sscanf(const char * restrict, const char * restrict, ...) __attribute__((__format__ (__scanf__, 2, 3))); 393 | FILE *tmpfile(void); 394 | 395 | __attribute__((__availability__(swift, unavailable, message="Use mkstemp(3) instead."))) 396 | 397 | __attribute__((deprecated("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead."))) 398 | 399 | char *tmpnam(char *); 400 | int ungetc(int, FILE *); 401 | int vfprintf(FILE * restrict, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0))); 402 | int vprintf(const char * restrict, va_list) __attribute__((__format__ (__printf__, 1, 0))); 403 | int vsprintf(char * restrict, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0))) __attribute__((__availability__(swift, unavailable, message="Use vsnprintf instead."))); 404 | # 208 "/usr/include/stdio.h" 3 4 405 | char *ctermid(char *); 406 | 407 | 408 | 409 | 410 | 411 | FILE *fdopen(int, const char *) __asm("_" "fdopen" ); 412 | 413 | int fileno(FILE *); 414 | # 232 "/usr/include/stdio.h" 3 4 415 | int pclose(FILE *) __attribute__((__availability__(swift, unavailable, message="Use posix_spawn APIs or NSTask instead."))); 416 | 417 | 418 | 419 | FILE *popen(const char *, const char *) __asm("_" "popen" ) __attribute__((__availability__(swift, unavailable, message="Use posix_spawn APIs or NSTask instead."))); 420 | # 253 "/usr/include/stdio.h" 3 4 421 | int __srget(FILE *); 422 | int __svfscanf(FILE *, const char *, va_list) __attribute__((__format__ (__scanf__, 2, 0))); 423 | int __swbuf(int, FILE *); 424 | # 264 "/usr/include/stdio.h" 3 4 425 | inline __attribute__ ((__always_inline__)) int __sputc(int _c, FILE *_p) { 426 | if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) 427 | return (*_p->_p++ = _c); 428 | else 429 | return (__swbuf(_c, _p)); 430 | } 431 | # 290 "/usr/include/stdio.h" 3 4 432 | void flockfile(FILE *); 433 | int ftrylockfile(FILE *); 434 | void funlockfile(FILE *); 435 | int getc_unlocked(FILE *); 436 | int getchar_unlocked(void); 437 | int putc_unlocked(int, FILE *); 438 | int putchar_unlocked(int); 439 | 440 | 441 | 442 | int getw(FILE *); 443 | int putw(int, FILE *); 444 | 445 | 446 | __attribute__((__availability__(swift, unavailable, message="Use mkstemp(3) instead."))) 447 | 448 | __attribute__((deprecated("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead."))) 449 | 450 | char *tempnam(const char *__dir, const char *__prefix) __asm("_" "tempnam" ); 451 | # 328 "/usr/include/stdio.h" 3 4 452 | # 1 "/usr/include/sys/_types/_off_t.h" 1 3 4 453 | # 31 "/usr/include/sys/_types/_off_t.h" 3 4 454 | typedef __darwin_off_t off_t; 455 | # 329 "/usr/include/stdio.h" 2 3 4 456 | 457 | 458 | int fseeko(FILE * __stream, off_t __offset, int __whence); 459 | off_t ftello(FILE * __stream); 460 | 461 | 462 | 463 | 464 | 465 | int snprintf(char * restrict __str, size_t __size, const char * restrict __format, ...) __attribute__((__format__ (__printf__, 3, 4))); 466 | int vfscanf(FILE * restrict __stream, const char * restrict __format, va_list) __attribute__((__format__ (__scanf__, 2, 0))); 467 | int vscanf(const char * restrict __format, va_list) __attribute__((__format__ (__scanf__, 1, 0))); 468 | int vsnprintf(char * restrict __str, size_t __size, const char * restrict __format, va_list) __attribute__((__format__ (__printf__, 3, 0))); 469 | int vsscanf(const char * restrict __str, const char * restrict __format, va_list) __attribute__((__format__ (__scanf__, 2, 0))); 470 | # 353 "/usr/include/stdio.h" 3 4 471 | # 1 "/usr/include/sys/_types/_ssize_t.h" 1 3 4 472 | # 31 "/usr/include/sys/_types/_ssize_t.h" 3 4 473 | typedef __darwin_ssize_t ssize_t; 474 | # 354 "/usr/include/stdio.h" 2 3 4 475 | 476 | 477 | int dprintf(int, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3))) __attribute__((availability(macosx,introduced=10.7))); 478 | int vdprintf(int, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0))) __attribute__((availability(macosx,introduced=10.7))); 479 | ssize_t getdelim(char ** restrict __linep, size_t * restrict __linecapp, int __delimiter, FILE * restrict __stream) __attribute__((availability(macosx,introduced=10.7))); 480 | ssize_t getline(char ** restrict __linep, size_t * restrict __linecapp, FILE * restrict __stream) __attribute__((availability(macosx,introduced=10.7))); 481 | FILE *fmemopen(void * restrict __buf, size_t __size, const char * restrict __mode) __attribute__((availability(macos,introduced=10.13))) __attribute__((availability(ios,introduced=11.0))) __attribute__((availability(tvos,introduced=11.0))) __attribute__((availability(watchos,introduced=4.0))); 482 | FILE *open_memstream(char **__bufp, size_t *__sizep) __attribute__((availability(macos,introduced=10.13))) __attribute__((availability(ios,introduced=11.0))) __attribute__((availability(tvos,introduced=11.0))) __attribute__((availability(watchos,introduced=4.0))); 483 | # 371 "/usr/include/stdio.h" 3 4 484 | extern const int sys_nerr; 485 | extern const char *const sys_errlist[]; 486 | 487 | int asprintf(char ** restrict, const char * restrict, ...) __attribute__((__format__ (__printf__, 2, 3))); 488 | char *ctermid_r(char *); 489 | char *fgetln(FILE *, size_t *); 490 | const char *fmtcheck(const char *, const char *); 491 | int fpurge(FILE *); 492 | void setbuffer(FILE *, char *, int); 493 | int setlinebuf(FILE *); 494 | int vasprintf(char ** restrict, const char * restrict, va_list) __attribute__((__format__ (__printf__, 2, 0))); 495 | FILE *zopen(const char *, const char *, int); 496 | 497 | 498 | 499 | 500 | 501 | FILE *funopen(const void *, 502 | int (* _Nullable)(void *, char *, int), 503 | int (* _Nullable)(void *, const char *, int), 504 | fpos_t (* _Nullable)(void *, fpos_t, int), 505 | int (* _Nullable)(void *)); 506 | # 411 "/usr/include/stdio.h" 3 4 507 | # 1 "/usr/include/secure/_stdio.h" 1 3 4 508 | # 31 "/usr/include/secure/_stdio.h" 3 4 509 | # 1 "/usr/include/secure/_common.h" 1 3 4 510 | # 32 "/usr/include/secure/_stdio.h" 2 3 4 511 | # 42 "/usr/include/secure/_stdio.h" 3 4 512 | extern int __sprintf_chk (char * restrict, int, size_t, 513 | const char * restrict, ...); 514 | # 52 "/usr/include/secure/_stdio.h" 3 4 515 | extern int __snprintf_chk (char * restrict, size_t, int, size_t, 516 | const char * restrict, ...); 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | extern int __vsprintf_chk (char * restrict, int, size_t, 525 | const char * restrict, va_list); 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | extern int __vsnprintf_chk (char * restrict, size_t, int, size_t, 534 | const char * restrict, va_list); 535 | # 412 "/usr/include/stdio.h" 2 3 4 536 | # 2 "test123.c" 2 537 | 538 | int main() 539 | { 540 | printf("Hello world!\n"); 541 | } 542 | -------------------------------------------------------------------------------- /test/example1.c: -------------------------------------------------------------------------------- 1 | int main(int argc,char **argv) { 2 | int x=22; 3 | int y=33; 4 | int z=x+y; 5 | 6 | return z; 7 | } 8 | --------------------------------------------------------------------------------