什么是编译器中基本类型的自动类型转换的好算法?

时间:2016-10-22 15:43:54

标签: compiler-construction

我正在开发一个简单的编译器,并希望以适当的方式实现自动类型转换。我有的类型是例如byte,int,uint16_t,uint64_t,int16_t,float,double等。编译器应该检查类型,并确定某种类型的值是否可以用作另一种类型。

例如,int16_t值可以毫无问题地用作int32_t值,因为不会丢失精度。使用期望int16_t的int32_t值应该引发警告或错误。

我到目前为止的代码如下:

def do_coerce(self, expr, typ):
    """ Try to convert expression into the given type.

    expr: the expression value with a certain type
    typ: the type that it must be
    Raises an error is the conversion cannot be done.
    """
    if self.context.equal_types(expr.typ, typ):
        # no cast required
        pass
    elif isinstance(expr.typ, ast.PointerType) and \
            isinstance(typ, ast.PointerType):
        # Pointers are pointers, no matter the pointed data.
        expr = ast.TypeCast(typ, expr, expr.loc)
    elif self.context.equal_types('int', expr.typ) and \
            isinstance(typ, ast.PointerType):
        expr = ast.TypeCast(typ, expr, expr.loc)
    elif self.context.equal_types('int', expr.typ) and \
            self.context.equal_types('byte', typ):
        expr = ast.TypeCast(typ, expr, expr.loc)
    elif self.context.equal_types('int', expr.typ) and \
            self.context.equal_types('float', typ):
        expr = ast.TypeCast(typ, expr, expr.loc)
    elif self.context.equal_types('int', expr.typ) and \
            self.context.equal_types('double', typ):
        expr = ast.TypeCast(typ, expr, expr.loc)
    elif self.context.equal_types('double', expr.typ) and \
            self.context.equal_types('float', typ):
        expr = ast.TypeCast(typ, expr, expr.loc)
    elif self.context.equal_types('float', expr.typ) and \
            self.context.equal_types('double', typ):
        expr = ast.TypeCast(typ, expr, expr.loc)
    elif self.context.equal_types('byte', expr.typ) and \
            self.context.equal_types('int', typ):
        expr = ast.TypeCast(typ, expr, expr.loc)
    else:
        raise SemanticError(
            "Cannot use '{}' as '{}'".format(expr.typ, typ), expr.loc)
    self.check_expr(expr)
    return expr

此代码的作用是检查'source'类型和'destination'类型,如果这些类型是某些类型,则执行自动转换,否则引发错误。代码有效,但我想添加更多类型的变体,而且我认为if-else树会变得非常大。

我已经搜索了一个很好的解决方案并尝试阅读clang,gcc和C#编译器的源代码,但我找不到处理此问题的源代码。

有没有关于如何解决这个问题的想法,或指向实现这个问题的来源?

1 个答案:

答案 0 :(得分:0)

简单!只是从最窄到最宽的索引类型。例如:

byte = 0;
int = 1;
float = 2;
double = 3;

然后你要做的就是比较两者:

if (from <= to)
{
    // This is a legal cast, no loss of precision
}
else
{
    // Error, narrowing!
}

我强烈建议this本书。