【发布时间】:2021-05-19 11:00:14
【问题描述】:
目前我正在为类似 C/C++ 的语言开发一个编译器,以便更具体地作为类型检查器。 我已经生成了一个带有语法和 bnfc 工具的解析器。对于我的类型检查器,我需要推断表达式的类型。所有表达式都派生自抽象基类 Exp,如下所示:
class Exp {
...
}
class ExpPlus : public {
...
}
class ExpAnd : public {
...
}
...
ExpPlus 指的是Exp + Exp,ExpAnd 指的是Exp && Exp。
我的推断函数接受一个表达式并返回它的类型,如下所示:
ype *TypeChecker::infer(Exp *exp)
{
// check for kind of expression
/* Base cases */
if(dynamic_cast<ETrue*>(exp))
{
Type *tBool = new Type_bool;
return tBool;
}
if(dynamic_cast<EFalse*>(exp))
{
Type *tBool = new Type_bool;
return tBool;
}
if(dynamic_cast<EInt*>(exp))
{
Type *tInt = new Type_int;
return tInt;
}
if(dynamic_cast<EDouble*>(exp))
{
Type *tDouble = new Type_double;
return tDouble;
}
if(dynamic_cast<EId*>(exp)) // search for type of given Id in contexts
{
EId *eId = dynamic_cast<EId*>(exp);
Type *typeOfSearchedId = env_->lookupVarTypeFromContext(eId->id_);
return typeOfSearchedId;
}
/* Base cases end*/
/* check expressions */
if(dynamic_cast<EApp*>(exp))
{
EApp *eApp = dynamic_cast<EApp*>(exp);
Type *retType = env_->lookupFunTypeFromSymbolTable(eApp->id_).returnType;
return retType;
}
if(dynamic_cast<EUPlus*>(exp))
{
// cast exp to type of exp
EUPlus *eu_plus = dynamic_cast<EUPlus*>(exp);
// infer till base case is derived
Type *typeExp = infer(eu_plus->exp_);
// if type is int or double
if(dynamic_cast<Type_int*>(typeExp) || dynamic_cast<Type_double*>(typeExp))
return typeExp;
throw TypeException("Trying to unary add wrong type: " + env_->getStringRepresentationOfType(typeExp));
}
...
如您所见,我有一长串 If 语句,用于检查表达式是哪种具体表达式类型,它可以正常工作,但我想知道是否有更优雅的方式来执行此操作。
【问题讨论】:
-
chain of
if(dynamic_cast<....表示你仍然不知道应该如何使用多态性。 -
使用虚函数而不是动态转换
-
请注意,您发布的代码没有冒犯,有点混乱。
: public没有提到基类,;在类定义之后丢失,infer是如此不完整,以至于很难理解它实际上做了什么。请阅读minimal reproducible example -
您应该研究访问者模式。
标签: c++ casting compiler-construction typechecking bnfc