8 %lex
-param
{yyscan_t yyscanner
}
9 %parse
-param
{yyscan_t yyscanner
}
10 %parse
-param
{ast
::File
*& file
}
18 #include <core/assert.hh>
24 static void yyerror(YYLTYPE *yyloccp
, yyscan_t yyscanner
, ast
::File
*& file
, const char *str
)
27 std
::cerr
<< file
->path
<< ":" ;
28 std
::cerr
<< yyloccp
->first_line
<< "." << yyloccp
->first_column
<< "-"
29 << yyloccp
->last_line
<< "." << yyloccp
->last_column
30 << ": " << str
<< std
::endl
;
33 #define MAKE_BINARY_EXP(Type, Out, Left, Right) \
35 ast
::Type
* exp
= new ast
::Type
(); \
38 exp
= new ast
::Type
(); \
40 exp
->right
= (Right
); \
44 #define MAKE_UNARY_EXP(Type, Out, Exp) \
46 ast
::Type
* exp
= new ast
::Type
(); \
48 exp
= new ast
::Type
(); \
54 createType
(const char * name
)
62 { "uint8", false
, 8 },
63 { "int16", true
, 16 },
64 { "uint16", false
, 16 },
65 { "int32", true
, 32 },
66 { "uint32", false
, 32 },
67 { "int64", true
, 64 },
68 { "uint64", false
, 64 },
69 { "int128", true
, 128 },
70 { "uint128", false
, 128 },
74 for
(int i
= 0; integerTypes
[i
].name
; i
++)
75 if
(!strcmp
(name
, integerTypes
[i
].name
))
77 ast
::IntegerType
* itype
= new ast
::IntegerType
();
78 itype
->isSigned
= integerTypes
[i
].isSigned
;
79 itype
->size
= integerTypes
[i
].size
;
82 if
(!strcmp
("bool", name
))
83 return new ast
::BoolType
();
84 if
(!strcmp
("float", name
))
85 return new ast
::FloatType
();
86 if
(!strcmp
("double", name
))
87 return new ast
::DoubleType
();
88 /// @todo resolve correctly the type
89 return new ast
::Type
();
97 std
::vector
<ast
::Node
*> * nodes
;
98 ast
::Function
* funcDec
;
100 std
::vector
<ast
::VarDecl
*> * varDecls
;
101 ast
::VarDecl
* varDecl
;
104 ast
::NumberExp
* nbExp
;
111 %token
<nbExp
> NUMBER
113 %token EQ SEMICOL DOT DDOT COMMA
114 %token EQEQ LT LTEQ GT GTEQ NEQ
115 %token ADD SUB DIV MUL MOD
116 %token OR AND XOR SHL ASHR LSHR
117 %token NOT BANG OROR ANDAND
118 %token LPAR RPAR LBR RBR
119 %token GOTO CONST CAST RETURN
120 %token IF ELSE WHILE DO FOR
125 %type
<varDecls
> var_decls
126 %type
<varDecl
> var_decl
127 %type
<funcDec
> func_dec
129 %type
<nodes
> statements
130 %type
<node
> statement label_statement goto_statement
131 %type
<node
> if_statement else_statement while_statement
132 %type
<node
> do_while_statement return_statement
133 %type
<node
> exp_statement
134 %type
<exp
> exp assign_exp oror_exp andand_exp or_exp xor_exp and_exp
135 %type
<exp
> cmp_exp shift_exp add_exp mul_exp unary_exp
136 %type
<boolean
> is_const
141 file
= new ast
::File
();
147 $$
= $2 ?
: new std
::vector
<ast
::Node
*> ();
155 func_dec: type ID LPAR RPAR block
{
156 $$
= new ast
::Function
();
159 $$
->params
= new std
::vector
<ast
::Type
*>();
163 block: LBR var_decls statements RBR
{
164 $$
= new ast
::Block
();
169 var_decls: var_decls var_decl SEMICOL
{
171 $$
= $1 ?
: new std
::vector
<ast
::VarDecl
*> ();
173 } |
/* epsilon */ { $$
= new std
::vector
<ast
::VarDecl
*> (); };
176 $$
= new ast
::VarDecl
();
181 statements: statements statement
{
183 $$
= $1 ?
: new std
::vector
<ast
::Node
*> ();
185 } |
/* epsilon */ { $$
= new std
::vector
<ast
::Node
*> (); };
187 statement: exp_statement
{ $$
= $1; }
188 | label_statement
{ $$
= $1; }
189 | goto_statement
{ $$
= $1; }
190 | if_statement
{ $$
= $1; }
191 | while_statement
{ $$
= $1; }
192 | do_while_statement
{ $$
= $1; }
193 | return_statement
{ $$
= $1; }
195 | SEMICOL
{ $$
= new ast
::EmptyStatement
(); };
197 exp_statement: exp SEMICOL
{
202 label_statement: ID DDOT
{
203 ast
::Label
* label
= new ast
::Label
();
208 goto_statement: GOTO ID SEMICOL
{
209 ast
::Goto
* gt
= new ast
::Goto
();
214 if_statement: IF LPAR exp RPAR statement else_statement
{
215 ast
::If
* ifStmt
= new ast
::If
();
220 ifStmt
->trueBlock
= $5;
221 ifStmt
->falseBlock
= $6;
225 while_statement: WHILE LPAR exp RPAR statement
{
226 ast
::While
* whileStmt
= new ast
::While
;
229 whileStmt
->cond
= $3;
230 whileStmt
->block
= $5;
234 else_statement: ELSE statement
{
236 } |
/* epsylon */ { $$
= new ast
::EmptyStatement
; };
238 do_while_statement: DO statement WHILE LPAR exp RPAR SEMICOL
{
239 ast
::DoWhile
* doWhileStmt
= new ast
::DoWhile
;
242 doWhileStmt
->cond
= $5;
243 doWhileStmt
->block
= $2;
247 return_statement: RETURN SEMICOL
{
248 ast
::Return
* ret
= new ast
::Return
;
250 } | RETURN exp SEMICOL
{
251 ast
::ValuedReturn
* ret
= new ast
::ValuedReturn
;
262 is_const: CONST
{ $$
= true
; }
263 |
/* espilon */ { $$
= false
; };
270 assign_exp: ID EQ oror_exp
{
271 ast
::AssignExp
* exp
= new ast
::AssignExp
();
272 exp
->dest
= new ast
::Symbol
();
273 exp
->dest
->name
= $1;
276 } | oror_exp
{ assert
($1); $$
= $1; };
278 oror_exp: oror_exp OROR andand_exp
{ MAKE_BINARY_EXP
(OrOrExp
, $$
, $1, $3); }
279 | andand_exp
{ assert
($1); $$
= $1; };
281 andand_exp: andand_exp ANDAND or_exp
{ MAKE_BINARY_EXP
(AndAndExp
, $$
, $1, $3); }
282 | or_exp
{ assert
($1); $$
= $1; };
284 or_exp: or_exp OR xor_exp
{ MAKE_BINARY_EXP
(OrExp
, $$
, $1, $3); }
285 | xor_exp
{ assert
($1); $$
= $1; };
287 xor_exp: xor_exp XOR and_exp
{ MAKE_BINARY_EXP
(XorExp
, $$
, $1, $3); }
288 | and_exp
{ assert
($1); $$
= $1; };
290 and_exp: and_exp AND cmp_exp
{ MAKE_BINARY_EXP
(AndExp
, $$
, $1, $3); }
291 | cmp_exp
{ assert
($1); $$
= $1; };
293 cmp_exp: shift_exp EQEQ shift_exp
{ MAKE_BINARY_EXP
(EqExp
, $$
, $1, $3); }
294 | shift_exp NEQ shift_exp
{ MAKE_BINARY_EXP
(NeqExp
, $$
, $1, $3); }
295 | shift_exp LT shift_exp
{ MAKE_BINARY_EXP
(LtExp
, $$
, $1, $3); }
296 | shift_exp LTEQ shift_exp
{ MAKE_BINARY_EXP
(LtEqExp
, $$
, $1, $3); }
297 | shift_exp GT shift_exp
{ MAKE_BINARY_EXP
(GtExp
, $$
, $1, $3); }
298 | shift_exp GTEQ shift_exp
{ MAKE_BINARY_EXP
(GtEqExp
, $$
, $1, $3); }
299 | shift_exp
{ assert
($1); $$
= $1; };
301 shift_exp: shift_exp SHL add_exp
{ MAKE_BINARY_EXP
(ShlExp
, $$
, $1, $3); }
302 | shift_exp ASHR add_exp
{ MAKE_BINARY_EXP
(AShrExp
, $$
, $1, $3); }
303 | shift_exp LSHR add_exp
{ MAKE_BINARY_EXP
(LShrExp
, $$
, $1, $3); }
304 | add_exp
{ assert
($1); $$
= $1; };
306 add_exp: add_exp ADD mul_exp
{ MAKE_BINARY_EXP
(AddExp
, $$
, $1, $3); }
307 | add_exp SUB mul_exp
{ MAKE_BINARY_EXP
(SubExp
, $$
, $1, $3); }
308 | mul_exp
{ assert
($1); $$
= $1; };
310 mul_exp: mul_exp MUL unary_exp
{ MAKE_BINARY_EXP
(MulExp
, $$
, $1, $3); }
311 | mul_exp DIV unary_exp
{ MAKE_BINARY_EXP
(DivExp
, $$
, $1, $3); }
312 | mul_exp MOD unary_exp
{ MAKE_BINARY_EXP
(ModExp
, $$
, $1, $3); }
313 | unary_exp
{ assert
($1); $$
= $1; };
315 unary_exp: NUMBER
{ $$
= $1; }
317 ast
::IdExp
* exp
= new ast
::IdExp
();
320 } | LPAR exp RPAR
{ assert
($2); $$
= $2; }
321 | BANG unary_exp
{ MAKE_UNARY_EXP
(BangExp
, $$
, $2); }
322 | NOT unary_exp
{ MAKE_UNARY_EXP
(NotExp
, $$
, $2); }
323 | SUB unary_exp
{ MAKE_UNARY_EXP
(NegExp
, $$
, $2); }
324 | CAST LPAR type COMMA exp RPAR
{
325 ast
::CastExp
* cast
= new ast
::CastExp
;
341 yylex_init
(&scanner
);
342 yyparse(scanner
, &exp
);
345 #endif /* WITH_MAIN */