编译器开发系列--Ocelot语言6.静态类型检查

关于“静态类型检查”,想必使用C 或Java 的各位应该非常熟悉了。在此过程中将检查表达式的类型,发现类型不正确的操作时就会报错。例如结构体之间无法用+ 进行加法运算,指针和数值之间无法用* 进行乘法运算,将数组传递给参数类型为int 型的函数会出现莫名其妙的结果。在编译过程中检查是否符合这样的限制的处理就是静态类型检查。

在静态类型检查过程中也会实施隐式类型转换。

    /*入口
     * 
     */
    public void check(AST ast) throws SemanticException {
    	/*
    	 * 第1 个foreach 语句对全局变量的定义进行遍历,
    	 */
        for (DefinedVariable var : ast.definedVariables()) {
            checkVariable(var);
        }
        /*
         * 第2 个foreach 语句对函数定义进行遍历,并实施类型检查。
         */
        for (DefinedFunction f : ast.definedFunctions()) {
            currentFunction = f;
            checkReturnType(f);
            checkParamTypes(f);
            check(f.body());
        }
        if (errorHandler.errorOccured()) {
            throw new SemanticException("compile failed.");
        }
    }
    /*
     * checkVariable 方法在检查变量的类型是否为非void 的同
		时,还对变量的初始化表达式进行遍历。
     */
    private void checkVariable(DefinedVariable var) {
        if (isInvalidVariableType(var.type())) {
            error(var.location(), "invalid variable type");
            return;
        }
        if (var.hasInitializer()) {
            if (isInvalidLHSType(var.type())) {
                error(var.location(), "invalid LHS type: " + var.type());
                return;
            }
            check(var.initializer());
            var.setInitializer(implicitCast(var.type(), var.initializer()));
        }
    }
    /*
     * checkReturnType 方法检查函数返回值的类型是否为非结
		构体、联合体或数组。这里再重复一下,Ocelot中函数不能返回结构体或联合体。
     */
    private void checkReturnType(DefinedFunction f) {
        if (isInvalidReturnType(f.returnType())) {
            error(f.location(), "returns invalid type: " + f.returnType());
        }
    }
    /*
     * checkParamTypes 方法检查函数形参的类型是否为非结构体、联合体或void。因为Ocelot
		中函数参数的类型不能是结构体或联合体。
     */
    private void checkParamTypes(DefinedFunction f) {
        for (Parameter param : f.parameters()) {
            if (isInvalidParameterType(param.type())) {
                error(param.location(),
                        "invalid parameter type: " + param.type());
            }
        }
    }
    /*
     * check 是遍历参数节点的方法。各节点类会重写该函数,通过调用check(f.
		body()) 对函数体进行遍历。
     */
    private void check(StmtNode node) {
        visitStmt(node);
    }

 

posted @ 2016-12-22 19:44  是非猫  阅读(491)  评论(0编辑  收藏  举报