8 %lex
-param
{yyscan_t yyscanner
}
9 %parse
-param
{yyscan_t yyscanner
}
10 %parse
-param
{ozulis
::ast
::File
*& file
}
20 #include <ozulis/core/assert.hh>
21 #include <ozulis/ast/ast.hh>
22 #include <ozulis/ast/node-factory.hh>
27 static void yyerror(YYLTYPE *yyloccp
,
28 yyscan_t
/*yyscanner*/,
29 ozulis
::ast
::File
*& file
,
33 std
::cerr
<< file
->path
<< ":" ;
34 std
::cerr
<< yyloccp
->first_line
<< "." << yyloccp
->first_column
<< "-"
35 << yyloccp
->last_line
<< "." << yyloccp
->last_column
36 << ": " << str
<< std
::endl
;
39 #define MAKE_BINARY_EXP(Type, Out, Left, Right) \
41 ozulis
::ast
::Type
* exp
= new ozulis
::ast
::Type
(); \
44 exp
= new ozulis
::ast
::Type
(); \
46 exp
->right
= (Right
); \
50 #define MAKE_UNARY_EXP(Type, Out, Exp) \
52 ozulis
::ast
::Type
* exp
= new ozulis
::ast
::Type
(); \
54 exp
= new ozulis
::ast
::Type
(); \
59 static ozulis
::ast
::Type
*
60 createType
(const char * name
)
68 { "uint8", false
, 8 },
69 { "int16", true
, 16 },
70 { "uint16", false
, 16 },
71 { "int32", true
, 32 },
72 { "uint32", false
, 32 },
73 { "int64", true
, 64 },
74 { "uint64", false
, 64 },
75 { "int128", true
, 128 },
76 { "uint128", false
, 128 },
80 for
(int i
= 0; integerTypes
[i
].name
; i
++)
81 if
(!strcmp
(name
, integerTypes
[i
].name
))
83 ozulis
::ast
::IntegerType
* itype
= new ozulis
::ast
::IntegerType
();
84 itype
->isSigned
= integerTypes
[i
].isSigned
;
85 itype
->size
= integerTypes
[i
].size
;
88 if
(!strcmp
("bool", name
))
89 return ozulis
::ast
::NodeFactory
::createBoolType
();
90 if
(!strcmp
("float", name
))
91 return ozulis
::ast
::NodeFactory
::createFloatType
();
92 if
(!strcmp
("double", name
))
93 return ozulis
::ast
::NodeFactory
::createDoubleType
();
94 if
(!strcmp
("void", name
))
95 return ozulis
::ast
::NodeFactory
::createVoidType
();
96 /// @todo resolve correctly the type
97 return new ozulis
::ast
::Type
();
104 ozulis
::ast
::Node
* node
;
105 std
::vector
<ozulis
::ast
::Node
*> * nodes
;
106 ozulis
::ast
::Function
* funcDec
;
107 ozulis
::ast
::Type
* type
;
108 std
::vector
<ozulis
::ast
::VarDecl
*> * varDecls
;
109 ozulis
::ast
::VarDecl
* varDecl
;
110 ozulis
::ast
::Block
* block
;
111 ozulis
::ast
::Exp
* exp
;
112 std
::vector
<ozulis
::ast
::Exp
*> * exps
;
113 ozulis
::ast
::NumberExp
* nbExp
;
120 %token
<nbExp
> NUMBER
121 %token
<string> ID STRING
122 %token EQ SEMICOL DOT DDOT COMMA
123 %token EQEQ LT LTEQ GT GTEQ NEQ
124 %token ADD SUB DIV STAR MOD AT DOLLAR
125 %token OR AND XOR SHL ASHR LSHR
126 %token NOT BANG OROR ANDAND
127 %token LPAR RPAR LBR RBR LSB RSB
128 %token GOTO CONST CAST RETURN
129 %token IF ELSE WHILE DO FOR
134 %type
<varDecls
> var_decls func_params func_params_non_empty
135 %type
<varDecl
> var_decl
136 %type
<node
> func_dec
138 %type
<nodes
> statements
139 %type
<node
> statement label_statement goto_statement
140 %type
<node
> if_statement else_statement while_statement
141 %type
<node
> do_while_statement return_statement
142 %type
<node
> exp_statement
143 %type
<exp
> exp assign_exp oror_exp andand_exp or_exp xor_exp and_exp
144 %type
<exp
> cmp_exp shift_exp add_exp mul_exp unary_exp
146 %type
<exps
> call_exp_args call_exp_args_non_empty
151 file
= new ozulis
::ast
::File
();
153 std
::reverse
(file
->decls
->begin
(), file
->decls
->end
());
161 } |
/* epsilon */ { $$
= new std
::vector
<ozulis
::ast
::Node
*> (); };
167 func_dec: type ID LPAR func_params RPAR SEMICOL
{
168 ozulis
::ast
::FunctionDecl
* func
= new ozulis
::ast
::FunctionDecl
;
169 func
->returnType
= $1;
173 } | type ID LPAR func_params RPAR block
{
174 ozulis
::ast
::Function
* func
= new ozulis
::ast
::Function
;
175 func
->returnType
= $1;
182 func_params: func_params_non_empty
{ $$
= $1; }
183 |
/* epsilon */ { $$
= new std
::vector
<ozulis
::ast
::VarDecl
*>(); };
185 func_params_non_empty: var_decl
{
186 $$
= new std
::vector
<ozulis
::ast
::VarDecl
*>();
188 } | func_params_non_empty COMMA var_decl
{
193 block: LBR var_decls statements RBR
{
194 $$
= new ozulis
::ast
::Block
();
199 var_decls: var_decls var_decl SEMICOL
{
201 $$
= $1 ?
: new std
::vector
<ozulis
::ast
::VarDecl
*> ();
203 } |
/* epsilon */ { $$
= new std
::vector
<ozulis
::ast
::VarDecl
*> (); };
206 $$
= new ozulis
::ast
::VarDecl
();
211 statements: statements statement
{
213 $$
= $1 ?
: new std
::vector
<ozulis
::ast
::Node
*> ();
215 } |
/* epsilon */ { $$
= new std
::vector
<ozulis
::ast
::Node
*> (); };
217 statement: exp_statement
{ $$
= $1; }
218 | label_statement
{ $$
= $1; }
219 | goto_statement
{ $$
= $1; }
220 | if_statement
{ $$
= $1; }
221 | while_statement
{ $$
= $1; }
222 | do_while_statement
{ $$
= $1; }
223 | return_statement
{ $$
= $1; }
225 | SEMICOL
{ $$
= new ozulis
::ast
::EmptyStatement
(); };
227 exp_statement: exp SEMICOL
{
232 label_statement: ID DDOT
{
233 ozulis
::ast
::Label
* label
= new ozulis
::ast
::Label
();
238 goto_statement: GOTO ID SEMICOL
{
239 ozulis
::ast
::Goto
* gt
= new ozulis
::ast
::Goto
();
244 if_statement: IF LPAR exp RPAR statement else_statement
{
245 ozulis
::ast
::If
* ifStmt
= new ozulis
::ast
::If
();
249 ifStmt
->branch
= new ozulis
::ast
::ConditionalBranch
;
250 ifStmt
->branch
->cond
= $3;
251 ifStmt
->trueBlock
= $5;
252 ifStmt
->falseBlock
= $6;
256 else_statement: ELSE statement
{
258 } |
/* epsylon */ { $$
= new ozulis
::ast
::EmptyStatement
; };
260 while_statement: WHILE LPAR exp RPAR statement
{
261 ozulis
::ast
::While
* whileStmt
= new ozulis
::ast
::While
;
264 whileStmt
->branch
= new ozulis
::ast
::ConditionalBranch
;
265 whileStmt
->branch
->cond
= $3;
266 whileStmt
->block
= $5;
270 do_while_statement: DO statement WHILE LPAR exp RPAR SEMICOL
{
271 ozulis
::ast
::DoWhile
* doWhileStmt
= new ozulis
::ast
::DoWhile
;
274 doWhileStmt
->branch
= new ozulis
::ast
::ConditionalBranch
;
275 doWhileStmt
->branch
->cond
= $5;
276 doWhileStmt
->block
= $2;
280 return_statement: RETURN SEMICOL
{
281 ozulis
::ast
::Return
* ret
= new ozulis
::ast
::Return
;
282 ret
->exp
= new ozulis
::ast
::VoidExp
;
283 ret
->exp
->type
= new ozulis
::ast
::VoidType
;
285 } | RETURN exp SEMICOL
{
286 ozulis
::ast
::Return
* ret
= new ozulis
::ast
::Return
;
298 ozulis
::ast
::PointerType
* type
= new ozulis
::ast
::PointerType
;
301 } | LBR NUMBER RBR type
{
302 ozulis
::ast
::ArrayType
* type
= new ozulis
::ast
::ArrayType
;
304 type
->size
= $2->number
;
313 assign_exp: exp EQ oror_exp
{
314 ozulis
::ast
::AssignExp
* exp
= new ozulis
::ast
::AssignExp
();
318 } | oror_exp
{ assert
($1); $$
= $1; };
320 oror_exp: oror_exp OROR andand_exp
{ MAKE_BINARY_EXP
(OrOrExp
, $$
, $1, $3); }
321 | andand_exp
{ assert
($1); $$
= $1; };
323 andand_exp: andand_exp ANDAND or_exp
{ MAKE_BINARY_EXP
(AndAndExp
, $$
, $1, $3); }
324 | or_exp
{ assert
($1); $$
= $1; };
326 or_exp: or_exp OR xor_exp
{ MAKE_BINARY_EXP
(OrExp
, $$
, $1, $3); }
327 | xor_exp
{ assert
($1); $$
= $1; };
329 xor_exp: xor_exp XOR and_exp
{ MAKE_BINARY_EXP
(XorExp
, $$
, $1, $3); }
330 | and_exp
{ assert
($1); $$
= $1; };
332 and_exp: and_exp AND cmp_exp
{ MAKE_BINARY_EXP
(AndExp
, $$
, $1, $3); }
333 | cmp_exp
{ assert
($1); $$
= $1; };
335 cmp_exp: shift_exp EQEQ shift_exp
{ MAKE_BINARY_EXP
(EqExp
, $$
, $1, $3); }
336 | shift_exp NEQ shift_exp
{ MAKE_BINARY_EXP
(NeqExp
, $$
, $1, $3); }
337 | shift_exp LT shift_exp
{ MAKE_BINARY_EXP
(LtExp
, $$
, $1, $3); }
338 | shift_exp LTEQ shift_exp
{ MAKE_BINARY_EXP
(LtEqExp
, $$
, $1, $3); }
339 | shift_exp GT shift_exp
{ MAKE_BINARY_EXP
(GtExp
, $$
, $1, $3); }
340 | shift_exp GTEQ shift_exp
{ MAKE_BINARY_EXP
(GtEqExp
, $$
, $1, $3); }
341 | shift_exp
{ assert
($1); $$
= $1; };
343 shift_exp: shift_exp SHL add_exp
{ MAKE_BINARY_EXP
(ShlExp
, $$
, $1, $3); }
344 | shift_exp ASHR add_exp
{ MAKE_BINARY_EXP
(AShrExp
, $$
, $1, $3); }
345 | shift_exp LSHR add_exp
{ MAKE_BINARY_EXP
(LShrExp
, $$
, $1, $3); }
346 | add_exp
{ assert
($1); $$
= $1; };
348 add_exp: add_exp ADD mul_exp
{ MAKE_BINARY_EXP
(AddExp
, $$
, $1, $3); }
349 | add_exp SUB mul_exp
{ MAKE_BINARY_EXP
(SubExp
, $$
, $1, $3); }
350 | mul_exp
{ assert
($1); $$
= $1; };
352 mul_exp: mul_exp STAR unary_exp
{ MAKE_BINARY_EXP
(MulExp
, $$
, $1, $3); }
353 | mul_exp DIV unary_exp
{ MAKE_BINARY_EXP
(DivExp
, $$
, $1, $3); }
354 | mul_exp MOD unary_exp
{ MAKE_BINARY_EXP
(ModExp
, $$
, $1, $3); }
355 | unary_exp
{ assert
($1); $$
= $1; };
357 unary_exp: NUMBER
{ $$
= $1; }
359 ozulis
::ast
::IdExp
* exp
= new ozulis
::ast
::IdExp
;
360 exp
->symbol
= new ozulis
::ast
::Symbol
;
361 exp
->symbol
->name
= $1;
364 ozulis
::ast
::StringExp
* exp
= new ozulis
::ast
::StringExp
;
367 } | LPAR exp RPAR
{ assert
($2); $$
= $2; }
368 | BANG unary_exp
{ MAKE_UNARY_EXP
(BangExp
, $$
, $2); }
369 | NOT unary_exp
{ MAKE_UNARY_EXP
(NotExp
, $$
, $2); }
370 | SUB unary_exp
{ MAKE_UNARY_EXP
(NegExp
, $$
, $2); }
371 | call_exp
{ $$
= $1; }
372 | CAST LPAR type COMMA exp RPAR
{
373 ozulis
::ast
::CastExp
* cast
= new ozulis
::ast
::CastExp
;
379 } | unary_exp DOLLAR
{
380 ozulis
::ast
::DereferenceExp
* exp
= new ozulis
::ast
::DereferenceExp
;
384 ozulis
::ast
::AtExp
* exp
= new ozulis
::ast
::AtExp
;
387 } | unary_exp LSB exp RSB
{
388 ozulis
::ast
::DereferenceByIndexExp
* exp
= new ozulis
::ast
::DereferenceByIndexExp
;
394 call_exp: ID LPAR call_exp_args RPAR
{
398 ozulis
::ast
::CallExp
* callExp
= new ozulis
::ast
::CallExp
;
404 call_exp_args: call_exp_args_non_empty
{ $$
= $1; }
405 |
/* empty */ { $$
= new std
::vector
<ozulis
::ast
::Exp
*>(); };
407 call_exp_args_non_empty: exp
{
409 $$
= new std
::vector
<ozulis
::ast
::Exp
*>();
411 } | call_exp_args_non_empty COMMA exp
{
426 yylex_init
(&scanner
);
427 yyparse(scanner
, &exp
);
430 #endif /* WITH_MAIN */