目前我正在为类似 C/C++ 的语言开发一个编译器,以便更具体地作为类型检查器。我已经生成了一个带有语法和 bnfc 工具的解析器。对于我的类型检查器,我需要推断表达式的类型。所有表达式都派生自抽象基类 Exp,如下所示:
class Exp {
...
}
class ExpPlus : public {
...
}
class ExpAnd : public {
...
}
...
ExpPlus 分别是指Exp + Exp
和 ExpAnd to 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 语句,用于检查表达式是哪种具体表达式类型,它工作得很好,但我想知道是否有更优雅的方式来做到这一点。