I am writing a compiler for the shader mechanism, and each one worked fine until it came to parsing the parts.
I used the abstract syntax tree defined using classes to do all the work (to simplify the creation of labels and intermediate code generation). So I have a class of their ancestors ASTNodeand go down classes, such as ASTFloat, ASTExpression, ASTIdentifier, etc.
In the file, .yI can create the AST in the usual 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 fine, but then I tried to create area operators (for example, the body of an if statement) as follows: I used a class ASTStatementsthat has a list ASTNode*that should be populated with a parser with every statement encountered.
So the approach would be something like this:
statements:
statement { if ($$ == null) $$ = new ASTStatements(); ((ASTStatements*)$$)->addStatement($1); } statements { $$->generateASM(); }
;
The problem is that the element needs to be initialized only once per statement block, but I don't know how to do it. Use if ($$ == null)is a hack that I tried, but it does not work, because it yylvalcan contain everything that is up to this point.
What is the normal / best way to deal with such situations using Bison?