parser.c (23216B)
1 // TO READ THIS FILE: 2 // see grammar.txt 3 // see the stateFt STATEF[FINAL] array 4 // and see the functions 5 6 #include "parser.h" 7 8 // TODO remove global variables to be able to run multithreaded 9 int stateM = IDLE; 10 11 smallArrayt *generatedC = NULL; 12 smallArrayt *sheepyC = NULL; 13 smallArrayt *stateStack = NULL; 14 smallArrayt *textStack = NULL; 15 16 char *STATESSTR[FINAL] = { 17 "IDLE", 18 "TYPE", 19 "TYPEID", 20 "POINTERTYPE", 21 "TYPEINIT", 22 "TYPEINITSTR", 23 "TYPEEND", 24 "CONST_", 25 "EXTERN_", 26 "VOLATILE_", 27 "STATIC_", 28 "UNSIGNED_", 29 "SIGNED_", 30 "ENUM_", 31 "ENUM_END", 32 "TYPEDEF_", 33 "TDSTRUCT", 34 "STRUCTBLOCK", 35 "STRUCTINBLOCK", 36 "UNIONINSTRUCT", 37 "STRUCTTYPE", 38 "STRUCTTYPEID", 39 "STRUCTTYPEEND", 40 "STRUCTID", 41 "STRUCTBLOCKEND", 42 "UNIONBLOCK", 43 "STRUCTINUNION", 44 "UNIONINBLOCK", 45 "UNIONTYPE", 46 "UNIONTYPEID", 47 "UNIONTYPEEND", 48 "UNIONID", 49 "UNIONBLOCKEND", 50 "FUNCOPEN", 51 "FUNCCLOSE", 52 "PROTOTYPE", 53 "CODEBLOCK", 54 "CONTINUE_", 55 "CODEBLOCKID", 56 "CALL", 57 "CALLSTR", 58 "CALLCLOSE", 59 "CALLEND", 60 "CALLENDNPOP", 61 "INCREMENT", 62 "GOTO_", 63 "GOTO_ID", 64 "GOTO_END", 65 "GOTO_ENDNPOP", 66 "COLON", 67 "COLONEND", 68 "ARRAYINDEX", 69 "ARRAYINDEXEND", 70 "ASSIGNMENT", 71 "NUMBER", 72 "ASSIGNID", 73 "QUOTED_CHAR", 74 "QUOTED_CHAR_SEMICOLON", 75 "SIZEOF_", 76 "IF_", 77 "ELSE_", 78 "FOR_", 79 "DO_", 80 "SWITCH_", 81 "SWITCH_BLOCK", 82 "CASE_", 83 "CASE_ID", 84 "CASE_BLOCK", 85 "BREAK_", 86 "SWITCH_BLOCKEND", 87 "RETURN_", 88 "RETURN_STR", 89 "RETURN_END", 90 "CODEBLOCKEND", 91 "DO_END", 92 "DO_FOR", 93 "DO_CLOSE", 94 "USE", 95 "USEID", 96 "USEDOT", 97 "USECOMMA", 98 "USEEND", 99 }; 100 101 // extra -1 -1 to run a default function when a token is not found 102 int STATES[FINAL][TRANSITIONS*2] = { 103 /*IDLE*/ {QUEX_TKN_PP_USE, USE, QUEX_TKN_CONST, CONST_, QUEX_TKN_TYPE_INT, TYPE, QUEX_TKN_TYPE_VOID, TYPE, QUEX_TKN_EXTERN, EXTERN_, QUEX_TKN_ENUM, ENUM_, QUEX_TKN_TYPE, TYPEDEF_, -1, -1}, 104 /*TYPE*/ {QUEX_TKN_IDENTIFIER, TYPEID, QUEX_TKN_MULT, POINTERTYPE, -1, -1}, 105 /*TYPEID*/ {QUEX_TKN_BRACKET_O, FUNCOPEN, QUEX_TKN_NODENT, TYPEEND, QUEX_TKN_OP_ASSIGNMENT, TYPEINIT, -1, -1}, 106 /*POINTERTYPE*/ {QUEX_TKN_IDENTIFIER, TYPEID, -1, -1}, 107 /*TYPEINIT*/ {QUEX_TKN_STRING, TYPEINITSTR, QUEX_TKN_NODENT, TYPEEND, -1, -1}, 108 /*TYPEINITSTR*/ {-1, -1, -1, -1}, 109 /*TYPEEND*/ {-1, -1, -1, -1}, 110 /*CONST_*/ {QUEX_TKN_TYPE_CHAR, TYPE, -1, -1}, 111 /*EXTERN_*/ {QUEX_TKN_TYPE_INT, TYPE, -1, -1}, 112 /*VOLATILE_*/ {QUEX_TKN_TYPE_INT, TYPE, -1, -1}, 113 /*STATIC_*/ {QUEX_TKN_TYPE_INT, TYPE, QUEX_TKN_TYPE_UNSIGNED, UNSIGNED_, -1, -1}, 114 /*UNSIGNED_*/ {QUEX_TKN_TYPE_LONG, TYPE, -1, -1}, 115 /*SIGNED_*/ {QUEX_TKN_TYPE_SHORT, TYPE, -1, -1}, 116 /*ENUM_*/ {QUEX_TKN_NODENT, ENUM_END, -1, -1}, 117 /*ENUM_END*/ {-1, -1, -1, -1}, 118 /*TYPEDEF_*/ {QUEX_TKN_STRUCT, TDSTRUCT, -1, -1}, 119 /*TDSTRUCT*/ {QUEX_TKN_INDENT, STRUCTBLOCK, -1, -1}, 120 /*STRUCTBLOCK*/ {QUEX_TKN_TYPE_INT, STRUCTTYPE, QUEX_TKN_IDENTIFIER, STRUCTID, QUEX_TKN_STRUCT, STRUCTINBLOCK, QUEX_TKN_UNION, UNIONINSTRUCT, -1, -1}, 121 /*STRUCTINBLOCK*/ {QUEX_TKN_INDENT, STRUCTBLOCK, -1, -1}, 122 /*UNIONINSTRUCT*/ {QUEX_TKN_INDENT, UNIONBLOCK, -1, -1}, 123 /*STRUCTTYPE*/ {QUEX_TKN_IDENTIFIER, STRUCTTYPEID, -1, -1}, 124 /*STRUCTTYPEID*/ {QUEX_TKN_NODENT, STRUCTTYPEEND, -1, -1}, 125 /*STRUCTTYPEEND*/ {-1, -1, -1, -1}, 126 /*STRUCTID*/ {QUEX_TKN_DEDENT, STRUCTBLOCKEND, -1, -1}, 127 /*STRUCTBLOCKEND*/ {-1, -1, -1, -1}, 128 /*UNIONBLOCK*/ {QUEX_TKN_TYPE_CHAR, UNIONTYPE, QUEX_TKN_TYPE_INT, UNIONTYPE, QUEX_TKN_IDENTIFIER, UNIONID, QUEX_TKN_STRUCT, STRUCTINUNION, QUEX_TKN_UNION, UNIONINBLOCK, -1, -1}, 129 /*STRUCTINUNION*/ {QUEX_TKN_INDENT, STRUCTBLOCK, -1, -1}, 130 /*UNIONINBLOCK*/ {QUEX_TKN_INDENT, UNIONBLOCK, -1, -1}, 131 /*UNIONTYPE*/ {QUEX_TKN_IDENTIFIER, UNIONTYPEID, -1, -1}, 132 /*UNIONTYPEID*/ {QUEX_TKN_NODENT, UNIONTYPEEND, -1, -1}, 133 /*UNIONTYPEEND*/ {-1, -1, -1, -1}, 134 /*UNIONID*/ {QUEX_TKN_DEDENT, UNIONBLOCKEND, -1, -1}, 135 /*UNIONBLOCKEND*/ {-1, -1, -1, -1}, 136 /*FUNCOPEN*/ {QUEX_TKN_BRACKET_C, FUNCCLOSE, -1, -1}, 137 /*FUNCCLOSE*/ {QUEX_TKN_INDENT, CODEBLOCK, QUEX_TKN_NODENT, PROTOTYPE, -1, -1}, 138 /*PROTOTYPE*/ {-1, -1, -1, -1}, 139 /*CODEBLOCK*/ {QUEX_TKN_CONST, CONST_, QUEX_TKN_CONTINUE, CONTINUE_, QUEX_TKN_VOLATILE, VOLATILE_, QUEX_TKN_STATIC, STATIC_, QUEX_TKN_TYPE_SIGNED, SIGNED_, QUEX_TKN_TYPE_CHAR, TYPE, QUEX_TKN_TYPE_DOUBLE, TYPE, QUEX_TKN_TYPE_FLOAT, TYPE, QUEX_TKN_TYPE_INT, TYPE, QUEX_TKN_IDENTIFIER, CODEBLOCKID, QUEX_TKN_DO, DO_, QUEX_TKN_ELSE, ELSE_, QUEX_TKN_FOR, FOR_, QUEX_TKN_GOTO, GOTO_, QUEX_TKN_IF, IF_, QUEX_TKN_RETURN, RETURN_, QUEX_TKN_SWITCH, SWITCH_, QUEX_TKN_DEDENT, CODEBLOCKEND, -1, -1}, 140 /*CONTINUE_*/ {QUEX_TKN_DEDENT, CODEBLOCKEND, -1, -1}, 141 /*CODEBLOCKID*/ {QUEX_TKN_BRACKET_O, CALL, QUEX_TKN_COLON, COLON, QUEX_TKN_CORNER_BRACKET_O, ARRAYINDEX, QUEX_TKN_OP_ASSIGNMENT, ASSIGNMENT, QUEX_TKN_INCREMENT, INCREMENT, -1, -1}, 142 /*CALL*/ {QUEX_TKN_STRING, CALLSTR, QUEX_TKN_BRACKET_C, CALLCLOSE, -1, -1}, 143 /*CALLSTR*/ {-1, -1, -1, -1}, 144 /*CALLCLOSE*/ {QUEX_TKN_NODENT, CALLEND, QUEX_TKN_DEDENT, CALLENDNPOP, -1, -1}, 145 /*CALLEND*/ {-1, -1, -1, -1}, 146 /*CALLENDNPOP*/ {-1, -1, -1, -1}, 147 /*INCREMENT*/ {QUEX_TKN_NODENT, CALLEND, QUEX_TKN_DEDENT, CALLENDNPOP, -1, -1}, 148 /*GOTO_*/ {QUEX_TKN_IDENTIFIER, GOTO_ID, -1, -1}, 149 /*GOTO_ID*/ {QUEX_TKN_NODENT, GOTO_END, QUEX_TKN_DEDENT, GOTO_ENDNPOP, -1, -1}, 150 /*GOTO_END*/ {-1, -1, -1, -1}, 151 /*GOTO_ENDNPOP*/ {-1, -1, -1, -1}, 152 /*COLON*/ {QUEX_TKN_NODENT, COLONEND, -1, -1}, 153 /*COLONEND*/ {-1, -1, -1, -1}, 154 /*ARRAYINDEX*/ {QUEX_TKN_CORNER_BRACKET_C, ARRAYINDEXEND, -1, -1}, 155 /*ARRAYINDEXEND*/ {QUEX_TKN_OP_ASSIGNMENT, ASSIGNMENT, -1, -1}, 156 /*ASSIGNMENT*/ {QUEX_TKN_NUMBER, NUMBER, QUEX_TKN_QUOTED_CHAR, QUOTED_CHAR, QUEX_TKN_SIZEOF, SIZEOF_, QUEX_TKN_IDENTIFIER, ASSIGNID, -1, -1}, 157 /*NUMBER*/ {QUEX_TKN_NODENT, CALLEND, QUEX_TKN_DEDENT, CALLENDNPOP, -1, -1}, 158 /*ASSIGNID*/ {QUEX_TKN_BRACKET_O, CALL, -1, -1}, 159 /*QUOTED_CHAR*/ {QUEX_TKN_SEMICOLON, QUOTED_CHAR_SEMICOLON, QUEX_TKN_NODENT, CALLEND, -1, -1}, 160 /*QUOTED_CHAR_SEMICOLON*/ {QUEX_TKN_NODENT, CALLEND, -1, -1}, 161 /*SIZEOF_*/ {QUEX_TKN_BRACKET_O, CALL, -1, -1}, 162 /*IF_*/ {QUEX_TKN_INDENT, CODEBLOCK, -1, -1}, 163 /*ELSE_*/ {QUEX_TKN_INDENT, CODEBLOCK, -1, -1}, 164 /*FOR_*/ {QUEX_TKN_INDENT, CODEBLOCK, -1, -1}, 165 /*DO_*/ {QUEX_TKN_INDENT, CODEBLOCK, -1, -1}, 166 /*SWITCH_*/ {QUEX_TKN_INDENT, SWITCH_BLOCK, -1, -1}, 167 /*SWITCH_BLOCK*/ {QUEX_TKN_CASE, CASE_, QUEX_TKN_DEFAULT, CASE_ID, QUEX_TKN_DEDENT, SWITCH_BLOCKEND, -1, -1}, 168 /*CASE_*/ {QUEX_TKN_IDENTIFIER, CASE_ID, QUEX_TKN_NUMBER, CASE_ID, -1, -1}, 169 /*CASE_ID*/ {QUEX_TKN_INDENT, CASE_BLOCK, -1, -1}, 170 /*CASE_BLOCK*/ {QUEX_TKN_IDENTIFIER, CODEBLOCKID, QUEX_TKN_BREAK, BREAK_, QUEX_TKN_DO, DO_, QUEX_TKN_ELSE, ELSE_, QUEX_TKN_FOR, FOR_, QUEX_TKN_GOTO, GOTO_, QUEX_TKN_IF, IF_, QUEX_TKN_RETURN, RETURN_, QUEX_TKN_SWITCH, SWITCH_, QUEX_TKN_DEDENT, CODEBLOCKEND, -1, -1}, 171 /*BREAK_*/ {QUEX_TKN_DEDENT, CODEBLOCKEND, -1, -1}, 172 /*SWITCH_BLOCKEND*/ {-1, -1, -1, -1}, 173 /*RETURN_*/ {QUEX_TKN_STRING, RETURN_STR, QUEX_TKN_DEDENT, RETURN_END, -1, -1}, 174 /*RETURN_STR*/ {-1, -1, -1, -1}, 175 /*RETURN_END*/ {-1, -1, -1, -1}, 176 /*CODEBLOCKEND*/ {-1, -1, -1, -1}, 177 /*DO_END*/ {QUEX_TKN_FOR, DO_FOR, -1, -1}, 178 /*DO_FOR*/ {QUEX_TKN_NODENT, DO_CLOSE, -1, -1}, 179 /*DO_CLOSE*/ {-1, -1, -1, -1}, 180 /*USE*/ {QUEX_TKN_IDENTIFIER, USEID, -1, -1}, 181 /*USEID*/ {QUEX_TKN_DOT, USEDOT, QUEX_TKN_COMMA, USECOMMA, QUEX_TKN_NODENT, USEEND, -1, -1}, 182 /*USEDOT*/ {QUEX_TKN_IDENTIFIER, USEID, -1, -1}, 183 /*USECOMMA*/ {QUEX_TKN_IDENTIFIER, USEID, -1, -1}, 184 /*USEEND*/ {-1, -1, -1, -1}, 185 }; 186 187 void toCString(char *text) { 188 // convert to C string 189 char *tmp = dupS(text); 190 pErrorNULL(setS(tmp, 0, '\"')); 191 pErrorNULL(setS(tmp, -1, '\"')); 192 // TODO regular expression 193 pErrorNULL(iReplaceS_max(&tmp, "\'", "'")); 194 pErrorNULL(pushNFreeG(sheepyC, tmp)); 195 return; 196 } 197 198 void generateCodeL() { 199 smallStringt *tmp = joinG(sheepyC, ""); 200 pErrorNULL(pushNFreeG(generatedC, tmp)); 201 freeG(sheepyC); 202 //initiateAllocateSmallString(&sheepyC); 203 } 204 205 void defaultInState(int ste, char *text) { 206 //printf("%s %s %s\n",__func__,STATESSTR[ste], text); 207 } 208 209 void defaultInStateCopy(int ste, char *text) { 210 pErrorNULL(pushG(sheepyC, " ")); 211 pErrorNULL(pushG(sheepyC, text)); 212 } 213 214 void idle(int ste, char *text) { 215 } 216 217 void type(int ste, char *text) { 218 pErrorNULL(pushG(sheepyC, " ")); 219 pErrorNULL(pushG(sheepyC, text)); 220 // set next state 221 pErrorNULL(pushG(stateStack, stateM)); 222 stateM = ste; 223 } 224 225 void typeid(int ste, char *text) { 226 // set next state 227 stateM = ste; 228 } 229 230 void pointertype(int ste, char *text) { 231 // set next state 232 stateM = ste; 233 } 234 235 void typeinit(int ste, char *text) { 236 // set next state 237 stateM = ste; 238 } 239 240 void typeinitstr(int ste, char *text) { 241 toCString(text); 242 // set next state 243 stateM = TYPEINIT; 244 } 245 246 void typeend(int ste, char *text) { 247 pErrorNULL(pushG(sheepyC, ";")); 248 generateCodeL(); 249 // set next state 250 stateM = popG(stateStack, rtInt32_t); 251 if ((stateM == IDLE)||(stateM == CODEBLOCK)||(stateM == CASE_BLOCK)) { 252 return; 253 } 254 if (stateM == EXTERN_) { 255 stateM = IDLE; 256 return; 257 } 258 // TODO pop until block is found 259 stateM = popG(stateStack, rtInt32_t); 260 if ((stateM == CODEBLOCK)||(stateM == CASE_BLOCK)) { 261 return; 262 } 263 stateM = popG(stateStack, rtInt32_t); 264 } 265 266 void extern_(int ste, char *text) { 267 // set next state 268 stateM = ste; 269 } 270 271 void volatile_(int ste, char *text) { 272 // set next state 273 stateM = ste; 274 } 275 276 void static_(int ste, char *text) { 277 // set next state 278 stateM = ste; 279 } 280 281 void unsigned_(int ste, char *text) { 282 // set next state 283 stateM = ste; 284 } 285 286 void signed_(int ste, char *text) { 287 // set next state 288 stateM = ste; 289 } 290 291 void enum_(int ste, char *text) { 292 pushG(sheepyC, "enum {"); 293 // set next state 294 stateM = ste; 295 } 296 297 void enum_end(int ste, char *text) { 298 pErrorNULL(pushG(sheepyC, "};")); 299 generateCodeL(); 300 // set next state 301 stateM = IDLE; 302 } 303 304 void typedef_(int ste, char *text) { 305 pErrorNULL(pushG(sheepyC, "typedef")); 306 // set next state 307 stateM = ste; 308 } 309 310 void tdstruct(int ste, char *text) { 311 // set next state 312 stateM = ste; 313 } 314 315 void structblock(int ste, char *text) { 316 pErrorNULL(pushG(sheepyC, " {")); 317 generateCodeL(); 318 pErrorNULL(pushG(stateStack, stateM)); 319 // set next state 320 stateM = ste; 321 } 322 323 void structinblock(int ste, char *text) { 324 // set next state 325 stateM = ste; 326 } 327 328 void unioninstruct(int ste, char *text) { 329 // set next state 330 stateM = ste; 331 } 332 333 void structtype(int ste, char *text) { 334 // set next state 335 stateM = ste; 336 } 337 338 void structtypeid(int ste, char *text) { 339 // set next state 340 stateM = ste; 341 } 342 343 void structtypeend(int ste, char *text) { 344 pErrorNULL(pushG(sheepyC, ";")); 345 generateCodeL(); 346 // set next state 347 stateM = STRUCTBLOCK; 348 } 349 350 void structid(int ste, char *text) { 351 pErrorNULL(pushG(textStack, text)); 352 // set next state 353 stateM = ste; 354 } 355 356 void structblockend(int ste, char *text) { 357 char *id = popG(textStack, rtChar); 358 pErrorNULL(pushG(sheepyC, "} ")); 359 pErrorNULL(pushNFreeG(sheepyC, id)); 360 pErrorNULL(pushG(sheepyC, ";")); 361 generateCodeL(); 362 // set next state 363 stateM = popG(stateStack, rtInt32_t); 364 switch(stateM) { 365 case TDSTRUCT: 366 stateM = IDLE; 367 break; 368 case STRUCTINBLOCK: 369 stateM = STRUCTBLOCK; 370 break; 371 case STRUCTINUNION: 372 stateM = UNIONBLOCK; 373 break; 374 } 375 } 376 377 void unionblock(int ste, char *text) { 378 // set next state 379 stateM = ste; 380 } 381 382 void structinunion(int ste, char *text) { 383 // set next state 384 stateM = ste; 385 } 386 387 void unioninblock(int ste, char *text) { 388 // set next state 389 stateM = ste; 390 } 391 392 void uniontype(int ste, char *text) { 393 // set next state 394 stateM = ste; 395 } 396 397 void uniontypeid(int ste, char *text) { 398 // set next state 399 stateM = ste; 400 } 401 402 void uniontypeend(int ste, char *text) { 403 pErrorNULL(pushG(sheepyC, ";")); 404 generateCodeL(); 405 // set next state 406 stateM = UNIONBLOCK; 407 } 408 409 void unionid(int ste, char *text) { 410 // set next state 411 stateM = ste; 412 } 413 414 void unionblockend(int ste, char *text) { 415 char *id = popG(textStack, rtChar); 416 pErrorNULL(pushG(sheepyC, "} ")); 417 pErrorNULL(pushNFreeG(sheepyC, id)); 418 pErrorNULL(pushG(sheepyC, ";")); 419 generateCodeL(); 420 // set next state 421 stateM = popG(stateStack, rtInt32_t); 422 switch(stateM) { 423 /* case TDUNION: */ 424 /* stateM = IDLE; */ 425 /* break; */ 426 case UNIONINBLOCK: 427 stateM = UNIONBLOCK; 428 break; 429 case UNIONINSTRUCT: 430 stateM = STRUCTBLOCK; 431 break; 432 } 433 } 434 435 void funcopen(int ste, char *text) { 436 // set next state 437 stateM = ste; 438 } 439 440 void funcclose(int ste, char *text) { 441 // do nothing the bracket ) and curly bracket are in the 442 // codeblock function 443 // set next state 444 stateM = ste; 445 } 446 447 void prototype(int ste, char *text) { 448 pushG(sheepyC, ");"); 449 generateCodeL(); 450 // set next state 451 stateM = IDLE; 452 } 453 454 void codeblock(int ste, char *text) { 455 if ((stateM == DO_)||(stateM == ELSE_)) { 456 pErrorNULL(pushG(sheepyC, " {")); 457 } 458 else { 459 // close condition statement 460 pErrorNULL(pushG(sheepyC, ") {")); 461 } 462 generateCodeL(); 463 pErrorNULL(pushG(stateStack, stateM)); 464 // set next state 465 stateM = ste; 466 } 467 468 void codeblockid(int ste, char *text) { 469 pErrorNULL(pushG(sheepyC, text)); 470 // set next state 471 pushG(stateStack, stateM); 472 stateM = ste; 473 } 474 475 void call(int ste, char *text) { 476 pErrorNULL(pushG(sheepyC, "(")); 477 // set next state 478 stateM = ste; 479 } 480 481 void callstr(int ste, char *text) { 482 toCString(text); 483 // set next state 484 stateM = CALL; 485 } 486 487 void callclose(int ste, char *text) { 488 pErrorNULL(pushG(sheepyC, ")")); 489 // set next state 490 stateM = ste; 491 } 492 493 void callend(int ste, char *text) { 494 pErrorNULL(pushG(sheepyC, ";")); 495 generateCodeL(); 496 // set next state 497 // pop to return to CODEBLOCK or CASE_BLOCK 498 stateM = popG(stateStack, rtInt32_t); 499 } 500 501 void callendnpop(int ste, char *text) { 502 pErrorNULL(pushG(sheepyC, ";")); 503 generateCodeL(); 504 // set next state 505 // pop to return to CODEBLOCK or CASE_BLOCK 506 stateM = popG(stateStack, rtInt32_t); 507 codeblockend(ste, text); 508 } 509 510 void increment(int ste, char *text) { 511 // set next state 512 stateM = ste; 513 } 514 515 void goto_(int ste, char *text) { 516 // set next state 517 stateM = ste; 518 } 519 520 void goto_id(int ste, char *text) { 521 // set next state 522 stateM = ste; 523 } 524 525 void goto_end(int ste, char *text) { 526 pErrorNULL(pushG(sheepyC, ";")); 527 generateCodeL(); 528 // set next state 529 stateM = CODEBLOCK; 530 } 531 532 void goto_endnpop(int ste, char *text) { 533 pErrorNULL(pushG(sheepyC, ";")); 534 generateCodeL(); 535 // set next state 536 codeblockend(ste, text); 537 } 538 539 void colon(int ste, char *text) { 540 pErrorNULL(pushG(sheepyC, ":")); 541 generateCodeL(); 542 // set next state 543 // pop stateM pushed in codeblockid 544 // discard because goto labels are always in codeblocks 545 popG(stateStack, rtInt32_t); 546 stateM = ste; 547 } 548 549 void colonend(int ste, char *text) { 550 // set next state 551 stateM = CODEBLOCK; 552 } 553 554 void arrayindex(int ste, char *text) { 555 // set next state 556 stateM = ste; 557 } 558 559 void arrayindexend(int ste, char *text) { 560 // set next state 561 stateM = ste; 562 } 563 564 void assignment(int ste, char *text) { 565 // set next state 566 stateM = ste; 567 } 568 569 void quoted_char(int ste, char *text) { 570 // convert to C char 571 text = dupS(text); 572 pErrorNULL(iReplaceS(&text, "'", "\\'", 1)); 573 pErrorNULL(setS(text, 0, '\'')); 574 pErrorNULL(iAppendS(&text, "'")); 575 pErrorNULL(iReplaceS(&text, "\\@", "@", 1)); 576 pErrorNULL(pushNFreeG(sheepyC, text)); 577 // set next state 578 stateM = ste; 579 } 580 581 void quoted_char_semicolon(int ste, char *text) { 582 // change last string in sheepyC 583 // add space in char 584 // tabs should be \t 585 smallStringt *txt = getG(sheepyC, rtSmallStringt, -1); 586 pErrorNULL(setG(txt, 1, ' ')); 587 pErrorNULL(pushG(txt, "'")); 588 // pointer in sheepyC should be updated with setPG sheepyC 589 // but this string is always short 590 // the pointer doesn't change 591 smashG(txt); 592 // set next state 593 stateM = ste; 594 } 595 596 void sizeof_(int ste, char *text) { 597 // set next state 598 stateM = ste; 599 } 600 601 void assignmentend(int ste, char *text) { 602 // set next state 603 stateM = ste; 604 } 605 606 void if_(int ste, char *text) { 607 pErrorNULL(pushG(sheepyC, text)); 608 pErrorNULL(pushG(sheepyC, " (")); 609 // set next state 610 stateM = ste; 611 } 612 613 void else_(int ste, char *text) { 614 // set next state 615 stateM = ste; 616 } 617 618 void for_(int ste, char *text) { 619 // set next state 620 stateM = ste; 621 } 622 623 void do_(int ste, char *text) { 624 // set next state 625 stateM = ste; 626 } 627 628 void switch_(int ste, char *text) { 629 // set next state 630 stateM = ste; 631 } 632 633 void switch_block(int ste, char *text) { 634 pErrorNULL(pushG(sheepyC, ") {")); 635 generateCodeL(); 636 // TODO push stateM >> use structblock function 637 // set next state 638 stateM = ste; 639 } 640 641 void case_(int ste, char *text) { 642 // set next state 643 stateM = ste; 644 } 645 646 void case_id(int ste, char *text) { 647 // set next state 648 stateM = ste; 649 } 650 651 void case_block(int ste, char *text) { 652 // add curly brackets around code for case labels 653 pErrorNULL(pushG(sheepyC, ": {")); 654 generateCodeL(); 655 pErrorNULL(pushG(stateStack, stateM)); 656 // set next state 657 stateM = ste; 658 } 659 660 void break_(int ste, char *text) { 661 pErrorNULL(pushG(sheepyC, text)); 662 pErrorNULL(pushG(sheepyC, ";")); 663 // set next state 664 stateM = ste; 665 } 666 667 void switch_blockend(int ste, char *text) { 668 pErrorNULL(pushG(sheepyC, "}")); 669 // TODO pop stateM 670 // set next state 671 stateM = CODEBLOCK; 672 } 673 674 void return_(int ste, char *text) { 675 // set next state 676 stateM = ste; 677 } 678 679 void return_str(int ste, char *text) { 680 // convert to C string 681 toCString(text); 682 // set next state 683 stateM = RETURN_; 684 } 685 686 void return_end(int ste, char *text) { 687 // when return doesnt have parameters 688 // replace bracket with semicolon 689 char *tmp = getG(sheepyC, rtChar, -1); 690 if (getS(tmp, -1) == '(') { 691 pErrorNULL(setS(tmp, -1, ';')); 692 } 693 else { 694 pErrorNULL(pushG(sheepyC, ");")); 695 } 696 generateCodeL(); 697 // set next state 698 stateM = CODEBLOCKEND; 699 codeblockend(ste, text); 700 } 701 702 void codeblockend(int ste, char *text) { 703 pErrorNULL(pushG(sheepyC, "}")); 704 // set next state 705 stateM = popG(stateStack, rtInt32_t); 706 switch(stateM) { 707 case FUNCCLOSE: 708 generateCodeL(); 709 stateM = IDLE; 710 break; 711 case IF_: 712 generateCodeL(); 713 stateM = CODEBLOCK; 714 break; 715 case ELSE_: 716 generateCodeL(); 717 stateM = CODEBLOCK; 718 break; 719 case FOR_: 720 generateCodeL(); 721 stateM = CODEBLOCK; 722 break; 723 case DO_: 724 // dont generate code because the conditional 725 // statement is after that 726 stateM = DO_END; 727 break; 728 case CASE_ID: 729 generateCodeL(); 730 stateM = SWITCH_BLOCK; 731 break; 732 } 733 } 734 735 void do_end(int ste, char *text) { 736 // set next state 737 stateM = ste; 738 } 739 740 void do_for(int ste, char *text) { 741 pErrorNULL(pushG(sheepyC, " while (")); 742 // set next state 743 stateM = ste; 744 } 745 746 void do_close(int ste, char *text) { 747 pErrorNULL(pushG(sheepyC, ");")); 748 generateCodeL(); 749 // set next state 750 stateM = CODEBLOCK; 751 } 752 753 void use(int ste, char *text) { 754 pErrorNULL(pushG(sheepyC, "#include \"")); 755 // set next state 756 stateM = ste; 757 } 758 759 void addT(int ste, char *text) { 760 pErrorNULL(pushG(sheepyC, text)); 761 // set next state 762 stateM = ste; 763 } 764 765 void usecomma(int ste, char *text) { 766 pErrorNULL(pushG(sheepyC, "\"")); 767 generateCodeL(); 768 // expecting more use 769 use(ste, text); 770 } 771 772 void useend(int ste, char *text) { 773 pErrorNULL(pushG(sheepyC, "\"")); 774 generateCodeL(); 775 stateM = IDLE; 776 } 777 778 void addSpaceNT(int ste, char *text) { 779 pErrorNULL(pushG(sheepyC, " ")); 780 pErrorNULL(pushG(sheepyC, text)); 781 // set next state 782 stateM = ste; 783 } 784 785 786 // ste is the state it is transitioning to 787 // text is the token 788 typedef void (*stateFt)(int ste, char *text); 789 stateFt STATEF[FINAL] = { 790 /*IDLE*/ idle, 791 /*TYPE*/ type, 792 /*TYPEID*/ addSpaceNT, 793 /*POINTERTYPE*/ addSpaceNT, 794 /*TYPEINIT*/ addT, 795 /*TYPEINITSTR*/ typeinitstr, 796 /*TYPEEND*/ typeend, 797 /*CONST_*/ type, 798 /*EXTERN_*/ addSpaceNT, 799 /*VOLATILE_*/ type, 800 /*STATIC_*/ type, 801 /*UNSIGNED_*/ type, 802 /*SIGNED_*/ type, 803 /*ENUM_*/ enum_, 804 /*ENUM_END*/ enum_end, 805 /*TYPEDEF_*/ typedef_, 806 /*TDSTRUCT*/ addSpaceNT, 807 /*STRUCTBLOCK*/ structblock, 808 /*STRUCTINBLOCK*/ addT, 809 /*UNIONINSTRUCT*/ addT, 810 /*STRUCTTYPE*/ addSpaceNT, 811 /*STRUCTTYPEID*/ addSpaceNT, 812 /*STRUCTTYPEEND*/ structtypeend, 813 /*STRUCTID*/ structid, 814 /*STRUCTBLOCKEND*/ structblockend, 815 /*UNIONBLOCK*/ structblock, 816 /*STRUCTINUNION*/ addT, 817 /*UNIONINBLOCK*/ addT, 818 /*UNIONTYPE*/ addSpaceNT, 819 /*UNIONTYPEID*/ addSpaceNT, 820 /*UNIONTYPEEND*/ uniontypeend, 821 /*UNIONID*/ structid, 822 /*UNIONBLOCKEND*/ unionblockend, 823 /*FUNCOPEN*/ addSpaceNT, 824 /*FUNCCLOSE*/ funcclose, 825 /*PROTOTYPE*/ prototype, 826 /*CODEBLOCK*/ codeblock, 827 /*CONTINUE_*/ break_, 828 /*CODEBLOCKID*/ codeblockid, 829 /*CALL*/ call, 830 /*CALLSTR*/ callstr, 831 /*CALLCLOSE*/ callclose, 832 /*CALLEND*/ callend, 833 /*CALLENDNPOP*/ callendnpop, 834 /*INCREMENT*/ addT, 835 /*GOTO_*/ addT, 836 /*GOTO_ID*/ addSpaceNT, 837 /*GOTO_END*/ goto_end, 838 /*GOTO_ENDNPOP*/ goto_endnpop, 839 /*COLON*/ colon, 840 /*COLONEND*/ colonend, 841 /*ARRAYINDEX*/ addT, 842 /*ARRAYINDEXEND*/ addT, 843 /*ASSIGNMENT*/ addSpaceNT, 844 /*NUMBER*/ addSpaceNT, 845 /*ASSIGNID*/ addT, 846 /*QUOTED_CHAR*/ quoted_char, 847 /*QUOTED_CHAR_SEMICOLON*/ quoted_char_semicolon, 848 /*SIZEOF_*/ addT, 849 /*IF_*/ if_, 850 /*ELSE_*/ addT, 851 /*FOR_*/ if_, 852 /*DO_*/ addT, 853 /*SWITCH_*/ if_, 854 /*SWITCH_BLOCK*/ switch_block, 855 /*CASE_*/ addT, 856 /*CASE_ID*/ addSpaceNT, 857 /*CASE_BLOCK*/ case_block, 858 /*BREAK_*/ break_, 859 /*SWITCH_BLOCKEND*/ switch_blockend, 860 /*RETURN_*/ if_, 861 /*RETURN_STR*/ return_str, 862 /*RETURN_END*/ return_end, 863 /*CODEBLOCKEND*/ codeblockend, 864 /*DO_END*/ do_end, 865 /*DO_FOR*/ do_for, 866 /*DO_CLOSE*/ do_close, 867 /*USE*/ use, 868 /*USEID*/ addT, 869 /*USEDOT*/ addT, 870 /*USECOMMA*/ usecomma, 871 /*USEEND*/ useend, 872 }; 873 874 stateFt STATEDEFAULTF[FINAL] = { 875 /*IDLE*/ idle, 876 /*TYPE*/ defaultInState, 877 /*TYPEID*/ defaultInState, 878 /*POINTERTYPE*/ defaultInState, 879 /*TYPEINIT*/ defaultInStateCopy, 880 /*TYPEINITSTR*/ defaultInState, 881 /*TYPEEND*/ defaultInState, 882 /*CONST_*/ defaultInState, 883 /*EXTERN_*/ defaultInState, 884 /*VOLATILE_*/ defaultInState, 885 /*STATIC_*/ defaultInState, 886 /*UNSIGNED_*/ defaultInState, 887 /*SIGNED_*/ defaultInState, 888 /*ENUM_*/ defaultInStateCopy, 889 /*ENUM_END*/ defaultInState, 890 /*TYPEDEF_*/ defaultInState, 891 /*TDSTRUCT*/ defaultInState, 892 /*STRUCTBLOCK*/ defaultInState, 893 /*STRUCTINBLOCK*/ defaultInState, 894 /*UNIONINSTRUCT*/ defaultInState, 895 /*STRUCTTYPE*/ defaultInState, 896 /*STRUCTTYPEID*/ defaultInState, 897 /*STRUCTTYPEEND*/ defaultInState, 898 /*STRUCTID*/ defaultInState, 899 /*STRUCTBLOCKEND*/ defaultInState, 900 /*UNIONBLOCK*/ defaultInState, 901 /*STRUCTINUNION*/ defaultInState, 902 /*UNIONINBLOCK*/ defaultInState, 903 /*UNIONTYPE*/ defaultInState, 904 /*UNIONTYPEID*/ defaultInState, 905 /*UNIONTYPEEND*/ defaultInState, 906 /*UNIONID*/ defaultInState, 907 /*UNIONBLOCKEND*/ defaultInState, 908 /*FUNCOPEN*/ defaultInStateCopy, 909 /*FUNCCLOSE*/ defaultInState, 910 /*PROTOTYPE*/ defaultInState, 911 /*CODEBLOCK*/ defaultInState, 912 /*CONTINUE_*/ defaultInState, 913 /*CODEBLOCKID*/ defaultInState, 914 /*CALL*/ defaultInStateCopy, 915 /*CALLSTR*/ defaultInState, 916 /*CALLCLOSE*/ defaultInState, 917 /*CALLEND*/ defaultInState, 918 /*CALLENDNPOP*/ defaultInState, 919 /*INCREMENT*/ defaultInState, 920 /*GOTO_*/ defaultInState, 921 /*GOTO_ID*/ defaultInState, 922 /*GOTO_END*/ defaultInState, 923 /*GOTO_ENDNPOP*/ defaultInState, 924 /*COLON*/ defaultInState, 925 /*COLONEND*/ defaultInState, 926 /*ARRAYINDEX*/ defaultInStateCopy, 927 /*ARRAYINDEXEND*/ defaultInState, 928 /*ASSIGNMENT*/ defaultInState, 929 /*NUMBER*/ defaultInState, 930 /*ASSIGNID*/ defaultInState, 931 /*QUOTED_CHAR*/ defaultInState, 932 /*QUOTED_CHAR_SEMICOLON*/ defaultInState, 933 /*SIZEOF_*/ defaultInState, 934 /*IF_*/ defaultInStateCopy, 935 /*ELSE_*/ defaultInState, 936 /*FOR_*/ defaultInStateCopy, 937 /*DO_*/ defaultInState, 938 /*SWITCH_*/ defaultInStateCopy, 939 /*SWITCH_BLOCK*/ defaultInState, 940 /*CASE_*/ defaultInState, 941 /*CASE_ID*/ defaultInState, 942 /*CASE_BLOCK*/ defaultInState, 943 /*BREAK_*/ defaultInState, 944 /*SWITCH_BLOCKEND*/ defaultInState, 945 /*RETURN_*/ defaultInStateCopy, 946 /*RETURN_STR*/ defaultInState, 947 /*RETURN_END*/ defaultInState, 948 /*CODEBLOCKEND*/ defaultInState, 949 /*DO_END*/ defaultInState, 950 /*DO_FOR*/ defaultInStateCopy, 951 /*DO_CLOSE*/ defaultInState, 952 /*USE*/ defaultInState, 953 /*USEID*/ defaultInState, 954 /*USEDOT*/ defaultInState, 955 /*USECOMMA*/ defaultInState, 956 /*USEEND*/ defaultInState, 957 }; 958