【问题标题】:Bison if statements - setting symbol table prior to parsing block statementsBison if 语句 - 在解析块语句之前设置符号表
【发布时间】:2021-02-12 19:24:10
【问题描述】:

在我的语言中,我能够在当前符号表范围内声明一个变量,并创建一个 if 语句,该语句将为其语句生成一个新的符号表范围。

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);
       }
       ;

我想做的是在野牛进入 if 语句块之前设置一个新的范围。例如。 semanticAnalyzerParser->enterScope("if statement scope");,因此当声明变量的语法被识别时,它将使用semanticAnalyzerParser->getScope()->registerVariable(typeName->identifier, varName->identifier, exprBase);在正确的范围内声明它

但是,由于 bison 必须识别 if 语句的完整语法,它只在完成解析后才创建作用域,从而将变量注册到错误的作用域上。

如何在解析ifstmt 语法的stmts 部分之前执行代码,以便它可以设置正确的范围?我知道一种选择是之后遍历 AST 树,但我想避免这种情况,因为在 bison 中创建的 AST 很大程度上取决于语义分析中收集的信息。

【问题讨论】:

  • 您可以在规则中的任何位置添加代码块,例如ifstmt : TIF { some code } ... more symbols ... TCLOSEBLOCK { some more code }。您需要确保这不会产生冲突(这不是此语法的问题)。

标签: c++ bison semantic-analysis


【解决方案1】:

通常您会使用“嵌入式”操作来执行此操作:

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

在识别ifstmt 的第一部分之后(直到TRPAREN,TOPENBLOCK 作为前瞻),在解析主体(stmts)之前,将执行嵌入的操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 2020-01-12
    • 1970-01-01
    相关资源
    最近更新 更多