C语言 创建 AST 后的语义检查



我创建了一个扫描仪和一个解析器(分别使用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;
}

如何管理类型检查(在变量名和表达式语句之间(?我必须创建一个具有整个 AST 类似参数的函数(在 ast.c 中(,还是每当我发现需要在解析器中进行类型检查的产品时调用此函数?

请在此处查看符号表是否可用于语义操作:

  • https://www.gnu.org/software/bison/manual/html_node/Pure-Calling.html
  • https://www.gnu.org/software/bison/manual/html_node/Parser-Function.html

然后这里有一个非常简化的赋值语义动作函数的伪 cpp-code,尽管最好在树完成后执行此操作:

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(。相应地返回错误。

最新更新