zoukankan      html  css  js  c++  java
  • 编译器开发系列--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);
        }
    
  • 相关阅读:
    lambda函数
    linux 自学系列:wc命令
    linux 自学系列:chmod 权限操作
    linux 自学系列:创建、删除目录、移动、更名文件或目录
    linux 自学系列:vi、vim编辑工具
    《架构之美》学习随笔:设计第一步
    安装memcache 时提示error while loading shared libraries: libevent2.0解决办法
    《架构之美》学习随笔:保证质量
    linux 自学系列:环境变量设置
    logging模块学习笔记:logger 对象、日志等级
  • 原文地址:https://www.cnblogs.com/joey-hua/p/6211596.html
Copyright © 2011-2022 走看看