I'm writing a compiler for a shading engine and every worked fine until I reached the statements parsing part.
I used an abstract syntax tree defined with classes to do all the work (to simplify typechecking and intermediate code generation).. so I have an ancestor class ASTNode
and all descending classes like ASTFloat
, ASTExpression
, ASTIdentifier
and so on..
In .y
file I'm able to build up the AST in the common way:
nexp:
T_LPAR nexp T_RPAR { $$ = $2; }
| nexp OP_PLUS nexp { $$ = new ASTBExpression('+', (ASTExpression*)$1, (ASTExpression*)$3); }
| nexp OP_MINUS nexp { $$ = new ASTBExpression('-', (ASTExpression*)$1, (ASTExpression*)$3); }
| nexp OP_TIMES nexp { $$ = new ASTBExpression('*', (ASTExpression*)$1, (ASTExpression*)$3); }
and it works quite fine but then I tried to generate statements of a scope (for example the body of an if statement) in this way: I have used a class ASTStatements
which has a list of ASTNode*
that must be filled by parser with each statement encountered.
So the approach would be something similar to this:
statements:
statement { if ($$ == null) $$ = new ASTStatements(); ((ASTStatements*)$$)->addStatement($1); } statements { $$->generateASM(); }
;
The problem is that the item should be initialized just once per block of statements but I don't know how to do it. Using if ($$ == null)
is a hack I tried but it doesn't work because yylval
can contain whatever up to that point.
Which is the normal/best way to handle this kind of situations using Bison?