yacc.y 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. %{
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "yacc.tab.h"
  5. #include "symtable.h"
  6. #include "ast_node.h"
  7. #include "parser.h"
  8. #include <unistd.h>
  9. #include "structtable.h"
  10. #include <stdlib.h>
  11. // line number (got from lex.l)
  12. extern int linenum;
  13. // buffer for general use
  14. #define DD_BUFFER_SIZE 1000
  15. char buffer[DD_BUFFER_SIZE];
  16. // error
  17. void yyerror(const char *str)
  18. {
  19. fprintf(stderr,"error: line %d: %s\n", linenum, str);
  20. _exit(-1);
  21. }
  22. // game node, parent of all nodes
  23. struct ast_node *game_node;
  24. /* compiler flags
  25. * debug_symbol_table: print details of the symbol table
  26. * debug_struct_table: print details of the struct table
  27. * debug_ast: print the abstract syntax tree
  28. */
  29. int debug_symbol_table = 0;
  30. int debug_struct_table = 0;
  31. int debug_ast = 0;
  32. char *srcfile = 0;
  33. // init data, parse, exit
  34. int main(int argc, char *argv[])
  35. {
  36. /* handle arguments
  37. * currently they can only allow printing of debugging information
  38. */
  39. int i = 1;
  40. while (i < argc) {
  41. if (strcmp(argv[i], "--debug") == 0) {
  42. debug_symbol_table = 1;
  43. debug_struct_table = 1;
  44. debug_ast = 1;
  45. }
  46. else if (strcmp(argv[i], "--debug-symbol-table") == 0) {
  47. debug_symbol_table = 1;
  48. }
  49. else if (strcmp(argv[i], "--debug-struct-table") == 0) {
  50. debug_struct_table = 1;
  51. }
  52. else if (strcmp(argv[i], "--debug-ast") == 0) {
  53. debug_ast = 1;
  54. }
  55. // no specific argument found, assume that's source file
  56. else {
  57. srcfile = argv[i];
  58. }
  59. // next argument
  60. i++;
  61. } // done parsing arguments
  62. if (srcfile == 0) {
  63. printf("please supply a source file!\n");
  64. return -1;
  65. }
  66. // init data
  67. linenum = 1;
  68. // initial symbols
  69. if (!symtable_init()) {
  70. fprintf(stderr, "yacc: unable to initialise symbol table\n");
  71. return -1;
  72. }
  73. if (symtable_insert("DD_WIDTH", DD_INTERNAL_WIDTH) == -1
  74. || symtable_insert("DD_HEIGHT", DD_INTERNAL_HEIGHT) == -1) {
  75. fprintf(stderr, "yacc: unable to add symbol to symbol table\n");
  76. return -1;
  77. }
  78. game_node = ast_create(AST_GAME, 0);
  79. // init structs
  80. struct struct_entry *temp_entry = malloc(sizeof(struct struct_entry));
  81. temp_entry->name = "dd_world";
  82. struct_insert(temp_entry);
  83. temp_entry = malloc(sizeof(struct struct_entry));
  84. temp_entry->name = "dd_sprite";
  85. struct_insert(temp_entry);
  86. temp_entry = malloc(sizeof(struct struct_entry));
  87. temp_entry->name = "dd_vector2d";
  88. struct_insert(temp_entry);
  89. // parse!
  90. yyparse();
  91. // parse resulting ast tree to a file
  92. parse(argv[1], game_node);
  93. // print debug data
  94. if (debug_symbol_table) {
  95. symtable_print();
  96. }
  97. if (debug_struct_table) {
  98. struct_print();
  99. }
  100. if (debug_ast) {
  101. ast_print(game_node);
  102. }
  103. // clean everything
  104. symtable_clean();
  105. ast_delete(game_node);
  106. // success!
  107. return 0;
  108. }
  109. %}
  110. /* keywords */
  111. %token DD_KEYWORD_INT DD_KEYWORD_FLOAT DD_KEYWORD_STRUCT DD_KEYWORD_OVERRIDE DD_KEYWORD_IF DD_KEYWORD_VOID
  112. /* internal variables */
  113. %token DD_INTERNAL_WIDTH DD_INTERNAL_HEIGHT
  114. /* constants */
  115. %token DD_CONSTANT_SYMBOL DD_CONSTANT_STRING DD_CONSTANT_NUMBER
  116. /* operators */
  117. %token DD_OPERATOR_EQ DD_OPERATOR_LE DD_OPERATOR_GE
  118. /* associativity */
  119. %left '='
  120. %left '+' '-'
  121. %left '*' '/'
  122. %left '>' '<' DD_OPERATOR_EQ DD_OPERATOR_LE DD_OPERATOR_GE
  123. %%
  124. /* each rule creates a node,
  125. * possibly with children nodes,
  126. * all non-terminals are nodes that can be obtained with ast_pop() (left to right)
  127. */
  128. /* the game itself, contains statements
  129. */
  130. game:
  131. statements {
  132. ast_child_add(game_node, ast_pop());
  133. }
  134. ;
  135. statements:
  136. statement statements_additional {
  137. // add statement to group
  138. struct ast_node *group = ast_pop();
  139. struct ast_node *statement = ast_pop();
  140. ast_child_add_first(group, statement);
  141. ast_push(group);
  142. }
  143. ;
  144. statements_additional:
  145. { ast_push( ast_create(AST_GROUP, 0) ); }
  146. | statement statements_additional {
  147. // add statement to group
  148. struct ast_node *group = ast_pop();
  149. struct ast_node *statement = ast_pop();
  150. ast_child_add_first(group, statement);
  151. ast_push(group);
  152. }
  153. ;
  154. statement:
  155. /* definition statement
  156. */
  157. definition
  158. |
  159. /* define struct
  160. * takes all definitions, and adds them to the struct table
  161. */
  162. DD_KEYWORD_STRUCT DD_CONSTANT_SYMBOL struct_parent '{' definitions '}' ';' {
  163. // get symbol in symbol table
  164. struct entry *e = symtable_entryat($2);
  165. if (!e) {
  166. fprintf(stderr, "yacc: struct definition: could not find symtable entry at %d\n", $2);
  167. exit(-1);
  168. }
  169. // check if its already defined, if not define it, if yes error
  170. if (e->token == DD_CONSTANT_SYMBOL) {
  171. e->token = DD_KEYWORD_STRUCT;
  172. }
  173. else {
  174. snprintf(buffer, DD_BUFFER_SIZE, "'%s' is already defined", e->lexptr);
  175. yyerror(buffer);
  176. }
  177. // create new struct entry based on symbol table
  178. struct struct_entry se;
  179. se.name = e->lexptr;
  180. se.parent = 0;
  181. // group node has all definitions
  182. struct ast_node *group = ast_pop();
  183. // if parent exists
  184. struct ast_node *parent = ast_pop();
  185. if (parent->node_type == AST_STRUCT_PARENT) {
  186. se.parent = parent->value;
  187. }
  188. else {
  189. se.parent = -1;
  190. }
  191. int struct_index = struct_insert(&se);
  192. // create struct node and add definitions as child
  193. /*
  194. group->node_type = AST_STRUCT;
  195. group->value = struct_index;
  196. */
  197. struct ast_node *n = ast_create(AST_STRUCT, struct_index);
  198. ast_child_add(n, group);
  199. // push to ast tree
  200. ast_push(n);
  201. }
  202. |
  203. /* if statement */
  204. DD_KEYWORD_IF '(' expression ')' '{' statements '}' {
  205. struct ast_node *expression;
  206. struct ast_node *statements;
  207. struct ast_node *ifnode = ast_create(AST_IF, 0);
  208. statements = ast_pop();
  209. expression = ast_pop();
  210. ast_child_add(ifnode, expression);
  211. ast_child_add(ifnode, statements);
  212. ast_push(ifnode);
  213. }
  214. |
  215. expression ';' {
  216. struct ast_node *group = ast_create(AST_GROUP_STATEMENTS, 0);
  217. ast_child_add(group, ast_pop());
  218. ast_push(group);
  219. }
  220. ;
  221. definitions:
  222. { ast_push( ast_create(AST_GROUP, 0) ); }
  223. | definitions definition {
  224. struct ast_node *n;
  225. struct ast_node *c;
  226. c = ast_pop();
  227. n = ast_pop();
  228. ast_child_add(n, c);
  229. ast_push(n);
  230. }
  231. ;
  232. definition:
  233. /* definition
  234. * define a new variable
  235. * error if variable is already defined
  236. */
  237. variable_type DD_CONSTANT_SYMBOL ';' {
  238. // get variable type
  239. struct ast_node *vartype = ast_pop();
  240. // get symbol in symbol table
  241. struct entry *e = symtable_entryat($2);
  242. if (!e) {
  243. fprintf(stderr, "yacc: variable definition: could not find symtable entry at %d\n", $2);
  244. exit(-1);
  245. }
  246. // check if its already defined, if not define it, if yes error
  247. if (e->token == DD_CONSTANT_SYMBOL) {
  248. // variable type is void
  249. if (vartype->node_type == AST_VARTYPE_VOID) {
  250. e->token = DD_KEYWORD_VOID;
  251. }
  252. else
  253. // variable type is an int
  254. if (vartype->node_type == AST_VARTYPE_INT) {
  255. e->token = DD_KEYWORD_INT;
  256. }
  257. else
  258. // variable type is a float
  259. if (vartype->node_type == AST_VARTYPE_FLOAT) {
  260. e->token = DD_KEYWORD_FLOAT;
  261. }
  262. else
  263. // variable type is a struct
  264. if (vartype->node_type == AST_VARTYPE_STRUCT) {
  265. e->token = DD_KEYWORD_STRUCT;
  266. e->value = vartype->value;
  267. }
  268. }
  269. else {
  270. snprintf(buffer, DD_BUFFER_SIZE, "'%s' is already defined", e->lexptr);
  271. yyerror(buffer);
  272. }
  273. // create a definition node
  274. struct ast_node *n = ast_create(AST_DEFINITION, 0);
  275. // that has the to-be defined variable as child
  276. struct ast_node *c = ast_create(AST_IDENTIFIER, $2);
  277. ast_child_add(n, c);
  278. // add it to the game
  279. ast_push(n);
  280. }
  281. |
  282. /* function definition */
  283. variable_type DD_CONSTANT_SYMBOL '(' function_arguments_decleration ')' '{' statements '}' ';' {
  284. // get variable type
  285. struct ast_node *statements = ast_pop();
  286. struct ast_node *arguments = ast_pop();
  287. struct ast_node *vartype = ast_pop();
  288. struct entry *function = symtable_entryat($2);
  289. if (!function) {
  290. fprintf(stderr, "yacc: function definition: could not find symtable entry at %d\n", $2);
  291. exit(-1);
  292. }
  293. function->value = 0;
  294. struct ast_node *n = ast_create(AST_FUNCTION_DEFINITION, $2);
  295. ast_child_add(n, arguments);
  296. ast_child_add(n, statements);
  297. ast_push(n);
  298. }
  299. |
  300. DD_KEYWORD_OVERRIDE variable_type DD_CONSTANT_SYMBOL '(' function_arguments_decleration ')' '{' statements '}' ';' {
  301. // get variable type
  302. struct ast_node *statements = ast_pop();
  303. struct ast_node *arguments = ast_pop();
  304. struct ast_node *vartype = ast_pop();
  305. struct entry *function = symtable_entryat($3);
  306. if (!function) {
  307. fprintf(stderr, "yacc: override function definition: could not find symtable entry at %d\n", $3);
  308. exit(-1);
  309. }
  310. function->value = 1;
  311. struct ast_node *n = ast_create(AST_FUNCTION_DEFINITION, $3);
  312. ast_child_add(n, arguments);
  313. ast_child_add(n, statements);
  314. ast_push(n);
  315. }
  316. ;
  317. expression:
  318. expression '=' expression {
  319. struct ast_node *n = ast_create(AST_ASSIGNMENT, '=');
  320. struct ast_node *exp = ast_pop();
  321. struct ast_node *term = ast_pop();
  322. ast_child_add(n, term);
  323. ast_child_add(n, exp);
  324. ast_push(n);
  325. }
  326. |
  327. expression '>' expression {
  328. struct ast_node *n = ast_create(AST_OPERATOR_BINARY, '>');
  329. struct ast_node *exp = ast_pop();
  330. struct ast_node *term = ast_pop();
  331. ast_child_add(n, term);
  332. ast_child_add(n, exp);
  333. ast_push(n);
  334. }
  335. |
  336. expression '<' expression {
  337. struct ast_node *n = ast_create(AST_OPERATOR_BINARY, '<');
  338. struct ast_node *exp = ast_pop();
  339. struct ast_node *term = ast_pop();
  340. ast_child_add(n, term);
  341. ast_child_add(n, exp);
  342. ast_push(n);
  343. }
  344. |
  345. expression DD_OPERATOR_EQ expression {
  346. struct ast_node *n = ast_create(AST_OPERATOR_BINARY, DD_OPERATOR_EQ);
  347. struct ast_node *exp = ast_pop();
  348. struct ast_node *term = ast_pop();
  349. ast_child_add(n, term);
  350. ast_child_add(n, exp);
  351. ast_push(n);
  352. }
  353. |
  354. expression DD_OPERATOR_LE expression {
  355. struct ast_node *n = ast_create(AST_OPERATOR_BINARY, DD_OPERATOR_LE);
  356. struct ast_node *exp = ast_pop();
  357. struct ast_node *term = ast_pop();
  358. ast_child_add(n, term);
  359. ast_child_add(n, exp);
  360. ast_push(n);
  361. }
  362. |
  363. expression DD_OPERATOR_GE expression {
  364. struct ast_node *n = ast_create(AST_OPERATOR_BINARY, DD_OPERATOR_GE);
  365. struct ast_node *exp = ast_pop();
  366. struct ast_node *term = ast_pop();
  367. ast_child_add(n, term);
  368. ast_child_add(n, exp);
  369. ast_push(n);
  370. }
  371. |
  372. expression '+' expression {
  373. struct ast_node *n = ast_create( AST_OPERATOR_BINARY, '+');
  374. struct ast_node *exp = ast_pop();
  375. struct ast_node *term = ast_pop();
  376. ast_child_add(n, term);
  377. ast_child_add(n, exp);
  378. ast_push(n);
  379. }
  380. |
  381. expression '-' expression {
  382. struct ast_node *n = ast_create( AST_OPERATOR_BINARY, '-');
  383. struct ast_node *exp = ast_pop();
  384. struct ast_node *term = ast_pop();
  385. ast_child_add(n, term);
  386. ast_child_add(n, exp);
  387. ast_push(n);
  388. }
  389. |
  390. expression '*' expression {
  391. struct ast_node *n = ast_create(AST_OPERATOR_BINARY, '*');
  392. struct ast_node *exp = ast_pop();
  393. struct ast_node *term = ast_pop();
  394. ast_child_add(n, term);
  395. ast_child_add(n, exp);
  396. ast_push(n);
  397. }
  398. |
  399. expression '/' expression {
  400. struct ast_node *n = ast_create(AST_OPERATOR_BINARY, '/');
  401. struct ast_node *exp = ast_pop();
  402. struct ast_node *term = ast_pop();
  403. ast_child_add(n, term);
  404. ast_child_add(n, exp);
  405. ast_push(n);
  406. }
  407. |
  408. '(' expression ')' {
  409. struct ast_node *n = ast_create(AST_GROUP_EXPRESSIONS, 0);
  410. struct ast_node *child = ast_pop();
  411. ast_child_add(n, child);
  412. ast_push(n);
  413. }
  414. |
  415. factor
  416. ;
  417. factor:
  418. DD_CONSTANT_NUMBER { ast_push( ast_create(AST_NUMBER, $1) ); }
  419. |
  420. DD_CONSTANT_STRING { ast_push( ast_create(AST_STRING, $1) ); }
  421. |
  422. variable optional_variable_function {
  423. struct ast_node *arguments = ast_pop();
  424. struct ast_node *variable = ast_pop();
  425. if (arguments->node_type == AST_EMPTY) {
  426. ast_push(variable);
  427. }
  428. else {
  429. struct ast_node *n = ast_create(AST_FUNCTION_CALL, variable->value);
  430. ast_child_add(n, variable);
  431. ast_child_add(n, arguments);
  432. ast_push(n);
  433. }
  434. }
  435. ;
  436. variable_type:
  437. DD_KEYWORD_VOID { $$ = DD_KEYWORD_VOID; ast_push( ast_create(AST_VARTYPE_VOID, 0) ); }
  438. |
  439. DD_KEYWORD_INT { $$ = DD_KEYWORD_INT; ast_push( ast_create(AST_VARTYPE_INT, 0) ); }
  440. |
  441. DD_KEYWORD_FLOAT { $$ = DD_KEYWORD_FLOAT; ast_push( ast_create(AST_VARTYPE_FLOAT, 0) ); }
  442. |
  443. DD_KEYWORD_STRUCT DD_CONSTANT_SYMBOL {
  444. $$ = DD_KEYWORD_STRUCT;
  445. struct entry *e = symtable_entryat($2);
  446. if (!e) {
  447. fprintf(stderr, "yacc: struct variable type: could not find symtable entry at %d\n", $2);
  448. exit(-1);
  449. }
  450. ast_push( ast_create(AST_VARTYPE_STRUCT, struct_lookup(e->lexptr)) );
  451. }
  452. ;
  453. struct_parent:
  454. { ast_push( ast_create(AST_EMPTY, 0) ); }
  455. |
  456. ':' DD_CONSTANT_SYMBOL {
  457. struct entry *e = symtable_entryat($2);
  458. if (!e) {
  459. fprintf(stderr, "yacc: struct parent variable type: could not find symtable entry at %d\n", $2);
  460. exit(-1);
  461. }
  462. ast_push( ast_create(AST_STRUCT_PARENT, struct_lookup(e->lexptr)) );
  463. }
  464. ;
  465. optional_variable_function:
  466. { ast_push( ast_create(AST_EMPTY, 0) ); }
  467. |
  468. '(' function_arguments_call ')' {
  469. }
  470. ;
  471. variable:
  472. DD_CONSTANT_SYMBOL {
  473. ast_push( ast_create(AST_IDENTIFIER, $1 ));
  474. }
  475. variable_additional
  476. ;
  477. variable_additional:
  478. | variable_additional '.' DD_CONSTANT_SYMBOL {
  479. struct ast_node *n = ast_pop();
  480. ast_child_add(n, ast_create(AST_IDENTIFIER, $3));
  481. ast_push(n);
  482. $$ = $3;
  483. }
  484. ;
  485. function_arguments_decleration:
  486. { ast_push( ast_create(AST_GROUP, 0) ); }
  487. |
  488. variable_type DD_CONSTANT_SYMBOL function_arguments_decleration_additional {
  489. struct ast_node *n = ast_pop();
  490. struct ast_node *vartype = ast_pop();
  491. struct entry *esymbol = symtable_entryat($2);
  492. if (!esymbol) {
  493. fprintf(stderr, "yacc: function arguments declaration: could not find symtable entry at %d\n", $2);
  494. exit(-1);
  495. }
  496. esymbol->token = $1;
  497. ast_child_add_first(n, ast_create(AST_IDENTIFIER, $2));
  498. ast_push(n);
  499. }
  500. ;
  501. function_arguments_decleration_additional:
  502. { ast_push( ast_create(AST_GROUP, 0) ); }
  503. |
  504. ',' variable_type DD_CONSTANT_SYMBOL function_arguments_decleration_additional {
  505. struct ast_node *n = ast_pop();
  506. struct ast_node *vartype = ast_pop();
  507. struct entry *esymbol = symtable_entryat($3);
  508. if (!esymbol) {
  509. fprintf(stderr, "yacc: function arguments declaration: could not find symtable entry at %d\n", $3);
  510. exit(-1);
  511. }
  512. esymbol->token = $2;
  513. ast_child_add_first(n, ast_create(AST_IDENTIFIER, $3));
  514. ast_push(n);
  515. }
  516. ;
  517. function_arguments_call:
  518. { ast_push( ast_create(AST_GROUP, 0) ); }
  519. |
  520. expression function_arguments_call_additional {
  521. struct ast_node *n = ast_pop();
  522. struct ast_node *expression = ast_pop();
  523. ast_child_add_first(n, expression);
  524. ast_push(n);
  525. }
  526. ;
  527. function_arguments_call_additional:
  528. { ast_push( ast_create(AST_GROUP, 0) ); }
  529. |
  530. ',' expression function_arguments_call_additional {
  531. struct ast_node *n = ast_pop();
  532. struct ast_node *expression = ast_pop();
  533. ast_child_add_first(n, expression);
  534. ast_push(n);
  535. }
  536. ;