• 编译器开发系列--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);
        }
    
  • 相关阅读:
    ES6 新特性
    基于.NET平台常用的框架整理
    你可能不知道的一些JavaScript 奇技淫巧
    js中apply方法的使用
    数据库中字段类型对应C#中的数据类型
    C# Socket SSL通讯笔记
    Media Types
    JS使用模板快速填充HTML控件数据 --- 自己写组件(0)
    FastDFS的配置、部署与API使用解读(8)FastDFS多种文件上传接口详解
    FastDFS的配置、部署与API使用解读(7)Nginx的FastDFS模块
  • 原文地址:https://www.cnblogs.com/joey-hua/p/6211596.html
Copyright © 2020-2023  润新知