Iniciado trabalho com llvm_codegen_visitor.
[toypasc.git] / parser.y
blob49709004b6830838512e49b4f0b0c0382ce3bbb8
1 %{
2 #include <ctype.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include "base.h"
7 #include "parser.h"
8 #include "ast.h"
9 #include "symbol_table.h"
11 #include "typecheck_visitor.h"
12 #include "simpleprinter_visitor.h"
13 #include "graphprinter_visitor.h"
14 #include "c_codegen_visitor.h"
16 bool simple_flag = FALSE;
17 bool graph_flag = FALSE;
18 bool c_flag = FALSE;
19 bool llvm_flag = FALSE;
20 //char *output = NULL;
22 int opts;
24 /*extern char *yytext;*/
25 extern FILE *yyin;
27 static void yyerror (/*YYLTYPE *locp, */const char *msg);
28 /*int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param);*/
30 static struct AstNode *ast;
33 %defines
34 %locations
35 %pure-parser
36 %error-verbose
37 /*%parse-param {ValaParser *parser}
38 %lex-param {ValaParser *parser}*/
40 %union {
41 char* lexeme;
42 int integer;
43 int boolean;
44 char character;
45 int type;
46 struct AstNode *astnode;
49 /* Tokens */
50 %left <lexeme> T_OR
51 %left <lexeme> T_AND
52 %left <lexeme> T_EQUAL T_NOTEQUAL
53 %left <lexeme> T_LESSER T_GREATER T_LESSEREQUAL T_GREATEREQUAL
54 %left <lexeme> T_PLUS T_MINUS
55 %left <lexeme> T_STAR T_SLASH
56 %left <lexeme> T_NOT
58 %token T_PROGRAM
59 %token T_VAR
60 %token T_PROCEDURE
61 %token T_FUNCTION
62 %token T_BEGIN
63 %token T_END
65 %token T_IF
66 %token T_THEN
67 %token T_ELSE
68 %token T_WHILE
69 %token T_FOR
70 %token T_TO
71 %token T_DO
73 %token T_ASSIGNMENT
75 %token T_LPAR
76 %token T_RPAR
77 %token T_SEMICOLON
78 %token T_COLON
79 %token T_COMMA
80 %token T_DOT
82 %token T_PRINT_INT
83 %token T_PRINT_CHAR
84 %token T_PRINT_BOOL
85 %token T_PRINT_LINE
87 %token <type> TYPE_IDENTIFIER
88 %token <lexeme> IDENTIFIER
89 %token <integer> INT_LITERAL
90 %token <boolean> BOOL_LITERAL
91 %token <character> CHAR_LITERAL
93 /* Tipos das Regras */
94 %type <astnode> Program
95 %type <astnode> ProgramDecl
96 %type <astnode> VarDeclList
97 %type <astnode> MultiVarDecl
98 %type <astnode> VarDecl
99 %type <astnode> IdentifierList
100 %type <astnode> MultiIdentifier
101 %type <astnode> SingleIdentifier
103 %type <astnode> ProcFuncList
104 %type <astnode> MultiProcFuncDecl
105 %type <astnode> ProcFuncDecl
106 %type <astnode> ProcDecl
107 %type <astnode> FuncDecl
108 %type <astnode> ParamList
109 %type <astnode> SingleParam
110 %type <astnode> MultiParam
112 %type <astnode> ProgramBody
113 %type <astnode> Statements
114 %type <astnode> StatementList
115 %type <astnode> MultiStatement
116 %type <astnode> Statement
117 %type <astnode> IfStatement
118 %type <astnode> ElseStatement
119 %type <astnode> WhileStatement
120 %type <astnode> ForStatement
121 %type <astnode> PrintStatement
122 %type <astnode> PrintCharStatement
123 %type <astnode> PrintIntStatement
124 %type <astnode> PrintBoolStatement
125 %type <astnode> PrintLineStatement
127 %type <astnode> Expression
128 %type <astnode> SimpleExpression
129 %type <astnode> NotFactor
130 %type <astnode> Factor
131 %type <astnode> Term
133 %type <astnode> Call
134 %type <astnode> CallParamList
135 %type <astnode> MultiCallParam
137 %type <astnode> Assignment
138 %type <astnode> Identifier
139 %type <astnode> Literal
141 %type <astnode> AddOp
142 %type <astnode> MulOp
143 %type <astnode> RelOp
144 %type <astnode> NotOp
146 %start Program
149 Program:
150 ProgramDecl VarDeclList ProcFuncList ProgramBody
152 struct AstNode *ast_node;
154 ast_node = ast_node_new("Program", PROGRAM, VOID,
155 yylloc.last_line, NULL);
156 ast_node_add_child(ast_node, $1); // ProgramDecl
157 ast_node_add_child(ast_node, $2); // VarDeclList
158 ast_node_add_child(ast_node, $3); // ProcFuncList
159 ast_node_add_child(ast_node, $4); // ProgramBody
160 $$ = ast_node;
162 ast = ast_node;
166 ProgramDecl:
167 T_PROGRAM Identifier T_SEMICOLON
169 struct AstNode *ast_node;
170 ast_node = ast_node_new("ProgramDecl", PROGRAM_DECL, VOID,
171 yylloc.last_line, NULL);
172 ast_node_add_child(ast_node, $2);
173 $$ = ast_node;
177 VarDeclList:
178 /* empty */ { $$ = NULL; }
179 | MultiVarDecl
181 struct AstNode *ast_node;
182 ast_node = ast_node_new("VarDeclList", VARDECL_LIST, VOID,
183 yylloc.last_line, NULL);
184 ast_node_add_child(ast_node, $1);
185 $$ = ast_node;
189 MultiVarDecl:
190 /* empty */ { $$ = NULL; }
191 | VarDecl MultiVarDecl
193 ast_node_add_sibling($1, $2);
194 $$ = $1;
198 VarDecl:
199 T_VAR IdentifierList T_COLON TYPE_IDENTIFIER T_SEMICOLON
201 struct AstNode *ast_node;
202 ast_node = ast_node_new("VarDecl", VARDECL, $4,
203 yylloc.last_line, NULL);
204 ast_node_add_child(ast_node, $2);
205 $$ = ast_node;
209 IdentifierList:
210 SingleIdentifier MultiIdentifier
212 struct AstNode *ast_node;
213 ast_node = ast_node_new("IdentifierList", IDENT_LIST, VOID,
214 yylloc.last_line, NULL);
215 ast_node_add_sibling($1, $2);
216 ast_node_add_child(ast_node, $1);
217 $$ = ast_node;
221 MultiIdentifier:
222 /* empty */ { $$ = NULL; }
223 | T_COMMA SingleIdentifier MultiIdentifier
225 ast_node_add_sibling($2, $3);
226 $$ = $2;
230 SingleIdentifier:
231 Identifier { $$ = $1; }
235 ProcFuncList:
236 /* empty */ { $$ = NULL; }
237 | ProcFuncDecl MultiProcFuncDecl
239 struct AstNode *ast_node;
240 ast_node = ast_node_new("ProcFuncList", PROCFUNC_LIST, VOID,
241 yylloc.last_line, NULL);
242 ast_node_add_sibling($1, $2);
243 ast_node_add_child(ast_node, $1);
244 $$ = ast_node;
248 MultiProcFuncDecl:
249 /* empty */ { $$ = NULL; }
250 | ProcFuncDecl MultiProcFuncDecl
252 ast_node_add_sibling($1, $2);
253 $$ = $1;
257 ProcFuncDecl:
258 ProcDecl { $$ = $1; }
259 | FuncDecl { $$ = $1; }
262 ProcDecl:
263 T_PROCEDURE Identifier T_LPAR ParamList T_RPAR T_SEMICOLON VarDeclList
264 T_BEGIN StatementList T_END T_SEMICOLON
266 Symbol *symtab;
267 struct AstNode *ast_node;
269 ast_node = ast_node_new("ProcDecl", PROCEDURE, VOID,
270 yylloc.last_line, NULL);
271 ast_node_add_child(ast_node, $2); // Identifier
272 ast_node_add_child(ast_node, $4); // ParamList
273 ast_node_add_child(ast_node, $7); // VarDeclList
274 ast_node_add_child(ast_node, $9); // Statements
276 ast_node->symbol = symbol_new(NULL);
278 $$ = ast_node;
282 FuncDecl:
283 T_FUNCTION Identifier T_LPAR ParamList T_RPAR T_COLON TYPE_IDENTIFIER
284 T_SEMICOLON VarDeclList T_BEGIN StatementList T_END T_SEMICOLON
286 Symbol *symtab;
287 struct AstNode *ast_node;
288 struct AstNode *id = (struct AstNode *) $2;
290 ast_node = ast_node_new("FuncDecl", FUNCTION, $7,
291 yylloc.last_line, NULL);
292 ast_node_add_child(ast_node, id); // Identifier
293 ast_node_add_child(ast_node, $4); // ParamList
294 ast_node_add_child(ast_node, $9); // VarDeclList
295 ast_node_add_child(ast_node, $11); // Statements
297 id->symbol->type = $7;
299 ast_node->symbol = symbol_new(NULL);
301 $$ = ast_node;
305 ParamList:
306 /* empty */ { $$ = NULL; }
307 | SingleParam MultiParam
309 struct AstNode *ast_node;
310 ast_node = ast_node_new("ParamList", PARAM_LIST, VOID,
311 yylloc.last_line, NULL);
312 ast_node_add_sibling($1, $2);
313 ast_node_add_child(ast_node, $1);
314 $$ = ast_node;
318 MultiParam:
319 /* empty */ { $$ = NULL; }
320 | T_COMMA SingleParam MultiParam
322 ast_node_add_sibling($2, $3);
323 $$ = $2;
327 SingleParam:
328 Identifier T_COLON TYPE_IDENTIFIER
330 struct AstNode *ast_node;
331 ast_node = ast_node_new("SingleParam", PARAMETER, $3,
332 yylloc.last_line, NULL);
333 ast_node_add_child(ast_node, $1); // Identifier
334 $$ = ast_node;
338 ProgramBody:
339 /* empty */ { $$ = NULL; }
340 | T_BEGIN StatementList T_END T_DOT { $$ = $2; }
343 Statements:
344 Statement { $$ = $1; }
345 | T_BEGIN StatementList T_END { $$ = $2; }
348 StatementList:
349 /* empty */ { $$ = NULL; }
350 | Statement MultiStatement
352 struct AstNode *ast_node;
353 ast_node = ast_node_new("StatementList", STATEMENT_LIST, VOID,
354 yylloc.last_line, NULL);
355 ast_node_add_sibling($1, $2);
356 ast_node_add_child(ast_node, $1);
357 $$ = ast_node;
361 MultiStatement:
362 /* empty */ { $$ = NULL; }
363 | T_SEMICOLON Statement MultiStatement
365 ast_node_add_sibling($2, $3);
366 $$ = $2;
370 Statement:
371 Assignment { $$ = $1; }
372 | IfStatement { $$ = $1; }
373 | WhileStatement { $$ = $1; }
374 | ForStatement { $$ = $1; }
375 | Call { $$ = $1; }
376 | PrintStatement { $$ = $1; }
379 PrintStatement:
380 PrintIntStatement { $$ = $1; }
381 | PrintCharStatement { $$ = $1; }
382 | PrintBoolStatement { $$ = $1; }
383 | PrintLineStatement { $$ = $1; }
386 PrintIntStatement:
387 T_PRINT_INT T_LPAR Expression T_RPAR
389 struct AstNode *ast_node;
390 ast_node = ast_node_new("PrintIntStatement", PRINTINT_STMT, VOID,
391 yylloc.last_line, NULL);
392 ast_node_add_child(ast_node, $3);
393 $$ = ast_node;
397 PrintCharStatement:
398 T_PRINT_CHAR T_LPAR Expression T_RPAR
400 struct AstNode *ast_node;
401 ast_node = ast_node_new("PrintCharStatement", PRINTCHAR_STMT, VOID,
402 yylloc.last_line, NULL);
403 ast_node_add_child(ast_node, $3);
404 $$ = ast_node;
408 PrintBoolStatement:
409 T_PRINT_BOOL T_LPAR Expression T_RPAR
411 struct AstNode *ast_node;
412 ast_node = ast_node_new("PrintBoolStatement", PRINTBOOL_STMT, VOID,
413 yylloc.last_line, NULL);
414 ast_node_add_child(ast_node, $3);
415 $$ = ast_node;
419 PrintLineStatement:
420 T_PRINT_LINE T_LPAR T_RPAR
422 struct AstNode *ast_node;
423 ast_node = ast_node_new("PrintLineStatement", PRINTLINE_STMT, VOID,
424 yylloc.last_line, NULL);
425 $$ = ast_node;
429 Assignment:
430 Identifier T_ASSIGNMENT Expression
432 struct AstNode *ast_node;
433 ast_node = ast_node_new("Assignment", ASSIGNMENT_STMT, VOID,
434 yylloc.last_line, NULL);
435 ast_node_add_child(ast_node, $1);
436 ast_node_add_child(ast_node, $3);
437 $$ = ast_node;
441 IfStatement:
442 T_IF Expression T_THEN Statements ElseStatement
444 struct AstNode *ast_node;
445 ast_node = ast_node_new("IfStatement", IF_STMT, VOID,
446 yylloc.last_line, NULL);
447 ast_node_add_child(ast_node, $2);
448 ast_node_add_child(ast_node, $4);
449 ast_node_add_child(ast_node, $5);
450 $$ = ast_node;
454 ElseStatement:
455 /* empty */ { $$ = NULL; }
456 | T_ELSE Statements { $$ = $2; }
459 WhileStatement:
460 T_WHILE Expression T_DO Statements
462 struct AstNode *ast_node;
463 ast_node = ast_node_new("WhileStatement", WHILE_STMT, VOID,
464 yylloc.last_line, NULL);
465 ast_node_add_child(ast_node, $2);
466 ast_node_add_child(ast_node, $4);
467 $$ = ast_node;
471 ForStatement:
472 T_FOR Assignment T_TO Expression T_DO Statements
474 struct AstNode *ast_node;
475 ast_node = ast_node_new("ForStatement", FOR_STMT, VOID,
476 yylloc.last_line, NULL);
477 ast_node_add_child(ast_node, $2); // Assignment
478 ast_node_add_child(ast_node, $4); // Expression
479 ast_node_add_child(ast_node, $6); // Statements
480 $$ = ast_node;
484 Expression:
485 SimpleExpression { $$ = $1; }
486 | SimpleExpression RelOp SimpleExpression
488 struct AstNode *ast_node;
489 ast_node = ast_node_new("RelExpression", REL_EXPR, BOOLEAN,
490 yylloc.last_line, NULL);
491 ast_node_add_child(ast_node, $1);
492 ast_node_add_child(ast_node, $2);
493 ast_node_add_child(ast_node, $3);
494 $$ = ast_node;
498 SimpleExpression:
499 Term { $$ = $1; }
500 | SimpleExpression AddOp Term
502 struct AstNode *ast_node;
503 Type type = ((struct AstNode *) $2)->type;
505 ast_node = ast_node_new("AddExpression", ADD_EXPR, type,
506 yylloc.last_line, NULL);
507 ast_node_add_child(ast_node, $1);
508 ast_node_add_child(ast_node, $2);
509 ast_node_add_child(ast_node, $3);
510 $$ = ast_node;
514 Term:
515 NotFactor { $$ = $1; }
516 | Term MulOp NotFactor
518 struct AstNode *ast_node;
519 Type type = ((struct AstNode *) $2)->type;
521 ast_node = ast_node_new("MulExpression", MUL_EXPR, type,
522 yylloc.last_line, NULL);
523 ast_node_add_child(ast_node, $1);
524 ast_node_add_child(ast_node, $2);
525 ast_node_add_child(ast_node, $3);
526 $$ = ast_node;
530 NotFactor:
531 Factor { $$ = $1; }
532 | NotOp Factor
534 struct AstNode *ast_node;
535 struct AstNode *op_ast_node;
536 ast_node = ast_node_new("NotFactor", NOTFACTOR, BOOLEAN,
537 yylloc.last_line, NULL);
538 ast_node_add_child(ast_node, $1);
539 ast_node_add_child(ast_node, $2);
540 $$ = ast_node;
544 Factor:
545 Identifier { $$ = $1; }
546 | Literal { $$ = $1; }
547 | Call { $$ = $1; }
548 | T_LPAR Expression T_RPAR { $$ = $2; }
551 Call:
552 Identifier T_LPAR CallParamList T_RPAR
554 struct AstNode *ast_node;
555 ast_node = ast_node_new("Call", CALL, VOID,
556 yylloc.last_line, NULL);
557 ast_node_add_child(ast_node, $1);
558 ast_node_add_child(ast_node, $3);
559 $$ = ast_node;
563 CallParamList:
564 /* empty */ { $$ = NULL; }
565 | Expression MultiCallParam
567 struct AstNode *ast_node;
568 ast_node = ast_node_new("CallParamList", CALLPARAM_LIST, VOID,
569 yylloc.last_line, NULL);
570 ast_node_add_sibling($1, $2);
571 ast_node_add_child(ast_node, $1);
572 $$ = ast_node;
576 MultiCallParam:
577 /* empty */ { $$ = NULL; }
578 | T_COMMA Expression MultiCallParam
580 ast_node_add_sibling($2, $3);
581 $$ = $2;
585 AddOp:
586 T_PLUS
588 struct AstNode *ast_node;
589 ast_node = ast_node_new($1, T_PLUS, INTEGER,
590 yylloc.last_line, NULL);
591 $$ = ast_node;
593 | T_MINUS
595 struct AstNode *ast_node;
596 ast_node = ast_node_new($1, T_MINUS, INTEGER,
597 yylloc.last_line, NULL);
598 $$ = ast_node;
600 | T_OR
602 struct AstNode *ast_node;
603 ast_node = ast_node_new($1, T_OR, BOOLEAN,
604 yylloc.last_line, NULL);
605 $$ = ast_node;
609 MulOp:
610 T_STAR
612 struct AstNode *ast_node;
613 ast_node = ast_node_new($1, T_STAR, INTEGER,
614 yylloc.last_line, NULL);
615 $$ = ast_node;
617 | T_SLASH
619 struct AstNode *ast_node;
620 ast_node = ast_node_new($1, T_SLASH, INTEGER,
621 yylloc.last_line, NULL);
622 $$ = ast_node;
624 | T_AND
626 struct AstNode *ast_node;
627 ast_node = ast_node_new($1, T_AND, BOOLEAN,
628 yylloc.last_line, NULL);
629 $$ = ast_node;
633 RelOp:
634 T_LESSER
636 struct AstNode *ast_node;
637 ast_node = ast_node_new($1, T_LESSER, BOOLEAN,
638 yylloc.last_line, NULL);
639 $$ = ast_node;
641 | T_LESSEREQUAL
643 struct AstNode *ast_node;
644 ast_node = ast_node_new($1, T_LESSEREQUAL, BOOLEAN,
645 yylloc.last_line, NULL);
646 $$ = ast_node;
648 | T_GREATER
650 struct AstNode *ast_node;
651 ast_node = ast_node_new($1, T_GREATER, BOOLEAN,
652 yylloc.last_line, NULL);
653 $$ = ast_node;
655 | T_GREATEREQUAL
657 struct AstNode *ast_node;
658 ast_node = ast_node_new($1, T_GREATEREQUAL, BOOLEAN,
659 yylloc.last_line, NULL);
660 $$ = ast_node;
662 | T_EQUAL
664 struct AstNode *ast_node;
665 ast_node = ast_node_new($1, T_EQUAL, BOOLEAN,
666 yylloc.last_line, NULL);
667 $$ = ast_node;
669 | T_NOTEQUAL
671 struct AstNode *ast_node;
672 ast_node = ast_node_new($1, T_NOTEQUAL, BOOLEAN,
673 yylloc.last_line, NULL);
674 $$ = ast_node;
678 NotOp:
679 T_NOT
681 struct AstNode *ast_node;
682 ast_node = ast_node_new($1, T_NOT, BOOLEAN,
683 yylloc.last_line, NULL);
684 $$ = ast_node;
688 Identifier:
689 IDENTIFIER
691 struct AstNode *ast_node;
693 ast_node = ast_node_new("Identifier", IDENTIFIER, VOID,
694 yylloc.last_line, NULL);
695 ast_node->symbol = symbol_new($1);
696 ast_node->symbol->decl_linenum = yylloc.last_line;
697 $$ = ast_node;
701 Literal:
702 INT_LITERAL
704 struct AstNode *ast_node;
705 ast_node = ast_node_new("IntLiteral", INT_LITERAL, INTEGER,
706 yylloc.last_line, NULL);
707 value_set_from_int(&ast_node->value, $1);
708 $$ = ast_node;
710 | BOOL_LITERAL
712 struct AstNode *ast_node;
713 ast_node = ast_node_new("BoolLiteral", BOOL_LITERAL, BOOLEAN,
714 yylloc.last_line, NULL);
715 value_set_from_bool(&ast_node->value, $1);
716 $$ = ast_node;
718 | CHAR_LITERAL
720 struct AstNode *ast_node;
721 ast_node = ast_node_new("CharLiteral", CHAR_LITERAL, CHAR,
722 yylloc.last_line, NULL);
723 value_set_from_char(&ast_node->value, $1);
724 $$ = ast_node;
730 static void
731 yyerror (/*YYLTYPE *locp,*/ const char *msg)
733 fprintf(stderr, "Error: line %d: %s\n", yyget_lineno(), msg);
737 main (int argc, char **argv)
739 Visitor *visitor;
741 opterr = 0;
743 while ((opts = getopt (argc, argv, "sgcl")) != -1) {
744 switch (opts) {
745 case 's':
746 simple_flag = TRUE;
747 break;
748 case 'g':
749 graph_flag = TRUE;
750 break;
751 case 'c':
752 c_flag = TRUE;
753 break;
754 case 'l':
755 llvm_flag = TRUE;
756 break;
757 /*case 'o':
758 output = optarg;
759 break;
760 case '?':
761 if (optopt == 'o')
762 fprintf (stderr, "Option -%c requires an argument.\n",
763 optopt);
764 else if (isprint (optopt))
765 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
766 else
767 fprintf (stderr,
768 "Unknown option character `\\x%x'.\n", optopt);
770 default:
771 return 1;
775 if (argc > optind)
776 yyin = fopen(argv[optind], "r");
777 else
778 yyin = stdin;
780 /*yylloc.first_line = yylloc.last_line = 1;
781 yylloc.first_column = yylloc.last_column = 0;*/
783 yyparse();
785 /* Verificacao de tipos. */
786 visitor = typecheck_new();
787 ast_node_accept(ast, visitor);
789 /* Mostra estrutura da AST em forma de texto. */
790 if (simple_flag) {
791 visitor = simpleprinter_new();
792 ast_node_accept(ast, visitor);
795 /* Desenha grafo da AST. */
796 if (graph_flag) {
797 visitor = graphprinter_new();
798 ast_node_accept(ast, visitor);
801 /* Gera codigo em linguagem C. */
802 if (c_flag) {
803 visitor = c_codegen_new();
804 ast_node_accept(ast, visitor);
807 fclose(stdout);
808 return 0;