suppressed some warnings
[ozulis.git] / src / lang / mugiwara / bison-parser / parser.y
blobe9f3e749a467a48140868f0232a2c23dc75475fd
1 %glr-parser
2 %pure-parser
3 %locations
4 %start file
5 %defines
6 %error-verbose
8 %lex-param {yyscan_t yyscanner}
9 %parse-param {yyscan_t yyscanner}
10 %parse-param {ast::File *& file}
13 #include <stdio.h>
14 #include <string.h>
15 #include <stdlib.h>
16 #include <iostream>
18 #include <core/assert.hh>
19 #include <ast/ast.hh>
21 #include "parser.hh"
22 #include "lexer.hh"
24 static void yyerror(YYLTYPE *yyloccp,
25 yyscan_t /*yyscanner*/,
26 ast::File *& file,
27 const char *str)
29 if (file)
30 std::cerr << file->path << ":" ;
31 std::cerr << yyloccp->first_line << "." << yyloccp->first_column << "-"
32 << yyloccp->last_line << "." << yyloccp->last_column
33 << ": " << str << std::endl;
36 #define MAKE_BINARY_EXP(Type, Out, Left, Right) \
37 do { \
38 ast::Type * exp = new ast::Type(); \
39 assert(Left); \
40 assert(Right); \
41 exp = new ast::Type(); \
42 exp->left = (Left); \
43 exp->right = (Right); \
44 (Out) = exp; \
45 } while (0)
47 #define MAKE_UNARY_EXP(Type, Out, Exp) \
48 do { \
49 ast::Type * exp = new ast::Type(); \
50 assert(Exp); \
51 exp = new ast::Type(); \
52 exp->exp = (Exp); \
53 (Out) = exp; \
54 } while (0)
56 static ast::Type *
57 createType(const char * name)
59 static const struct {
60 const char * name;
61 bool isSigned;
62 int size;
63 } integerTypes[] = {
64 { "int8", true, 8 },
65 { "uint8", false, 8 },
66 { "int16", true, 16 },
67 { "uint16", false, 16 },
68 { "int32", true, 32 },
69 { "uint32", false, 32 },
70 { "int64", true, 64 },
71 { "uint64", false, 64 },
72 { "int128", true, 128 },
73 { "uint128", false, 128 },
74 { 0, false, 0 }
77 for (int i = 0; integerTypes[i].name; i++)
78 if (!strcmp(name, integerTypes[i].name))
80 ast::IntegerType * itype = new ast::IntegerType();
81 itype->isSigned = integerTypes[i].isSigned;
82 itype->size = integerTypes[i].size;
83 return itype;
85 if (!strcmp("bool", name))
86 return new ast::BoolType();
87 if (!strcmp("float", name))
88 return new ast::FloatType();
89 if (!strcmp("double", name))
90 return new ast::DoubleType();
91 if (!strcmp("void", name))
92 return new ast::VoidType();
93 /// @todo resolve correctly the type
94 return new ast::Type();
99 %union
101 ast::Node * node;
102 std::vector<ast::Node *> * nodes;
103 ast::Function * funcDec;
104 ast::Type * type;
105 std::vector<ast::VarDecl *> * varDecls;
106 ast::VarDecl * varDecl;
107 ast::Block * block;
108 ast::Exp * exp;
109 ast::NumberExp * nbExp;
111 int number;
112 char * string;
113 bool boolean;
116 %token <nbExp> NUMBER
117 %token <string> ID
118 %token EQ SEMICOL DOT DDOT COMMA
119 %token EQEQ LT LTEQ GT GTEQ NEQ
120 %token ADD SUB DIV MUL MOD
121 %token OR AND XOR SHL ASHR LSHR
122 %token NOT BANG OROR ANDAND
123 %token LPAR RPAR LBR RBR
124 %token GOTO CONST CAST RETURN
125 %token IF ELSE WHILE DO FOR
126 %token VOID
128 %type <nodes> decls
129 %type <node> decl
130 %type <type> type
131 %type <varDecls> var_decls
132 %type <varDecl> var_decl
133 %type <funcDec> func_dec
134 %type <block> block
135 %type <nodes> statements
136 %type <node> statement label_statement goto_statement
137 %type <node> if_statement else_statement while_statement
138 %type <node> do_while_statement return_statement
139 %type <node> exp_statement
140 %type <exp> exp assign_exp oror_exp andand_exp or_exp xor_exp and_exp
141 %type <exp> cmp_exp shift_exp add_exp mul_exp unary_exp
142 %type <boolean> is_const
146 file: decls {
147 file = new ast::File();
148 file->decls = $1;
151 decls: decl decls {
152 assert($1);
153 $$ = $2 ? : new std::vector<ast::Node *> ();
154 $$->push_back($1);
155 } | { $$ = 0; };
157 decl: func_dec {
158 $$ = $1;
161 func_dec: type ID LPAR RPAR block {
162 $$ = new ast::Function();
163 $$->returnType = $1;
164 $$->name = $2;
165 $$->params = new std::vector<ast::Type *>();
166 $$->block = $5;
169 block: LBR var_decls statements RBR {
170 $$ = new ast::Block();
171 $$->varDecls = $2;
172 $$->statements = $3;
175 var_decls: var_decls var_decl SEMICOL {
176 assert($2);
177 $$ = $1 ? : new std::vector<ast::VarDecl *> ();
178 $$->push_back($2);
179 } | /* epsilon */ { $$ = new std::vector<ast::VarDecl *> (); };
181 var_decl: type ID {
182 $$ = new ast::VarDecl();
183 $$->type = $1;
184 $$->name = $2;
187 statements: statements statement {
188 assert($2);
189 $$ = $1 ? : new std::vector<ast::Node *> ();
190 $$->push_back($2);
191 } | /* epsilon */ { $$ = new std::vector<ast::Node *> (); };
193 statement: exp_statement { $$ = $1; }
194 | label_statement { $$ = $1; }
195 | goto_statement { $$ = $1; }
196 | if_statement { $$ = $1; }
197 | while_statement { $$ = $1; }
198 | do_while_statement { $$ = $1; }
199 | return_statement { $$ = $1; }
200 | block { $$ = $1; }
201 | SEMICOL { $$ = new ast::EmptyStatement(); };
203 exp_statement: exp SEMICOL {
204 assert($1);
205 $$ = $1;
208 label_statement: ID DDOT {
209 ast::Label * label = new ast::Label();
210 label->name = $1;
211 $$ = label;
214 goto_statement: GOTO ID SEMICOL {
215 ast::Goto * gt = new ast::Goto();
216 gt->label = $2;
217 $$ = gt;
220 if_statement: IF LPAR exp RPAR statement else_statement {
221 ast::If * ifStmt = new ast::If();
222 assert($3);
223 assert($5);
224 assert($6);
225 ifStmt->branch = new ast::ConditionalBranch;
226 ifStmt->branch->cond = $3;
227 ifStmt->trueBlock = $5;
228 ifStmt->falseBlock = $6;
229 $$ = ifStmt;
232 else_statement: ELSE statement {
233 $$ = $2;
234 } | /* epsylon */ { $$ = new ast::EmptyStatement; };
236 while_statement: WHILE LPAR exp RPAR statement {
237 ast::While * whileStmt = new ast::While;
238 assert($3);
239 assert($5);
240 whileStmt->branch = new ast::ConditionalBranch;
241 whileStmt->branch->cond = $3;
242 whileStmt->block = $5;
243 $$ = whileStmt;
246 do_while_statement: DO statement WHILE LPAR exp RPAR SEMICOL {
247 ast::DoWhile * doWhileStmt = new ast::DoWhile;
248 assert($2);
249 assert($5);
250 doWhileStmt->branch = new ast::ConditionalBranch;
251 doWhileStmt->branch->cond = $5;
252 doWhileStmt->block = $2;
253 $$ = doWhileStmt;
256 return_statement: RETURN SEMICOL {
257 ast::Return * ret = new ast::Return;
258 ret->exp = new ast::Exp;
259 ret->exp->type = new ast::VoidType;
260 $$ = ret;
261 } | RETURN exp SEMICOL {
262 ast::Return * ret = new ast::Return;
263 ret->exp = $2;
264 $$ = ret;
267 type: is_const ID {
268 $$ = createType($2);
269 $$->isConst = $1;
270 $$->name = $2;
273 is_const: CONST { $$ = true; }
274 | /* espilon */ { $$ = false; };
276 exp: assign_exp {
277 assert($1);
278 $$ = $1;
281 assign_exp: ID EQ oror_exp {
282 ast::AssignExp * exp = new ast::AssignExp();
283 exp->dest = new ast::Symbol();
284 exp->dest->name = $1;
285 exp->value = $3;
286 $$ = exp;
287 } | oror_exp { assert($1); $$ = $1; };
289 oror_exp: oror_exp OROR andand_exp { MAKE_BINARY_EXP(OrOrExp, $$, $1, $3); }
290 | andand_exp { assert($1); $$ = $1; };
292 andand_exp: andand_exp ANDAND or_exp { MAKE_BINARY_EXP(AndAndExp, $$, $1, $3); }
293 | or_exp { assert($1); $$ = $1; };
295 or_exp: or_exp OR xor_exp { MAKE_BINARY_EXP(OrExp, $$, $1, $3); }
296 | xor_exp { assert($1); $$ = $1; };
298 xor_exp: xor_exp XOR and_exp { MAKE_BINARY_EXP(XorExp, $$, $1, $3); }
299 | and_exp { assert($1); $$ = $1; };
301 and_exp: and_exp AND cmp_exp { MAKE_BINARY_EXP(AndExp, $$, $1, $3); }
302 | cmp_exp { assert($1); $$ = $1; };
304 cmp_exp: shift_exp EQEQ shift_exp { MAKE_BINARY_EXP(EqExp, $$, $1, $3); }
305 | shift_exp NEQ shift_exp { MAKE_BINARY_EXP(NeqExp, $$, $1, $3); }
306 | shift_exp LT shift_exp { MAKE_BINARY_EXP(LtExp, $$, $1, $3); }
307 | shift_exp LTEQ shift_exp { MAKE_BINARY_EXP(LtEqExp, $$, $1, $3); }
308 | shift_exp GT shift_exp { MAKE_BINARY_EXP(GtExp, $$, $1, $3); }
309 | shift_exp GTEQ shift_exp { MAKE_BINARY_EXP(GtEqExp, $$, $1, $3); }
310 | shift_exp { assert($1); $$ = $1; };
312 shift_exp: shift_exp SHL add_exp { MAKE_BINARY_EXP(ShlExp, $$, $1, $3); }
313 | shift_exp ASHR add_exp { MAKE_BINARY_EXP(AShrExp, $$, $1, $3); }
314 | shift_exp LSHR add_exp { MAKE_BINARY_EXP(LShrExp, $$, $1, $3); }
315 | add_exp { assert($1); $$ = $1; };
317 add_exp: add_exp ADD mul_exp { MAKE_BINARY_EXP(AddExp, $$, $1, $3); }
318 | add_exp SUB mul_exp { MAKE_BINARY_EXP(SubExp, $$, $1, $3); }
319 | mul_exp { assert($1); $$ = $1; };
321 mul_exp: mul_exp MUL unary_exp { MAKE_BINARY_EXP(MulExp, $$, $1, $3); }
322 | mul_exp DIV unary_exp { MAKE_BINARY_EXP(DivExp, $$, $1, $3); }
323 | mul_exp MOD unary_exp { MAKE_BINARY_EXP(ModExp, $$, $1, $3); }
324 | unary_exp { assert($1); $$ = $1; };
326 unary_exp: NUMBER { $$ = $1; }
327 | ID {
328 ast::IdExp * exp = new ast::IdExp();
329 exp->name = $1;
330 $$ = exp;
331 } | LPAR exp RPAR { assert($2); $$ = $2; }
332 | BANG unary_exp { MAKE_UNARY_EXP(BangExp, $$, $2); }
333 | NOT unary_exp { MAKE_UNARY_EXP(NotExp, $$, $2); }
334 | SUB unary_exp { MAKE_UNARY_EXP(NegExp, $$, $2); }
335 | CAST LPAR type COMMA exp RPAR {
336 ast::CastExp * cast = new ast::CastExp;
337 assert($3);
338 assert($5);
339 cast->type = $3;
340 cast->exp = $5;
341 $$ = cast;
346 #ifdef WITH_MAIN
347 int main(void)
349 void *exp;
350 yyscan_t scanner;
352 yylex_init(&scanner);
353 yyparse(scanner, &exp);
354 return 0;
356 #endif /* WITH_MAIN */