Пример #1
0
        internal static TableAddStatus AddFun(FunSymbol funItem)
        {
            if (FindFun(funItem.name) != null)
            {
                return(TableAddStatus.SYMBOL_EXIST);
            }

            funs.Add(funItem.name, funItem);
            return(TableAddStatus.SUCCEED);
        }
Пример #2
0
 private void Paras(FunSymbol fun)
 {
     if (Utils.IsTypeTag(next.Tag))
     {
         Para(fun);
         if (TagIs(Tag.DL_COM))
         {
             Move();
             Paras(fun);
         }
     }
 }
Пример #3
0
        private void Para(FunSymbol fun)
        {
            VarSymbol para = new VarSymbol();

            para.type = Utils.TagToType(next.Tag);
            Move();

            string id = TagIs(Tag.ID) ? next.Value : null;

            if (id != null)
            {
                Move();
            }

            if (para.type != VarType.TYPE_VOID)
            {
                para.scopeId     = ScopeManager.CurrentScope;
                para.offsetInFun = -(2 + fun.parasType.Count) * 8;

                if (TagIs(Tag.DL_LSQU))
                {
                    para.eleType = para.type;
                    para.eleSize = Utils.SizeOf(para.eleType);
                    para.type    = VarType.TYPE_PTR;
                    Move();
                    RequiredToken(Tag.DL_RSQU);
                }
            }

            if (id != null)
            {
                para.name = id;
                if (SymbolTable.AddVar(para) == TableAddStatus.SYMBOL_EXIST)
                {
                    new ConflictingDeclarationError().PrintErrMsg();
                }
            }

            fun.parasType.Add(para.type);
        }
Пример #4
0
        private void Function(FunctionNode node)
        {
            FunSymbol fun = new FunSymbol();

            fun.returnType = Utils.TagToType(next.Tag);
            Move();

            string id = RequiredToken(Tag.ID);

            if (id != null)
            {
                fun.name  = id;
                node.name = id;
                ScopeManager.FunctionEnter(id);
            }

            ScopeManager.ScopeEnter();

            RequiredToken(Tag.DL_LPAR);
            Paras(fun);
            if (fun.parasType.Count > 1 && fun.parasType.Contains(VarType.TYPE_VOID))
            {
                new Error().PrintErrMsg();
            }
            else if (fun.parasType.Contains(VarType.TYPE_VOID))
            {
                fun.parasType = new List <VarType>();
            }
            RequiredToken(Tag.DL_RPAR);

            // 查看符号表中是否有同名函数
            FunSymbol tmp          = SymbolTable.FindFun(fun.name);
            bool      sameFunExist = false;

            if (tmp != null)
            {
                // 若存在同名函数则检查函数签名
                if (tmp.parasType.Count == fun.parasType.Count)
                {
                    int i = 0;
                    for (i = 0; i < tmp.parasType.Count; i++)
                    {
                        if (tmp.parasType[i] != fun.parasType[i])
                        {
                            break;
                        }
                    }

                    sameFunExist = i == tmp.parasType.Count && tmp.returnType == fun.returnType;
                }
            }

            if (TagIs(Tag.DL_LBRACE))
            {
                // 函数定义
                fun.isExtern = false;
                if (sameFunExist)
                {
                    if (tmp.isExtern)
                    {
                        tmp.isExtern = false;                         // 存在函数定义,符号表中已有的函数不再是extern
                    }
                    else
                    {
                        new Error().PrintErrMsg();                         // 存在重复定义
                    }
                }
            }
            else if (TagIs(Tag.DL_SEM))
            {
                // 函数声明
                fun.isExtern = true;
            }

            if (!sameFunExist)
            {
                if (SymbolTable.AddFun(fun) == TableAddStatus.SYMBOL_EXIST)
                {
                    // 不同签名的函数名冲突
                    new Error().PrintErrMsg();
                }
            }

            if (TagIs(Tag.DL_SEM))
            {
                Move();
            }
            else
            {
                node.body = new BlockNode();
                Block(node.body);
            }

            ScopeManager.ScopeLeave();
            ScopeManager.FunctionLeave();
        }
Пример #5
0
        private void Decl(DeclNode node)
        {
            FunSymbol function = SymbolTable.FindFun(ScopeManager.CurrentFun);
            VarSymbol variable = new VarSymbol();

            if (TagIs(Tag.KW_CONST))
            {
                variable.isConst = true;
                Move();
            }

            node.type = Utils.TagToType(next.Tag);
            Move();

            if (node.type == VarType.TYPE_VOID)
            {
                new Error().PrintErrMsg();
            }

            node.name = RequiredToken(Tag.ID);

            if (TagIs(Tag.DL_SET))
            {
                Move();
                node.init = new ExprNode();
                Expr(node.init);

                if (node.init.Type() != node.type)
                {
                    if (!Utils.IsNumType(node.init.Type()) || !Utils.IsNumType(node.type))
                    {
                        new TypeMismatchError(node.type, node.init.Type()).PrintErrMsg();
                    }
                }
            }
            else if (TagIs(Tag.DL_LSQU))
            {
                Move();
                variable.eleSize = Utils.SizeOf(node.type);
                variable.eleType = node.type;
                variable.isConst = true;
                node.type        = VarType.TYPE_PTR;
                node.size        = new ExprNode();
                Expr(node.size);

                if (!Utils.IsNumType(node.size.Type()) || !node.size.IsConstant())
                {
                    new Error().PrintErrMsg();
                }
                else
                {
                    function.localVarSize += (int)(node.size.Val() as IntNode).value * variable.eleSize;
                }

                RequiredToken(Tag.DL_RSQU);
            }

            if (node.name != null)
            {
                function.localVarSize += Utils.SizeOf(node.type);

                variable.name        = node.name;
                variable.type        = node.type;
                variable.scopeId     = ScopeManager.CurrentScope;
                variable.offsetInFun = function.localVarSize;

                if (SymbolTable.AddVar(variable) == TableAddStatus.SYMBOL_EXIST)
                {
                    new ConflictingDeclarationError().PrintErrMsg();
                }
            }

            RequiredToken(Tag.DL_SEM);
        }