Je suis en train d'écrire un compilateur pour un moteur d'ombrage et tout a bien fonctionné jusqu'à ce que j'aie atteint la partie d'analyse des instructions.Utilisation de bison pour analyser la liste des éléments
J'ai utilisé un arbre de syntaxe abstraite définie avec des classes à faire tout le travail (pour simplifier typage et génération de code intermédiaire) .. donc j'ai une classe ancêtre ASTNode
et toutes les classes descendantes comme ASTFloat
, ASTExpression
, ASTIdentifier
etc. .. sur
dans .y
fichier, je suis en mesure de construire l'AST de la manière commune:
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); }
et il fonctionne très bien, mais j'essayé de générer des déclarations o de cette façon: J'ai utilisé une classe ASTStatements
qui a une liste de ASTNode*
qui doit être remplie par l'analyseur avec chaque instruction rencontrée.
Donc, l'approche serait quelque chose de similaire à ceci:
statements:
statement { if ($$ == null) $$ = new ASTStatements(); ((ASTStatements*)$$)->addStatement($1); } statements { $$->generateASM(); }
;
Le problème est que l'élément doit être initialisé une seule fois par bloc de déclarations, mais je ne sais pas comment le faire. L'utilisation de if ($$ == null)
est un hack que j'ai essayé mais cela ne fonctionne pas car yylval
peut contenir n'importe quoi jusqu'à ce point.
Quelle est la meilleure façon de gérer ce genre de situations avec Bison?
avez-vous un% type statement_if etc. etc? –
bien sûr, j'ai dû résoudre le problème en transformant ASTStatements * en une classe avec une partie gauche (ASTStatement *) et une partie droite (ASTStatements *). J'ai en fait transformé la liste en un arbre dégénéré .. – Jack