zoukankan      html  css  js  c++  java
  • 自制编译器 青木峰郎 笔记 Ch9 语义分析(1) 引用消解

    9.1 语义分析概要

    本章目的

    1. 引用消解
    2. 类型名称消解: TypeRef->Type
    3. 类型定义检查:比如不能新建void的数组,void的成员结构体,直接将自身类型作为子成员的结构体等问题
    4. 表达式有效性检查: 比如1++
    5. 静态类型检查,比如在结构体间进行了未定义的+操作,或者是将int类型的值直接赋给指针类型的变量等

    介绍了Vistor模式来做类型检查,比如:

    public class VariableNode extends LHSNode {
        public <S,E> E accept(ASTVisitor<S,E> visitor) {
            return visitor.visit(this);
        }
    
    
    class IRGenerator implements ASTVisitor<Void, Expr> {
        public Void visit(CaseNode node) {
            throw new Error("must not happen");
        }
    
        // #@@range/While{
        public Void visit(WhileNode node) {
            Label begLabel = new Label();
            Label bodyLabel = new Label();
            Label endLabel = new Label();
    
            label(begLabel);
            cjump(node.location(),
                    transformExpr(node.cond()), bodyLabel, endLabel);
            label(bodyLabel);
            pushContinue(begLabel);
            pushBreak(endLabel);
            transformStmt(node.body());
            popBreak();
            popContinue();
            jump(begLabel);
            label(endLabel);
            return null;
        }
        // #@@}
    

    9.2 变量引用的消解

    目的: 确定变量及函数具体指向哪个作用域Scope
    作用域类Scope: Scope/TopLevelScope/LocalScope

    
    abstract public class Scope {
        protected List<LocalScope> children;
    
        public Scope() {
            children = new ArrayList<LocalScope>();
        }
    
        abstract public boolean isToplevel();
        abstract public ToplevelScope toplevel();
        abstract public Scope parent();
    
        protected void addChild(LocalScope s) {
            children.add(s);
        }
    
        abstract public Entity get(String name) throws SemanticException;
    }
    public class ToplevelScope extends Scope {
        protected Map<String, Entity> entities;
        protected List<DefinedVariable> staticLocalVariables;   // cache
          ...
    }
    public class LocalScope extends Scope {
        protected Scope parent;
        protected Map<String, DefinedVariable> variables;
          ...
    }
    

    Scope可以被认为是符号表的一种,因此cb直接在引用消解这一步传出了符号表。
    主逻辑:

    public class LocalResolver extends Visitor {
        // #@@range/ctor{
        private final LinkedList<Scope> scopeStack;
        private final ConstantTable constantTable;
        private final ErrorHandler errorHandler;
    
        public LocalResolver(ErrorHandler h) {
            this.errorHandler = h;
            this.scopeStack = new LinkedList<Scope>();
            this.constantTable = new ConstantTable();
        }
        // #@@}
    
        private void resolve(StmtNode n) {
            n.accept(this);
        }
    
        private void resolve(ExprNode n) {
            n.accept(this);
        }
    
        // #@@range/resolve{
        public void resolve(AST ast) throws SemanticException {
            ToplevelScope toplevel = new ToplevelScope();
            scopeStack.add(toplevel);
    
            // #@@range/declareToplevel{
            for (Entity decl : ast.declarations()) {
                toplevel.declareEntity(decl);
            }
            for (Entity ent : ast.definitions()) {
                toplevel.defineEntity(ent);
            }
            // #@@}
            // #@@range/resolveRefs{
            resolveGvarInitializers(ast.definedVariables());
            resolveConstantValues(ast.constants());
            resolveFunctions(ast.definedFunctions());
            // #@@}
            toplevel.checkReferences(errorHandler);
            if (errorHandler.errorOccured()) {
                throw new SemanticException("compile failed.");
            }
    
            ast.setScope(toplevel);
            ast.setConstantTable(constantTable);
        }
        // #@@}
    
        // #@@range/resolveGvarInitializers{
        private void resolveGvarInitializers(List<DefinedVariable> gvars) {
            for (DefinedVariable gvar : gvars) {
                if (gvar.hasInitializer()) {
                    resolve(gvar.initializer());
                }
            }
        }
        // #@@}
    
        private void resolveConstantValues(List<Constant> consts) {
            for (Constant c : consts) {
                resolve(c.value());
            }
        }
    
        // #@@range/resolveFunctions{
        private void resolveFunctions(List<DefinedFunction> funcs) {
            for (DefinedFunction func : funcs) {
                pushScope(func.parameters());
                resolve(func.body());
                func.setScope(popScope());
            }
        }
        // #@@}
    
        // #@@range/BlockNode{
        public Void visit(BlockNode node) {
            pushScope(node.variables());
            super.visit(node);
            node.setScope(popScope());
            return null;
        }
        // #@@}
    
        // #@@range/pushScope{
        private void pushScope(List<? extends DefinedVariable> vars) {
            LocalScope scope = new LocalScope(currentScope());
            for (DefinedVariable var : vars) {
                if (scope.isDefinedLocally(var.name())) {
                    error(var.location(),
                        "duplicated variable in scope: " + var.name());
                }
                else {
                    scope.defineVariable(var);
                }
            }
            scopeStack.addLast(scope);
        }
        // #@@}
    
        // #@@range/popScope{
        private LocalScope popScope() {
            return (LocalScope)scopeStack.removeLast();
        }
        // #@@}
    
        // #@@range/currentScope{
        private Scope currentScope() {
            return scopeStack.getLast();
        }
        // #@@}
    
        // #@@range/StringLiteralNode{
        public Void visit(StringLiteralNode node) {
            node.setEntry(constantTable.intern(node.value()));
            return null;
        }
        // #@@}
    
        // #@@range/VariableNode{
        public Void visit(VariableNode node) {
            try {
                Entity ent = currentScope().get(node.name());
                ent.refered();
                node.setEntity(ent);
            }
            catch (SemanticException ex) {
                error(node, ex.getMessage());
            }
            return null;
        }
        // #@@}
    
        private void error(Node node, String message) {
            errorHandler.error(node.location(), message);
        }
    
        private void error(Location loc, String message) {
            errorHandler.error(loc, message);
        }
    }
    
    

    这里的设计:在Visitor内部避免抛出异常继续向前处理。
    注意visit(BlockNode node),对于BlockNode,需要建立临时作用域。

    9.3 类型名称消解

    目的: TypeRef指向具体Type
    Scope: 认为只有一个作用域-TopScope,所以无需使用Scope树

    public class TypeResolver extends Visitor
            implements EntityVisitor<Void>, DeclarationVisitor<Void> {
        // #@@range/ctor{
        private final TypeTable typeTable;
        private final ErrorHandler errorHandler;
    
        public TypeResolver(TypeTable typeTable, ErrorHandler errorHandler) {
            this.typeTable = typeTable;
            this.errorHandler = errorHandler;
        }
        // #@@}
    
        // #@@range/resolveProgram{
        public void resolve(AST ast) {
    //先处理Type定义,再t.accept处理成员变量以防止无限递归
            defineTypes(ast.types());
            // #@@range/resolveProgram_core{
            for (TypeDefinition t : ast.types()) {
                t.accept(this);
            }
    //处理外部引用
            for (Entity e : ast.entities()) {
                e.accept(this);
            }
            // #@@}
        }
        // #@@}
    
        // #@@range/defineTypes{
        private void defineTypes(List<TypeDefinition> deftypes) {
            for (TypeDefinition def : deftypes) {
                if (typeTable.isDefined(def.typeRef())) {
                    error(def, "duplicated type definition: " + def.typeRef());
                }
                else {
                    typeTable.put(def.typeRef(), def.definingType());
                }
            }
        }
        // #@@}
    
        // #@@range/bindType{
        private void bindType(TypeNode n) {
            if (n.isResolved()) return;
            n.setType(typeTable.get(n.typeRef()));
        }
        // #@@}
    
        //
        // Declarations
        //
    
        // #@@range/StructNode{
        public Void visit(StructNode struct) {
            resolveCompositeType(struct);
            return null;
        }
        // #@@}
    
        // #@@range/UnionNode{
        public Void visit(UnionNode union) {
            resolveCompositeType(union);
            return null;
        }
        // #@@}
    
        // #@@range/resolveCompositeType{
        public void resolveCompositeType(CompositeTypeDefinition def) {
            CompositeType ct = (CompositeType)typeTable.get(def.typeNode().typeRef());
            if (ct == null) {
                throw new Error("cannot intern struct/union: " + def.name());
            }
            for (Slot s : ct.members()) {
                bindType(s.typeNode());
            }
        }
        // #@@}
    
        // #@@range/TypedefNode{
        public Void visit(TypedefNode typedef) {
            bindType(typedef.typeNode());
            bindType(typedef.realTypeNode());
            return null;
        }
        // #@@}
    
        //
        // Entities
        //
    
        // #@@range/DefinedVariable{
        public Void visit(DefinedVariable var) {
            bindType(var.typeNode());
            if (var.hasInitializer()) {
                visitExpr(var.initializer());
            }
            return null;
        }
        // #@@}
    
        public Void visit(UndefinedVariable var) {
            bindType(var.typeNode());
            return null;
        }
    
        public Void visit(Constant c) {
            bindType(c.typeNode());
            visitExpr(c.value());
            return null;
        }
    
        // #@@range/DefinedFunction{
        public Void visit(DefinedFunction func) {
            resolveFunctionHeader(func);
            visitStmt(func.body());
            return null;
        }
        // #@@}
    
        public Void visit(UndefinedFunction func) {
            resolveFunctionHeader(func);
            return null;
        }
    
        // #@@range/resolveFunctionHeader{
        private void resolveFunctionHeader(Function func) {
            bindType(func.typeNode());
            for (CBCParameter param : func.parameters()) {
                // arrays must be converted to pointers in a function parameter.
                Type t = typeTable.getParamType(param.typeNode().typeRef());
                param.typeNode().setType(t);
            }
        }
        // #@@}
    
        //
        // Expressions
        //
    
        public Void visit(BlockNode node) {
            for (DefinedVariable var : node.variables()) {
                var.accept(this);
            }
            visitStmts(node.stmts());
            return null;
        }
    
        public Void visit(CastNode node) {
            bindType(node.typeNode());
            super.visit(node);
            return null;
        }
    
        public Void visit(SizeofExprNode node) {
            bindType(node.typeNode());
            super.visit(node);
            return null;
        }
    
        public Void visit(SizeofTypeNode node) {
            bindType(node.operandTypeNode());
            bindType(node.typeNode());
            super.visit(node);
            return null;
        }
    
        public Void visit(IntegerLiteralNode node) {
            bindType(node.typeNode());
            return null;
        }
    
        public Void visit(StringLiteralNode node) {
            bindType(node.typeNode());
            return null;
        }
    
        private void error(Node node, String msg) {
            errorHandler.error(node.location(), msg);
        }
    }
    
    
  • 相关阅读:
    9.8
    9.6
    9.5
    树状数组
    逆序对
    tab标签切换(无炫效果,简单的显示隐藏)
    JQuery 的选择器
    简单的JQuery top返回顶部
    Hello Word!
    java Data 计算自己活了多少天
  • 原文地址:https://www.cnblogs.com/xuesu/p/14381933.html
Copyright © 2011-2022 走看看