Tom
Tom

Reputation: 1301

Bison if statements - setting symbol table prior to parsing block statements

In my language I have the ability to declare a variable in the current symbol table scope and also create a if statement which will generate a new symbol table scope for its statements.

stmts : stmt { $$ = new Block(); $$->addStatement($1); }
      | stmts stmt { $1->addStatement($2); }
      | /*blank*/ { $$ = new Block(); }
      ;

stmt : vardecl
     | ifstmt
     ;

ifstmt : TIF TLPAREN exprBase TRPAREN TOPENBLOCK stmts TCLOSEBLOCK {
                                                                     semanticAnalyzerParser->enterScope("if statement scope");
                                                                     $$ = new IfStatement($3, $7);
                                                                   }
       ;

assign :  ident ident TASSIGN exprBase {
                                        Var* typeName = $1;
                                        Var* varName = $2;
                                        ExpressionBase* exprBase = $4;
                                        semanticAnalyzerParser->getScope()->registerVariable(typeName->identifier, varName->identifier, exprBase);
                                        $$ = new VarDecl(typeName, varName, exprBase);
       }
       ;

What I'd like to do is set a new scope before bison enters the if statement block of statements. E.g. semanticAnalyzerParser->enterScope("if statement scope");, so that when grammar for declaring variables are recognised it will declare it on the correct scope with semanticAnalyzerParser->getScope()->registerVariable(typeName->identifier, varName->identifier, exprBase);

However, since bison has to recognise the complete grammar of a if statement, it only creates the scope after it finishes parsing and thus registers the variables on the wrong scope.

How can I execute code prior to parsing the stmts part of the ifstmt grammar, so that it can set the correct scope? I know that one option is to walk the AST tree afterwards but I want to avoid this since the ASTs to create in bison are largely determined by information gathered in the semantic analysis.

Upvotes: 0

Views: 311

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126526

Usually you would do this with an "embedded" action:

ifstmt : TIF TLPAREN exprBase TRPAREN {
                 semanticAnalyzerParser->enterScope("if statement scope"); }
         TOPENBLOCK stmts TCLOSEBLOCK {
                 semanticAnalyzerParser->leaveScope("if statement scope");
                 $$ = new IfStatement($3, $7); }
   ;

The embedded action will be executed after the first part of the ifstmt is recognized (up to the TRPAREN, with the TOPENBLOCK as lookahead), before the body (stmts) is parsed.

Upvotes: 2

Related Questions