AST创建后的语义检查

时间:2018-09-27 11:14:59

标签: c parsing bison abstract-syntax-tree semantic-analysis

我创建了一个扫描器和一个解析器(分别带有flex和bison)和一个AST,以实现Java-Python转换器。我不了解如何管理AST中的语义动作(类型检查,变量声明检查等),在哪里插入实现这些检查的函数以及如何将符号表(由我创建)连接到AST。例如,考虑解析器中的这种产生方式:

VariableDeclaration
                   : VariableName                               {$$ = varDec_new($1,NULL);}
                   | VariableName ASSIGNOP ExpressionStatement  {$$ = varDec_new($1,$3);}
                ;

在ast.c中将 varDec_new 定义如下:

ast_node *varDec_new(ast_node *variableName, ast_node *exprStmt)
{
    ast_node *n = newast(AST_VARDEC); // ast_node allocation (in this case for the ast_node AST_VARDEC (type of ast_node)
    n->varDec.variableName = variableName; // pointer to variableName struct in AST
    n->varDec.exprStmt = expreStmt;   //pointer to expreStmt struct in AST
    return n;
}

如何管理类型检查(在VariableName和ExpressionStatement之间)?我是否要在整个AST参数中创建一个函数(在ast.c中),还是在解析器中发现需要类型检查的产品时调用此函数?

1 个答案:

答案 0 :(得分:1)

在这里查看您的符号表,以供您进行语义操作:

然后这是赋值语义动作函数的非常简化的伪cpp代码,尽管最好在树完成后再执行:

bool storeNodeType(symtable* sym, node* assignment)
{
    switch(root->RHS_node_kind):
    {
        case '+':
             left_type = getNodeType(sym, assignment->RHS->left);
             right_type = getNodeType(sym, assignment->RHS->right);
             [ ... apply_type_coercion_rules ... ]
             return sym->store(found_type,assignment->left->var);

        break;
        [... Plenty of cases]
        case t_Var:
             return symtable->store(assignment->left->var->vartype,assignment->left->var);
        break;
    }
    // each return returns if assignement vaild regarding types */;
}
  1. 假定右侧使用的任何变量已经具有类型,如果不是这种情况,则在野牛完成后,您必须在第二遍中键入树。
  2. 您基本上执行了RHS的后遍历,您根据每个操作员的类型强制规则推导了每个子表达式的类型。叶节点将是已知类型的变量或常量。因此,您将RHS输入“自下而上”。
  3. 在sym :: store中,您必须管理是否接受转写(字符串<-int)和/或再次管理类型强制(int <-float)。相应地返回错误。