• 编译器开发系列--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);
        }
    
  • 相关阅读:
    "《算法导论》之‘图’":不带权二分图最大匹配(匈牙利算法)
    "C#":MySql批量数量导入
    MySql常用操作语句(2:数据库、表管理以及数据操作)
    MySql常用操作语句(1:启动、连接数据库及用户操作)
    HTML 段落
    HTML 标题
    HTML 属性
    HTML 元素
    HTML 基础
    HTML 编辑器
  • 原文地址:https://www.cnblogs.com/joey-hua/p/6211596.html
Copyright © 2020-2023  润新知