예제 #1
0
 //number→real_number |integer 产生实数或整数
 public static Value eval_number(NonterminalStackElement number_node)
 {
     if (number_node.branches.Count != 1)
     {
         throw new ExecutorException("文法发生了变化", number_node.linenum);
     }
     else
     {
         StackElement number = (StackElement)number_node.branches[0];
         if (number.type_code == 2)
         {
             IntStackElement int_number = (IntStackElement)number;
             return(new IntValue("int", true, int_number.content, int_number.linenum));
         }
         else if (number.type_code == 5)
         {
             RealStackElement real_number = (RealStackElement)number;
             return(new RealValue("real", true, real_number.content, real_number.linenum));
         }
         else
         {
             throw new ExecutorException("文法发生了变化", number_node.linenum);
         }
     }
 }
예제 #2
0
        /* term → factor more_factor
         *   factor→+factor |-factor|number|identifier more_identifier|(expr)|"string"|'char'
         *   more_factor→ε|mul_op factor more_factor
         *     mul_op → *|/
         * 如法炮制
         */
        public static Value eval_term(NonterminalStackElement term_node, List <Dictionary <string, Value> > bindings_stack)
        {
            NonterminalStackElement factor_node = (NonterminalStackElement)term_node.branches[0];
            NonterminalStackElement more_factor_node;

            more_factor_node = (NonterminalStackElement)term_node.branches[1];
            Value first_factor_value = eval_factor(factor_node, bindings_stack);

            //more_factor → ε
            while (more_factor_node.branches.Count == 3)
            {
                NonterminalStackElement   mul_op_node        = (NonterminalStackElement)more_factor_node.branches[0];
                OtherTerminalStackElement mul_op             = (OtherTerminalStackElement)mul_op_node.branches[0];
                NonterminalStackElement   second_factor_node = (NonterminalStackElement)more_factor_node.branches[1];
                Value second_factor_value = eval_factor(second_factor_node, bindings_stack);
                if (Value.computable_types.Contains(first_factor_value.type) && Value.computable_types.Contains(second_factor_value.type))
                {
                    first_factor_value = first_factor_value.mathCalculate(second_factor_value, mul_op.content);
                }
                else
                {
                    throw new ExecutorException("无法直接进行乘除运算的类型", mul_op.linenum);
                }
                more_factor_node = (NonterminalStackElement)more_factor_node.branches[2];
            }
            return(first_factor_value);
        }
예제 #3
0
        //执行stmt_lst,可能是一个函数的{stmt_lst},也可能就是一个局部的函数块
        //有三种可能,return 3返回了一个值,return;没有返回值,或者真的没有return语句,分别对应Value,NullValue,Null
        private static Value executeStmtLst(NonterminalStackElement stmt_lst_node, List <Dictionary <string, Value> > binding_stack)
        {
            //func_definition → type func_declaratee {stmt_lst}
            //stmt_lst → stmt stmt_lst | stmt
            NonterminalStackElement stmt_node          = (NonterminalStackElement)stmt_lst_node.branches[0];
            NonterminalStackElement specific_stmt_node = (NonterminalStackElement)stmt_node.branches[0];

            while (stmt_lst_node.branches.Count == 2)
            {
                stmt_node          = (NonterminalStackElement)stmt_lst_node.branches[0];
                specific_stmt_node = (NonterminalStackElement)stmt_node.branches[0];
                stmt_lst_node      = (NonterminalStackElement)stmt_lst_node.branches[1];
                Value result_value_ = executeStmt(specific_stmt_node, binding_stack);
                //执行指令,如果是return语句,就会返回一个Value,哪怕是return;,也会返回一个NullValue
                if (result_value_ != null)
                {
                    result_value_.line_num = specific_stmt_node.linenum;
                    return(result_value_);
                }
                //返回Null,不是return语句,那就必然是要继续执行了,不做处理
            }
            stmt_node          = (NonterminalStackElement)stmt_lst_node.branches[0];
            specific_stmt_node = (NonterminalStackElement)stmt_node.branches[0];
            Value result_value = executeStmt(specific_stmt_node, binding_stack);

            //有三种可能,return了一个值,return;,或者真的没有return语句,分别对应Value,NullValue,Null
            return(result_value);
        }
예제 #4
0
 //自顶向下,深度优先遍历语法树(与生成树顺序一致)
 private static void goThroughAST_toExecute(StackElement e)
 {
     if (e.type_code == 3)
     {
         NonterminalStackElement ee = (NonterminalStackElement)e;
         if (ee.name == "func_definition")
         {
             addFuncDefinition(ee);
             return;
         }
         else if (ee.name == "declare_stmt")
         {
             declareVaraible(ee, mainFrameStack);
             return;
         }
         else
         {
             foreach (object b in e.branches)
             {
                 StackElement child = (StackElement)b;
                 goThroughAST_toExecute(child);
             }
         }
     }
 }
예제 #5
0
        //当该节点为declare_stmt时进入这个函数,把变量添加到符号表bindings
        //可能一个declare语句会声明很多个变量,这些变量可能是数组也可能不是,这些变量可能被赋值也可能没有
        // declare_stmt→type declaratee_lst;
        public static void declareVaraible(NonterminalStackElement declarate_stmt, List <Dictionary <string, Value> > bindings_stack)
        {
            if (declarate_stmt.branches.Count == 3)
            {
                NonterminalStackElement   type_nonterminal = (NonterminalStackElement)declarate_stmt.branches[0];
                OtherTerminalStackElement type_node        = (OtherTerminalStackElement)type_nonterminal.branches[0];
                //获得变量类型
                string type = type_node.content;
                //声明的所有变量名
                List <NonterminalStackElement> declaratees = new List <NonterminalStackElement>();
                //有两种可能:declaratee_lst→declaratee,declaratee_lst|declaratee
                NonterminalStackElement declaratee_lst_node = (NonterminalStackElement)declarate_stmt.branches[1];
                //处理递归,把每个declaratee加到declaratees
                while (declaratee_lst_node.branches.Count != 1)
                {
                    NonterminalStackElement first_declaratee_node = (NonterminalStackElement)declaratee_lst_node.branches[0];
                    declaratees.Add(first_declaratee_node);
                    declaratee_lst_node = (NonterminalStackElement)declaratee_lst_node.branches[2];
                }
                NonterminalStackElement declaratee_node = (NonterminalStackElement)declaratee_lst_node.branches[0];
                declaratees.Add(declaratee_node);

                //现在已经获取到的东西有:变量类型(暂时未区分数组),声明的变量个数,所有的declaratees
                //还缺少:初始化所有变量
                initialize_declaratees(type, declaratees, bindings_stack);
            }
            else
            {
                throw new ExecutorException("语法树的declare_stmt应该有且只有三个子结点");
            }
        }
예제 #6
0
 public FuncValue(string type, string funcName, NonterminalStackElement func_def_node, int line_num)
 {
     this.type          = type;
     this.funcName      = funcName;
     this.initialized   = true;
     this.func_def_node = func_def_node;
     this.line_num      = line_num;
 }
예제 #7
0
 /* Function: 返回type类型的Value
  * PS: 若不能返回type类型的Value,那么就报错
  * 引入type的原因:real i = 1 + 2; 在evaluate这个expr时,我们不知道到底是int还是real
  */
 public static Value eval_expr(NonterminalStackElement expr_node, List <Dictionary <string, Value> > bindings_stack)
 {
     if (expr_node.branches.Count != 1)
     {
         throw new ExecutorException("文法发生了变化", expr_node.linenum);
     }
     else
     {
         NonterminalStackElement logical_expr_node = (NonterminalStackElement)expr_node.branches[0];
         return(eval_logical_expr(logical_expr_node, bindings_stack));
     }
 }
예제 #8
0
 //logical_expr→relational_expr logical_expr_more
 //  logical_expr_more→ ε | logical_op relational_expr logical_expr_more
 public static Value eval_logical_expr(NonterminalStackElement logical_expr_node, List <Dictionary <string, Value> > bindings_stack)
 {
     if (logical_expr_node.branches.Count != 2)
     {
         throw new ExecutorException("文法发生了变化", logical_expr_node.linenum);
     }
     else
     {
         NonterminalStackElement relational_expr_node   = (NonterminalStackElement)logical_expr_node.branches[0];
         NonterminalStackElement logical_expr_more_node = (NonterminalStackElement)logical_expr_node.branches[1];
         Value first_relational_expr_value = eval_relational_expr(relational_expr_node, bindings_stack);
         //逐个迭代,很自然的左结合
         while (logical_expr_more_node.branches.Count == 3)
         {
             NonterminalStackElement   logical_op_node             = (NonterminalStackElement)logical_expr_more_node.branches[0];
             NonterminalStackElement   second_relational_expr_node = (NonterminalStackElement)logical_expr_more_node.branches[1];
             OtherTerminalStackElement logical_op = (OtherTerminalStackElement)logical_op_node.branches[0];
             if (logical_op.content == "&&")
             {
                 //short circuit evaluation短路求值
                 if (!first_relational_expr_value.getBoolean())
                 {
                     return(new BoolValue("bool", true, false, logical_op.linenum));
                 }
                 //短路求值!
                 Value second_relational_expr_value = eval_relational_expr(second_relational_expr_node, bindings_stack);
                 first_relational_expr_value = new BoolValue("bool", true, second_relational_expr_value.getBoolean(), logical_op.linenum);
             }
             else
             {
                 //short circuit evaluation短路求值
                 if (first_relational_expr_value.getBoolean())
                 {
                     return(new BoolValue("bool", true, true, logical_op.linenum));
                 }
                 //短路求值!
                 Value second_relational_expr_value = eval_relational_expr(second_relational_expr_node, bindings_stack);
                 first_relational_expr_value = new BoolValue("bool", true, second_relational_expr_value.getBoolean(), logical_op.linenum);
             }
             logical_expr_more_node = (NonterminalStackElement)logical_expr_more_node.branches[2];
         }
         return(first_relational_expr_value);
     }
 }
예제 #9
0
        //当该节点为func_definition时进入这个函数,把函数添加到全局符号表
        private static void addFuncDefinition(NonterminalStackElement ee)
        {
            NonterminalStackElement func_declaratee_node = (NonterminalStackElement)ee.branches[1];
            IdentifierStackElement  func_identifier_node = (IdentifierStackElement)func_declaratee_node.branches[0];
            string func_name = func_identifier_node.content;

            Console.WriteLine("AddFunc: " + func_name);
            FuncValue func = new FuncValue("func", func_name, ee, func_identifier_node.linenum);

            //检查重复声明
            if (globalSymbolTable.Keys.Contains(func_name))
            {
                throw new ExecutorException("已声明的变量或函数名" + func_name, func_identifier_node.linenum);
            }
            else
            {
                globalSymbolTable.Add(func_name, func);
            }
        }
예제 #10
0
        //传入代表数组长度的simple_expr,返回int类型数组长度
        //检查是否是正整数
        public static int get_array_len_from_simple_expr(NonterminalStackElement simple_expr, List <Dictionary <string, Value> > bindings_stack)
        {
            if (simple_expr.name != "simple_expr")
            {
                throw new ExecutorException("调用了ExecutorTools类的get_array_len_from_simple_expr方法,但是传入参数却并不是simple_expr");
            }
            Value array_len_v = Evaluator.eval_simple_expr(simple_expr, bindings_stack);

            if (array_len_v.type != "int")
            {
                throw new ExecutorException("数组长度应当是整数类型");
            }
            IntValue int_array_len = (IntValue)array_len_v;
            int      array_len     = int_array_len.value;

            if (array_len <= 0)
            {
                throw new ExecutorException("数组长度应当是正数");
            }
            return(array_len);
        }
예제 #11
0
        //relational_expr→simple_expr relational_expr_more 返回一个value,这个value是truthy还是falsey交给上层函数
        //  relational_expr_more →ε | comparasion_op simple_expr relational_expr_more
        //这里只要进行了compare,那返回int value而不是其他的,其原因是:3>2>1 -> false
        public static Value eval_relational_expr(NonterminalStackElement relational_expr_node, List <Dictionary <string, Value> > bindings_stack)
        {
            NonterminalStackElement simple_expr_node          = (NonterminalStackElement)relational_expr_node.branches[0];
            NonterminalStackElement relational_expr_more_node = (NonterminalStackElement)relational_expr_node.branches[1];
            //这里面临一个问题,如果comparison是==或者空,那么simple_expr什么都可以,如果comparison是> <=等等,那就只能是number
            Value first_simple_expr_value = eval_simple_expr(simple_expr_node, bindings_stack);

            while (relational_expr_more_node.branches.Count == 3)
            {
                NonterminalStackElement comparison_op_node = (NonterminalStackElement)relational_expr_more_node.branches[0];
                NonterminalStackElement second_simple_expr = (NonterminalStackElement)relational_expr_more_node.branches[1];
                relational_expr_more_node = (NonterminalStackElement)relational_expr_more_node.branches[2];
                OtherTerminalStackElement comparison_op = (OtherTerminalStackElement)comparison_op_node.branches[0];
                if (comparison_op.content == "==")
                {
                    first_simple_expr_value = first_simple_expr_value.compareWith(eval_simple_expr(second_simple_expr, bindings_stack));
                }
                //这里相对上面是反过来的(不等于)
                else if (comparison_op.content == "!=" || comparison_op.content == "<>")
                {
                    IntValue result = first_simple_expr_value.compareWith(eval_simple_expr(second_simple_expr, bindings_stack));
                    if (result.value == 0)
                    {
                        result.value = 1;
                    }
                    else
                    {
                        result.value = 0;
                    }
                    first_simple_expr_value = result;
                }
                else
                {
                    first_simple_expr_value = first_simple_expr_value.compareWith(eval_simple_expr(second_simple_expr, bindings_stack), comparison_op.content);
                }
            }
            return(first_simple_expr_value);
        }
        private void drawTheAbstractSyntaxTree()
        {
            int index = 0;

            while (Parser.stack_to_parse.Count != 0)
            {
                //获取栈的最里面的节点
                StackElement first_ele = (StackElement)Parser.stack_to_parse.Peek();
                //准备添加的树节点
                TreeViewItem new_node = new TreeViewItem();
                if (first_ele.type_code == 6)
                {
                    Parser.stack_to_parse.Pop();
                    continue;
                }
                else if (first_ele.type_code != 3)
                {
                    throw new ParserException("怎么会有不是非终结符的最外层栈元素,它怎么过的语法分析?");
                }
                else
                {
                    NonterminalStackElement e = (NonterminalStackElement)first_ele;
                    try
                    {
                        Console.WriteLine("index" + index);
                        recursiveAddNodes(e, new_node);
                    }
                    catch (Exception ee)
                    {
                        Console.WriteLine(ee);
                    }
                    myAST_Node1.Items.Add(new_node);
                    return;
                }
            }
        }
예제 #13
0
        /* Function: 返回type类型的Value
         * 若不能返回type类型的Value,那么就报错
         * 注意:要区分负数,把负数放到value里面返回
         * 引入type的原因:real i = 1 + 2; 在evaluate这个expr时,我们不知道到底是int还是real
         * 相关的产生式:
         * simple_expr→term more_term
         *   term→factor more_factor
         *   more_term→ε|add_op term more_term
         *     add_op→+|-
         */
        public static Value eval_simple_expr(NonterminalStackElement simple_expr_node, List <Dictionary <string, Value> > bindings_stack)
        {
            NonterminalStackElement term_node      = (NonterminalStackElement)simple_expr_node.branches[0];
            NonterminalStackElement more_term_node = (NonterminalStackElement)simple_expr_node.branches[1];
            Value first_term_value = eval_term(term_node, bindings_stack);

            while (more_term_node.branches.Count == 3)
            {
                NonterminalStackElement   add_op_node      = (NonterminalStackElement)more_term_node.branches[0];
                OtherTerminalStackElement add_op           = (OtherTerminalStackElement)add_op_node.branches[0];
                NonterminalStackElement   second_term_node = (NonterminalStackElement)more_term_node.branches[1];
                Value second_term_value = eval_term(second_term_node, bindings_stack);
                if (Value.computable_types.Contains(first_term_value.type) && Value.computable_types.Contains(second_term_value.type))
                {
                    first_term_value = first_term_value.mathCalculate(second_term_value, add_op.content);
                }
                else
                {
                    throw new ExecutorException("无法直接进行加减运算的类型", add_op.linenum);
                }
                more_term_node = (NonterminalStackElement)more_term_node.branches[2];
            }
            return(first_term_value);
        }
예제 #14
0
        //执行某个具体的stmt,
        // stmt → if_stmt| while_stmt|read_stmt| write_stmt|assign_stmt|declare_stmt| →compound_stmt|return_stmt|expr_stmt
        // while_substmt →while_if_stmt| while_stmt|read_stmt| write_stmt|assign_stmt|declare_stmt| →while_compound_stmt|return_stmt|expr_stmt | break_stmt | continue_stmt
        // 有三种可能,return了一个值,return;,或者真的没有return语句,分别对应Value,NullValue,Null
        private static Value executeStmt(NonterminalStackElement specific_stmt_node, List <Dictionary <string, Value> > binding_stack)
        {
            string message = "";

            //if_stmt→if(expr)compound_stmt more_ifelse
            if (specific_stmt_node.name == "if_stmt")
            {
                NonterminalStackElement expr_node = (NonterminalStackElement)specific_stmt_node.branches[2];
                Value expr_value = Evaluator.eval_expr(expr_node, binding_stack);
                if (expr_value.getBoolean())
                {
                    NonterminalStackElement compound_stmt = (NonterminalStackElement)specific_stmt_node.branches[4];
                    return(executeStmt(compound_stmt, binding_stack));
                }
                else
                {
                    //more_ifelse→ε|else else_stmt
                    NonterminalStackElement more_if_else_node = (NonterminalStackElement)specific_stmt_node.branches[5];
                    if (more_if_else_node.branches.Count == 0)
                    {
                        return(null);
                    }
                    else
                    {
                        //else_stmt→if_stmt|compound_stmt
                        NonterminalStackElement else_stmt          = (NonterminalStackElement)more_if_else_node.branches[1];
                        NonterminalStackElement specific_else_stmt = (NonterminalStackElement)else_stmt.branches[0];
                        return(executeStmt(specific_else_stmt, binding_stack));
                    }
                }
                //emmm突然优雅起来了???
            }
            //while_stmt→while(expr)  while_compound_stmt
            else if (specific_stmt_node.name == "while_stmt")
            {
                NonterminalStackElement expr_node = (NonterminalStackElement)specific_stmt_node.branches[2];
                Value expr_value = Evaluator.eval_expr(expr_node, binding_stack);
                Dictionary <string, Value> new_bindings = new Dictionary <string, Value>();
                binding_stack.Add(new_bindings);
                Executor.while_indexes.Add(binding_stack.Count);
                //while_compound_stmt→{while_stmt_lst}|{}
                //while_stmt_lst →while_substmt while_stmt_lst | while_substmt
                NonterminalStackElement while_compound_stmt_node = (NonterminalStackElement)specific_stmt_node.branches[4];
                while (expr_value.getBoolean())
                {
                    if (while_compound_stmt_node.branches.Count == 2)
                    {
                        //do nothing
                    }
                    //while_compound_stmt→{while_stmt_lst}
                    else
                    {
                        NonterminalStackElement while_stmt_lst_node = (NonterminalStackElement)while_compound_stmt_node.branches[1];
                        Value v = executeStmtLst(while_stmt_lst_node, binding_stack);
                        //若提前执行return语句,直接结束while循环
                        if (v != null)
                        {
                            binding_stack.RemoveAt(binding_stack.Count - 1);
                            return(v);
                        }
                    }
                    expr_value = Evaluator.eval_expr(expr_node, binding_stack);
                }
                binding_stack.RemoveAt(binding_stack.Count - 1);
                return(null);
            }
            //read_stmt→read identifier;| read identifier [ simple_expr ] ;
            else if (specific_stmt_node.name == "read_stmt")
            {
                IdentifierStackElement identifier_node = (IdentifierStackElement)specific_stmt_node.branches[1];
                if (specific_stmt_node.branches.Count == 3)
                {
                    Dictionary <string, Value> bindings = findBindings(binding_stack, identifier_node.content);
                    if (bindings != null)
                    {
                        string type = bindings[identifier_node.content].type;
                        if (type.Contains("func") || type.Contains("bool"))
                        {
                            throw new ExecutorException("请检查您的读入目标是否有误,不可读入函数或者布尔类型值", specific_stmt_node.linenum);
                        }
                        else if (type.Contains("Array"))
                        {
                            int len = bindings[identifier_node.content].getArrayLen();
                            bindings[identifier_node.content] = ReaderHelper.read_array_value(type, identifier_node.linenum, len);
                        }
                        else
                        {
                            bindings[identifier_node.content] = ReaderHelper.read_single_value(type, identifier_node.linenum);
                        }
                    }
                    else
                    {
                        throw new ExecutorException("未定义的标识符" + identifier_node.content, identifier_node.linenum);
                    }
                }
                else
                {
                    Dictionary <string, Value> bindings = findBindings(binding_stack, identifier_node.content);
                    if (bindings != null)
                    {
                        string type = bindings[identifier_node.content].type;
                        if (!type.Contains("Array"))
                        {
                            throw new ExecutorException("请检查您的读入目标是否有误,该标识符并不对应数组", specific_stmt_node.linenum);
                        }
                        NonterminalStackElement simple_expr_node = (NonterminalStackElement)specific_stmt_node.branches[3];
                        int index = get_array_len_from_simple_expr(simple_expr_node, binding_stack);
                        type = type.Substring(0, type.Length - 5);
                        Value read_value = ReaderHelper.read_single_value(type, identifier_node.linenum);
                        bindings[identifier_node.content].changeValueOfArray(index, read_value.getString());
                    }
                    else
                    {
                        throw new ExecutorException("未定义的标识符" + identifier_node.content, identifier_node.linenum);
                    }
                }
                return(null);
            }
            //write_stmt→write expr;
            else if (specific_stmt_node.name == "write_stmt")
            {
                NonterminalStackElement expr_node = (NonterminalStackElement)specific_stmt_node.branches[1];
                Value v = Evaluator.eval_expr(expr_node, binding_stack);
                if (v.type == "func")
                {
                    throw new ExecutorException("不支持write函数", specific_stmt_node.linenum);
                }
                WriterHelper.write_value(v, specific_stmt_node.linenum);
                return(null);
            }
            //assign_stmt→identifier other_assign
            else if (specific_stmt_node.name == "assign_stmt")
            {
                IdentifierStackElement  identifier_node   = (IdentifierStackElement)specific_stmt_node.branches[0];
                NonterminalStackElement other_assign_node = (NonterminalStackElement)specific_stmt_node.branches[1];
                //other_assign→= expr; | [simple_expr] = expr;
                if (other_assign_node.branches.Count == 3)
                {
                    NonterminalStackElement    expr_node = (NonterminalStackElement)other_assign_node.branches[1];
                    Dictionary <string, Value> bindings  = findBindings(binding_stack, identifier_node.content);
                    if (bindings != null)
                    {
                        string type = bindings[identifier_node.content].type;
                        if (type.Contains("func"))
                        {
                            throw new ExecutorException("不可给函数赋值", identifier_node.linenum);
                        }
                        else if (type.Contains("Array"))
                        {
                            throw new ExecutorException("不可给数组类型赋单个的值", identifier_node.linenum);
                        }
                        else
                        {
                            Value v = Evaluator.eval_expr(expr_node, binding_stack);
                            bindings[identifier_node.content] = adjustType(type, v);
                        }
                    }
                    else
                    {
                        throw new ExecutorException("未定义的标识符" + identifier_node.content, identifier_node.linenum);
                    }
                }
                //other_assign → [simple_expr] = expr;
                else
                {
                    NonterminalStackElement    simple_expr_node = (NonterminalStackElement)other_assign_node.branches[1];
                    NonterminalStackElement    expr_node        = (NonterminalStackElement)other_assign_node.branches[4];
                    Dictionary <string, Value> bindings         = findBindings(binding_stack, identifier_node.content);
                    if (bindings != null)
                    {
                        string type = bindings[identifier_node.content].type;
                        if (type.Contains("func"))
                        {
                            throw new ExecutorException("不可给函数赋值", specific_stmt_node.linenum);
                        }
                        else if (type.Contains("Array"))
                        {
                            Value v = Evaluator.eval_expr(expr_node, binding_stack);
                            type = type.Substring(0, type.Length - 5);
                            //检查赋值的类型和变量类型是否相符
                            v = adjustType(type, v);
                            int index = get_array_len_from_simple_expr(simple_expr_node, binding_stack);
                            bindings[identifier_node.content].changeValueOfArray(index, v.getString());
                        }
                        else
                        {
                            throw new ExecutorException("该变量并不是数组类型,无法赋值", identifier_node.linenum);
                        }
                    }
                    else
                    {
                        throw new ExecutorException("未定义的标识符" + identifier_node.content, identifier_node.linenum);
                    }
                }
                return(null);
            }
            //declare_stmt→type declaratee_lst;
            else if (specific_stmt_node.name == "declare_stmt")
            {
                Executor.declareVaraible(specific_stmt_node, binding_stack);
                return(null);
            }
            // compound_stmt→{stmt_lst}|{}
            else if (specific_stmt_node.name == "compound_stmt")
            {
                if (specific_stmt_node.branches.Count == 2)
                {
                    return(null);
                }
                //{stmt_lst}执行完就要出栈bindings
                else
                {
                    Dictionary <string, Value> new_local_bindings = new Dictionary <string, Value>();
                    binding_stack.Add(new_local_bindings);
                    //stmt_lst → stmt stmt_lst | stmt
                    NonterminalStackElement stmt_lst_node = (NonterminalStackElement)specific_stmt_node.branches[1];
                    Value v = executeStmtLst(stmt_lst_node, binding_stack);
                    //{stmt_lst}执行完就要出栈bindings
                    binding_stack.RemoveAt(binding_stack.Count - 1);
                    return(v);
                }
            }
            // return_stmt→return expr; |  return;
            else if (specific_stmt_node.name == "return_stmt")
            {
                // return_stmt→ return;
                if (specific_stmt_node.branches.Count == 2)
                {
                    return(new NullValue(specific_stmt_node.linenum));
                }
                // return_stmt→return expr;
                else
                {
                    NonterminalStackElement expr_node = (NonterminalStackElement)specific_stmt_node.branches[1];
                    Value v = Evaluator.eval_expr(expr_node, binding_stack);
                    return(v);
                }
            }
            //expr_stmt→expr;
            else if (specific_stmt_node.name == "expr_stmt")
            {
                NonterminalStackElement expr_node = (NonterminalStackElement)specific_stmt_node.branches[0];
                Value v = Evaluator.eval_expr(expr_node, binding_stack);
                if (v == null)
                {
                    return(null);
                }
                if (v.type == "func")
                {
                    throw new ExecutorException("函数调用格式错误", specific_stmt_node.linenum);
                }
                else
                {
                    return(null);
                }
            }
            //while_if_stmt→if(expr)while_compound_stmt while_more_ifelse
            else if (specific_stmt_node.name == "while_if_stmt")
            {
                NonterminalStackElement expr_node = (NonterminalStackElement)specific_stmt_node.branches[2];
                Value expr_value = Evaluator.eval_expr(expr_node, binding_stack);
                if (expr_value.getBoolean())
                {
                    NonterminalStackElement compound_stmt = (NonterminalStackElement)specific_stmt_node.branches[4];
                    return(executeStmt(compound_stmt, binding_stack));
                }
                else
                {
                    NonterminalStackElement more_if_else_node = (NonterminalStackElement)specific_stmt_node.branches[5];
                    //while_more_ifelse→ε|else while_else_stmt
                    if (more_if_else_node.branches.Count == 0)
                    {
                        return(null);
                    }
                    else
                    {
                        //while_else_stmt→while_if_stmt | while_compound_stmt
                        NonterminalStackElement else_stmt          = (NonterminalStackElement)more_if_else_node.branches[1];
                        NonterminalStackElement specific_else_stmt = (NonterminalStackElement)else_stmt.branches[0];
                        return(executeStmt(specific_else_stmt, binding_stack));
                    }
                }
            }
            //while_compound_stmt→{while_stmt_lst}|{}
            else if (specific_stmt_node.name == "while_compound_stmt")
            {
                if (specific_stmt_node.branches.Count == 2)
                {
                    return(null);
                }
                //{stmt_lst}执行完就要出栈bindings
                else
                {
                    Dictionary <string, Value> new_local_bindings = new Dictionary <string, Value>();
                    binding_stack.Add(new_local_bindings);
                    NonterminalStackElement stmt_lst_node = (NonterminalStackElement)specific_stmt_node.branches[1];
                    //while_stmt_lst →while_substmt while_stmt_lst | while_substmt
                    Value v = executeStmtLst(stmt_lst_node, binding_stack);
                    //{stmt_lst}执行完就要出栈bindings
                    binding_stack.RemoveAt(binding_stack.Count - 1);
                    return(v);
                }
            }
            //break_stmt→break;
            else if (specific_stmt_node.name == "break_stmt")
            {
                throw new ExecutorException("暂不实现");
            }
            //continue_stmt→continue;
            else if (specific_stmt_node.name == "continue_stmt")
            {
                throw new ExecutorException("暂不实现");
            }
            else
            {
                throw new ExecutorException("Stmt/While_sub_stmt应该只有这些");
            }
        }
예제 #15
0
        //执行函数(传入参数,返回类型等等)
        //注意创建一个新的bindings和Stack,且这个Stack目前只有globalBingdings->newBindings
        //可能return null-->(仅在void函数中可能)
        public static Value executeFunction(FuncValue func_value, List <Value> arguments_lst, int linenum)
        {
            //可以看到,所有的东西都是局部变量,因此函数调用结束这些Bindings都会自动free
            List <Dictionary <string, Value> > binding_stack  = new List <Dictionary <string, Value> >();
            Dictionary <string, Value>         local_bindings = new Dictionary <string, Value>();

            binding_stack.Add(Executor.globalSymbolTable);
            binding_stack.Add(local_bindings);
            //获得返回类型
            NonterminalStackElement   return_type_node          = (NonterminalStackElement)func_value.func_def_node.branches[0];
            OtherTerminalStackElement specific_return_type_node = (OtherTerminalStackElement)return_type_node.branches[0];
            string return_type = specific_return_type_node.content;
            //获得函数名
            NonterminalStackElement func_declaratee = (NonterminalStackElement)func_value.func_def_node.branches[1];
            IdentifierStackElement  identifier_node = (IdentifierStackElement)func_declaratee.branches[0];
            string        func_name  = identifier_node.content;
            List <string> params_lst = new List <string>();

            //part1 传参

            //先把实参传进来(加到local_bindings顺便做一个类型检查,函数签名和传入参数)
            //func_declaratee →identifier()|identifier(param_lst)
            if (func_declaratee.branches.Count == 4)
            {
                int index = 0;
                NonterminalStackElement param_lst_node = (NonterminalStackElement)func_declaratee.branches[2];
                //param_lst→param_declaration,param_lst | param_declaration
                NonterminalStackElement param_declaration_node = (NonterminalStackElement)param_lst_node.branches[0];
                while (param_lst_node.branches.Count == 3)
                {
                    if (arguments_lst.Count <= index)
                    {
                        throw new ExecutorException("传入实参多于形参", linenum);
                    }
                    //param_declaration→type identifier|type identifier[simple_expr]
                    NonterminalStackElement   type_node          = (NonterminalStackElement)param_declaration_node.branches[0];
                    OtherTerminalStackElement specific_type_node = (OtherTerminalStackElement)type_node.branches[0];
                    IdentifierStackElement    identifier_Node    = (IdentifierStackElement)param_declaration_node.branches[1];
                    param_lst_node         = (NonterminalStackElement)param_lst_node.branches[2];
                    param_declaration_node = (NonterminalStackElement)param_lst_node.branches[0];
                    string type = specific_type_node.content;
                    //传入数组会更特殊
                    if (param_declaration_node.branches.Count == 4)
                    {
                        type += "Array";
                        if (arguments_lst[index].type != type)
                        {
                            throw new ExecutorException("函数形参类型与实际传入参数类型不符", linenum);
                        }
                        NonterminalStackElement simple_expr_node = (NonterminalStackElement)param_declaration_node.branches[3];
                        if (arguments_lst[index].getArrayLen() > get_array_len_from_simple_expr(simple_expr_node, binding_stack))
                        {
                            throw new ExecutorException("传入的数组长度大于对应的形参数组长度", linenum);
                        }
                    }
                    //如果符合要求,那就在local_bindings增加定义
                    if (arguments_lst[index].type == type)
                    {
                        local_bindings.Add(identifier_Node.content, arguments_lst[index]);
                        index++;
                    }
                    else
                    {
                        throw new ExecutorException("函数形参类型与实际传入参数类型不符", linenum);
                    }
                }
                if ((index + 1) > arguments_lst.Count)
                {
                    throw new ExecutorException("传入实参少于形参", linenum);
                }
                //最后一个参数,重复一遍上面的工作
                NonterminalStackElement   _type_node          = (NonterminalStackElement)param_declaration_node.branches[0];
                OtherTerminalStackElement _specific_type_node = (OtherTerminalStackElement)_type_node.branches[0];
                IdentifierStackElement    _identifier_Node    = (IdentifierStackElement)param_declaration_node.branches[1];
                string _type = _specific_type_node.content;
                //传入数组会更特殊
                if (param_declaration_node.branches.Count == 4)
                {
                    _type += "Array";
                    if (arguments_lst[index].type != _type)
                    {
                        throw new ExecutorException("函数形参类型与实际传入参数类型不符", linenum);
                    }
                    NonterminalStackElement simple_expr_node = (NonterminalStackElement)param_declaration_node.branches[3];
                    if (arguments_lst[index].getArrayLen() > get_array_len_from_simple_expr(simple_expr_node, binding_stack))
                    {
                        throw new ExecutorException("传入的数组长度大于对应的形参数组长度", linenum);
                    }
                }
                //如果符合要求,那就在local_bindings增加定义
                if (arguments_lst[index].type == _type)
                {
                    local_bindings.Add(_identifier_Node.content, arguments_lst[index]);
                    index++;
                }
                else
                {
                    throw new ExecutorException("函数形参类型与实际传入参数类型不符", linenum);
                }
            }
            //func_declaratee →identifier() 这样的话local_bindings就不需要任何东西了
            else
            {
                if (arguments_lst.Count != 0)
                {
                    throw new ExecutorException("函数" + identifier_node.content + "不需要接受任何参数", linenum);
                }
                //do nothing
            }

            //part2 实际执行
            //func_definition→type func_declaratee {stmt_lst} | type func_declaratee {}
            if (func_value.func_def_node.branches.Count == 4)
            {
                if (return_type == "void")
                {
                    return(null);
                }
                else
                {
                    throw new ExecutorException("函数" + identifier_node.content + "没有返回任何值", linenum);
                }
            }
            //func_definition → type func_declaratee {stmt_lst}
            //stmt_lst → stmt stmt_lst | stmt
            NonterminalStackElement stmt_lst_node = (NonterminalStackElement)func_value.func_def_node.branches[3];
            Value return_value = executeStmtLst(stmt_lst_node, binding_stack);

            //如果返回一个NullValue或者Null,那要检查是否是void
            if (return_value == null || return_value.type == "null")
            {
                if (return_type == "void")
                {
                    return(null);
                }
                else
                {
                    throw new ExecutorException("函数" + func_name + "的返回值必须是" + return_type + "类型", linenum);
                }
            }
            //返回不是Null,返回了一个实际的Value,那就要检查类型是否相符,检查返回类型不是void
            else
            {
                if (return_type == "void")
                {
                    throw new ExecutorException("函数" + func_name + "的返回值必须是null", linenum);
                }
                else
                {
                    try
                    {
                        Value v = adjustType(return_type, return_value);
                        return(v);
                    }
                    //重新捕获调整再抛出
                    catch (ExecutorException ee)
                    {
                        throw new ExecutorException("函数" + func_name + "的返回值必须是" + return_type + "类型", linenum);
                    }
                    catch (Exception eee)
                    {
                        throw eee;
                    }
                }
            }
        }
예제 #16
0
        //这里情况就不同了,上面是对应着+-*/四则运算的,所以char/string/数组 都不应该直接进行这些运算,但是他们可以被访问赋值,因此这里不做过多限制

        /*
         * factor→+factor |-factor|number|identifier more_identifier|(expr)|"string"|'char'
         *   more_identifier→ ε | [simple_expr]  |  ()  |  (param_values)
         *   number→real_number |integer
         */
        public static Value eval_factor(NonterminalStackElement factor_node, List <Dictionary <string, Value> > bindings_stack)
        {
            StackElement first_child = (StackElement)factor_node.branches[0];

            //factor → number | "string" | 'char'
            if (factor_node.branches.Count == 1)
            {
                //char
                if (first_child.type_code == 7)
                {
                    CharStackElement char_node = (CharStackElement)first_child;
                    return(new CharValue("char", true, char_node.content, char_node.linenum));
                }
                //string
                else if (first_child.type_code == 8)
                {
                    StringStackElement string_node = (StringStackElement)first_child;
                    return(new StringValue("string", true, string_node.content, string_node.linenum));
                }
                //number
                else if (first_child.type_code == 3)
                {
                    NonterminalStackElement number_node = (NonterminalStackElement)first_child;
                    return(eval_number(number_node));
                }
                else
                {
                    throw new ExecutorException("eval_factor运行中发现factor文法发生了意想不到的变化");
                }
            }
            //factor→+factor |-factor | identifier more_identifier
            else if (factor_node.branches.Count == 2)
            {
                //+ - factor
                if (first_child.type_code == 4)
                {
                    int linenum = ((OtherTerminalStackElement)first_child).linenum;
                    OtherTerminalStackElement positive_or_negative = (OtherTerminalStackElement)first_child;
                    NonterminalStackElement   child_factor_node    = (NonterminalStackElement)factor_node.branches[1];
                    if (positive_or_negative.content == "+")
                    {
                        return(eval_factor(child_factor_node, bindings_stack));
                    }
                    //负号就要把值的符号颠倒
                    else
                    {
                        Value child_factor_node_value = eval_factor(child_factor_node, bindings_stack);
                        if (!Value.computable_types.Contains(child_factor_node_value.type))
                        {
                            throw new ExecutorException("不可在非数值类型前加上正号或者负号", linenum);
                        }
                        if (child_factor_node_value.type == "real")
                        {
                            RealValue value = (RealValue)child_factor_node_value;
                            value.value = -value.value;
                            return(value);
                        }
                        else if (child_factor_node_value.type == "int")
                        {
                            IntValue value = (IntValue)child_factor_node_value;
                            value.value = -value.value;
                            return(value);
                        }
                        else if (child_factor_node_value.type == "number")
                        {
                            NumberValue value = (NumberValue)child_factor_node_value;
                            value.value = -value.value;
                            return(value);
                        }
                        else
                        {
                            throw new ExecutorException("eval_factor运行中发现factor文法发生了意想不到的变化");
                        }
                    }
                }
                //factor→ identifier more_identifier
                //  more_identifier→ε | [simple_expr]  |  ()  |  (param_values)
                else
                {
                    IdentifierStackElement identifier_node = (IdentifierStackElement)factor_node.branches[0];
                    int linenum = identifier_node.linenum;
                    NonterminalStackElement more_identifier_node = (NonterminalStackElement)factor_node.branches[1];
                    //检查是否定义
                    Dictionary <string, Value> bindings = ExecutorTools.findBindings(bindings_stack, identifier_node.content);
                    if (bindings != null)
                    {
                        //只是访问一个identifier 即 factor→ identifier
                        // more_identifier→ε
                        if (more_identifier_node.branches.Count == 0)
                        {
                            Value identifier_value = bindings[identifier_node.content];
                            return(identifier_value);
                        }
                        //应该是调用了一个不接受任何参数的函数比如foo()这样, more_identifier→ ()
                        else if (more_identifier_node.branches.Count == 2)
                        {
                            Value identifier_value = bindings[identifier_node.content];
                            if (identifier_value.type != "func")
                            {
                                throw new ExecutorException("标识符后带()应该是调用函数,但该标识符" + identifier_node.content + "对应函数并不存在", linenum);
                            }
                            FuncValue relevant_fucntion = (FuncValue)identifier_value;
                            Value     return_value      = relevant_fucntion.executeFunction();
                            return(return_value);
                        }
                        // 应该是调用了一个带参数的函数,或者是访问数组的某个元素 more_identifier → [simple_expr]  |  (param_values)
                        else if (more_identifier_node.branches.Count == 3)
                        {
                            Value identifier_value = bindings[identifier_node.content];
                            NonterminalStackElement second_element = (NonterminalStackElement)more_identifier_node.branches[1];
                            // more_identifier → [simple_expr]  要检查:第一,数组访问越界了没有;第二,访问的数组元素类型是否与要求的类型type相符合
                            if (second_element.name == "simple_expr")
                            {
                                //类型错误
                                if (!identifier_value.type.Contains("Array"))
                                {
                                    throw new ExecutorException("标识符后带[ ]应该是访问数组某个元素,但该标识符" + identifier_node.content + "对应的并不是数组", linenum);
                                }
                                string array_type = identifier_value.type.Substring(0, identifier_value.type.Length - 5);
                                NonterminalStackElement simple_expr_node = second_element;
                                int index_to_access = ExecutorTools.get_array_len_from_simple_expr(simple_expr_node, bindings_stack);
                                //越界错误
                                if (index_to_access >= identifier_value.getArrayLen())
                                {
                                    throw new ExecutorException("访问数组" + identifier_node.content + "时出现越界访问错误,数组长度只有" + identifier_value.getArrayLen(), linenum);
                                }
                                //eval要求就是获取到值,所以这里直接获取数组中元素的值,再转换为Value类型
                                else
                                {
                                    if (identifier_value.type.Contains("int"))
                                    {
                                        return(new IntValue("int", false, identifier_value.getIntArrayElement(index_to_access).ToString(), linenum));
                                    }
                                    else if (identifier_value.type.Contains("real"))
                                    {
                                        return(new RealValue("real", false, identifier_value.getRealArrayElement(index_to_access).ToString(), linenum));
                                    }
                                    else if (identifier_value.type.Contains("int"))
                                    {
                                        return(new CharValue("char", false, identifier_value.getCharArrayElement(index_to_access).ToString(), linenum));
                                    }
                                    else
                                    {
                                        return(new StringValue("string", false, identifier_value.getStringArrayElement(index_to_access).ToString(), linenum));
                                    }
                                }
                            }
                            // more_identifier → (param_values)  要检查:第一,函数签名是否符合(类型,次序);第二,函数返回类型是否与要求的类型type相符合
                            else if (second_element.name == "param_values")
                            {
                                //类型错误
                                if (!identifier_value.type.Contains("func"))
                                {
                                    throw new ExecutorException(identifier_node.content + "对应的并不是函数,无法调用", linenum);
                                }
                                FuncValue               func_value = (FuncValue)identifier_value;
                                List <Value>            args       = new List <Value>();
                                NonterminalStackElement expr_node;
                                //param_values →expr,param_values|expr
                                NonterminalStackElement param_values_node = second_element;
                                while (param_values_node.branches.Count == 3)
                                {
                                    expr_node         = (NonterminalStackElement)param_values_node.branches[0];
                                    param_values_node = (NonterminalStackElement)param_values_node.branches[2];
                                    args.Add(eval_expr(expr_node, bindings_stack));
                                }
                                expr_node = (NonterminalStackElement)param_values_node.branches[0];
                                args.Add(eval_expr(expr_node, bindings_stack));
                                return(ExecutorTools.executeFunction(func_value, args, linenum));
                            }
                            else
                            {
                                throw new ExecutorException("文法发生了变化", linenum);
                            }
                        }
                        else
                        {
                            //Value relevant_value = Frame.curr_frame.local_bindings[identifier_node.content];
                            throw new ExecutorException("怎么到这的?", linenum);
                        }
                    }
                    throw new ExecutorException("语句中访问未定义的标识符" + identifier_node.content, linenum);
                }
            }
            //factor→ ( expr )
            else if (factor_node.branches.Count == 3)
            {
                NonterminalStackElement expr_node = (NonterminalStackElement)factor_node.branches[1];
                return(eval_expr(expr_node, bindings_stack));
            }
            else
            {
                throw new ExecutorException("文法发生了变化", factor_node.linenum);
            }
        }
예제 #17
0
        public override string ToString()
        {
            string text = "";

            if (type_code == 1)
            {
                IdentifierStackElement e = (IdentifierStackElement)this;
                text += "第" + e.linenum + "行标识符";
                text += e.content;
            }
            else if (type_code == 2)
            {
                IntStackElement e = (IntStackElement)this;
                text += "第" + e.linenum + "行整数";
                text += e.content;
            }
            else if (type_code == 3)
            {
                NonterminalStackElement e = (NonterminalStackElement)this;
                text += "非终结符";
                text += e.name;
                //递归调用
                foreach (StackElement s in e.branches)
                {
                    text += Environment.NewLine;
                    for (int i = 1; i < s.layers; i++)
                    {
                        text += "  ";
                    }
                    text += s.ToString();
                }
            }
            else if (type_code == 4)
            {
                OtherTerminalStackElement e = (OtherTerminalStackElement)this;
                text += "第" + e.linenum + "行终结符";
                text += e.content;
            }
            else if (type_code == 5)
            {
                RealStackElement e = (RealStackElement)this;
                text += "第" + e.linenum + "行实数";
                text += e.content;
            }
            else if (type_code == 7)
            {
                CharStackElement e = (CharStackElement)this;
                text += "第" + e.linenum + "行字符";
                text += e.content;
            }
            else if (type_code == 8)
            {
                StringStackElement e = (StringStackElement)this;
                text += "第" + e.linenum + "行字符串";
                text += e.content;
            }
            else
            {
                StateStackElement e = (StateStackElement)this;
                text += "状态" + e.state;
            }
            return(text);
        }
예제 #18
0
 //执行五种语法动作之一   语法动作 - 目前的第一个token - 根据token构建的栈元素
 private static void conductAction(Action a, Token t, StackElement ele, StateStackElement first)
 {
     if (a.action == "error")
     {
         throw new ParserException("第" + t.lineNum + "行:" + "遇到无法解析的语法成分:" + Token.getALineOfTokens(t.lineNum));
     }
     else if (a.action == "shift")
     {
         stack_to_parse.Push(ele);
         stack_to_parse.Push(new StateStackElement(a.new_state));
         all_tokens.RemoveAt(0);
     }
     else if (a.action == "reduce")
     {
         //规约产生的肯定都是非终结符
         NonterminalStackElement e = new NonterminalStackElement(-1, a.left);
         int count = a.right.Count;
         for (int i = 0; i < count * 2; i++)
         {
             //第偶数个pop出去的元素不是代表状态的元素,是需要规约的元素
             if (i % 2 == 1)
             {
                 //保证是子结点是顺序的
                 StackElement s = (StackElement)stack_to_parse.Pop();
                 s.layersIncreaseRecursively();
                 e.branches.Insert(0, s);
             }
             else
             {
                 stack_to_parse.Pop();
             }
         }
         StateStackElement first_now = (StateStackElement)(stack_to_parse.Peek());
         Action            aa        = getActionByTransformedToken(first_now.state, e.type_code, a.left);
         if (aa.action == "shift")
         {
             stack_to_parse.Push(e);
             stack_to_parse.Push(new StateStackElement(aa.new_state));
         }
         else
         {
             throw new ParserException("规约之后难道不是移进吗");
         }
     }
     else if (a.action == "special action")
     {
         //根据当前状态,将自动移入的nullable非终结符,获取分析表要我们执行的动作
         Action next_action = GrammerConfig.analysis_table[first.state][a.auto_shifted];
         if (next_action.action == "shift")
         {
             stack_to_parse.Push(new NonterminalStackElement(-1, a.auto_shifted));
             stack_to_parse.Push(new StateStackElement(next_action.new_state));
         }
         else
         {
             throw new ParserException("special action自动移入才对呀");
         }
     }
     else
     {
         throw new ParserException("还未实现acc");
     }
 }
예제 #19
0
 public static bool parse_tokens()
 {
     try
     {
         all_tokens.Clear();
         stack_to_parse = new Stack <object>();
         StateStackElement initial_state = new StateStackElement(1);
         stack_to_parse.Push(initial_state);
         foreach (Token t in MainWindow.allTokens)
         {
             all_tokens.Add(t);
         }
         while (all_tokens.Count != 0)
         {
             //获取分析栈的状态(第一个状态元素)
             StateStackElement first = (StateStackElement)(stack_to_parse.Peek());
             //获取剩余tokens的第一个
             Token t = all_tokens[0];
             //根据第一个token,构建一个栈元素(type_code自动赋予,用来判断token是哪一种stackelement)
             StackElement ele = (StackElement)Tools.transformTokenToSymbol(t);
             //结合分析表,获取应该进行的语法动作
             Action a = getActionByTransformedToken(first.state, ele.type_code, t.content);
             //进行该语法动作
             conductAction(a, t, ele, first);
         }
         //下面这部分就与tokens无关了,如果上面tokens没有出错,就会进入下面的收尾部分:
         while (true)
         {
             //这部分的意义主要是在于,tokens一旦为空,上面的while循环自动结束,但是这并不意味着语法分析的结束
             //程序只是进行了最后一次真正token的移入,但是还有很多规约,甚至是报错的工作要进行
             //这一部分每次都会接收到一个我们固定的empty,如果程序认为它不能在empty下规约,那么要么是到了最后的E,要么是报错
             StateStackElement last_state  = (StateStackElement)stack_to_parse.Peek();
             Action            last_action = GrammerConfig.analysis_table[last_state.state]["empty"];
             //执行语法动作,应该是一个规约,否则就是已经规约到头err,那就是结束err
             if (last_action.action == "reduce")
             {
                 //规约产生的肯定都是非终结符
                 NonterminalStackElement e = new NonterminalStackElement(-1, last_action.left);
                 int count = last_action.right.Count;
                 for (int i = 0; i < count * 2; i++)
                 {
                     if (i % 2 == 1)
                     {
                         StackElement s = (StackElement)stack_to_parse.Pop();
                         s.layersIncreaseRecursively();
                         e.branches.Insert(0, s);
                     }
                     else
                     {
                         stack_to_parse.Pop();
                     }
                 }
                 StateStackElement first_now = (StateStackElement)(stack_to_parse.Peek());
                 Console.WriteLine("last_action.left:" + last_action.left);
                 Action aa = getActionByTransformedToken(first_now.state, e.type_code, last_action.left);
                 if (aa.action == "shift")
                 {
                     stack_to_parse.Push(e);
                     stack_to_parse.Push(new StateStackElement(aa.new_state));
                 }
                 else if (aa.action == "error")
                 {
                     stack_to_parse.Push(e);
                     stack_to_parse.Push(new StateStackElement(0));
                     break;
                 }
                 else if (aa.action == "acc")
                 {
                     stack_to_parse.Push(e);
                     stack_to_parse.Push(new StateStackElement(0));
                     break;
                 }
                 else
                 {
                     throw new ParserException("规约之后难道不是移进吗");
                 }
             }
             else if (last_action.action == "error")
             {
                 throw new ParserException("程序定义不完整或者出现错误");
             }
             else if (last_action.action == "acc")
             {
                 stack_to_parse.Push(new StateStackElement(0));
                 break;
             }
             else if (last_action.action == "special action")
             {
                 throw new ParserException("程序定义不完整或者出现错误");
             }
             else
             {
                 MessageBox.Show(last_action.action);
                 throw new ParserException("不可能的情况");
             }
         }
         printStack();
         AbstractSyntaxTree ast_window = new AbstractSyntaxTree();
         if (MainWindow.grammer_output)
         {
             ast_window.Show();
         }
         return(true);
     }
     catch (ParserException pe)
     {
         MessageBox.Show(pe.getExceptionMsg());
         return(false);
     }
     catch (Exception ee)
     {
         MessageBox.Show(ee.ToString());
         return(false);
     }
 }
 private void recursiveAddNodes(StackElement e, TreeViewItem newItem)
 {
     try
     {
         if (e.type_code == 6)
         {
             throw new ParserException("这个表示状态的栈元素不应该出现在Tree的递归子结点中!");
         }
         else if (e.type_code == 1)
         {
             IdentifierStackElement ele = (IdentifierStackElement)e;
             newItem.Header = "第" + ele.linenum + "行的标识符:" + ele.content;
         }
         else if (e.type_code == 2)
         {
             IntStackElement ele = (IntStackElement)e;
             newItem.Header = "第" + ele.linenum + "行的整数:" + ele.content;
         }
         else if (e.type_code == 3)
         {
             NonterminalStackElement ele = (NonterminalStackElement)e;
             newItem.Header = "非终结符:" + ele.name;
         }
         else if (e.type_code == 4)
         {
             OtherTerminalStackElement ele = (OtherTerminalStackElement)e;
             newItem.Header = "第" + ele.linenum + "行的终结符:" + ele.content;
         }
         else if (e.type_code == 5)
         {
             RealStackElement ele = (RealStackElement)e;
             newItem.Header = "第" + ele.linenum + "行的实数:" + ele.content;
         }
         else if (e.type_code == 7)
         {
             CharStackElement ele = (CharStackElement)e;
             newItem.Header = "第" + ele.linenum + "行的字符:" + ele.content;
         }
         else if (e.type_code == 8)
         {
             StringStackElement ele = (StringStackElement)e;
             newItem.Header = "第" + ele.linenum + "行的字符串:" + ele.content;
         }
         else
         {
             throw new ParserException("这是啥栈元素?");
         }
         //若是终结符,branches就是空,若不是非终结符,它也终究会走到末端叶子节点,也就是非终结符,然后递归终止
         if (e.branches.Count != 0)
         {
             foreach (StackElement ele in e.branches)
             {
                 TreeViewItem new_node = new TreeViewItem();
                 newItem.Items.Add(new_node);
                 recursiveAddNodes(ele, new_node);
             }
         }
     }
     catch (ParserException pe)
     {
         MessageBox.Show(pe.err_msg);
     }
     catch (Exception ee)
     {
         MessageBox.Show(ee.ToString());
     }
 }
예제 #21
0
        /*
         * 初始化所有变量:规则(未给出初始化值initializer的,也就是只是声明的变量都赋0)
         * declaratee→identifier | identifier[simple_expr]  |  identifier initializer | identifier [simple_expr]  initializer |  identifier[] initializer
         * 接收参数declaratees:初始化数组/单个变量均可
         * 可能出现错误:重复声明,void类型变量错误
         * 声明单个变量:用数组给单个变量赋值,initializer值的类型与声明类型不符合
         * 声明变量数组:用单个变量给数组变量赋值,initializer值的类型与声明类型不符合,initializer值的长度大于声明长度
         * 可能有多个变量一起声明甚至初始化,但是他们类型必须相同(符合C语法)
         */
        private static void initialize_declaratees(string type, List <NonterminalStackElement> declaratees, List <Dictionary <string, Value> > bindings_stack)
        {
            foreach (NonterminalStackElement declaratee in declaratees)
            {
                IdentifierStackElement id_node = (IdentifierStackElement)declaratee.branches[0];
                string new_identifier          = id_node.content;
                int    linenum = id_node.linenum;
                //检查重复声明
                Dictionary <string, Value> bindings = ExecutorTools.findBindings(bindings_stack, new_identifier, true);
                //也就是已经有了同名变量
                if (bindings != null)
                {
                    throw new ExecutorException("重复声明已存在的变量" + new_identifier, id_node.linenum);
                }
                else
                {
                    //那就在最上层准备声明
                    bindings = bindings_stack[bindings_stack.Count - 1];
                    //declaratee→identifier声明变量
                    if (declaratee.branches.Count == 1)
                    {
                        if (type == "int")
                        {
                            bindings.Add(new_identifier, new IntValue("int", false, "0", id_node.linenum));
                        }
                        else if (type == "real")
                        {
                            bindings.Add(new_identifier, new RealValue("real", false, "0.0", id_node.linenum));
                        }
                        else if (type == "char")
                        {
                            bindings.Add(new_identifier, new CharValue("char", false, "", id_node.linenum));
                        }
                        else if (type == "string")
                        {
                            bindings.Add(new_identifier, new StringValue("string", false, "", id_node.linenum));
                        }
                        else
                        {
                            throw new ExecutorException("试图声明一个void类型的变量" + new_identifier, id_node.linenum);
                        }
                    }
                    //declaratee→identifier initializer 声明并初始化变量
                    else if (declaratee.branches.Count == 2)
                    {
                        NonterminalStackElement initializer_node = (NonterminalStackElement)declaratee.branches[1];
                        if (initializer_node.branches.Count != 2)
                        {
                            throw new ExecutorException("试图用数组给单个变量" + new_identifier + "进行初始化", linenum);
                        }
                        //排除后,必然是initializer→=expr
                        NonterminalStackElement expr_node = (NonterminalStackElement)initializer_node.branches[1];
                        Value v = Evaluator.eval_expr(expr_node, mainFrameStack);
                        v = ExecutorTools.adjustType(type, v);
                        bindings.Add(new_identifier, v);
                    }
                    //declaratee→identifier[simple_expr] | identifier[] initializer声明定长数组,初始化auto自适应长度数组
                    else if (declaratee.branches.Count == 4)
                    {
                        StackElement third_child_of_last_declaratee = (StackElement)declaratee.branches[2];

                        //declaratee→identifier[] initializer
                        if (third_child_of_last_declaratee.type_code == 4)
                        {
                            //现在还不知道数组长度,要根据initializer算
                            int array_len;
                            NonterminalStackElement initializer_node = (NonterminalStackElement)declaratee.branches[3];
                            //initializer→ = expr |={ initializer_lst}
                            if (initializer_node.branches.Count != 4)
                            {
                                throw new ExecutorException("试图用单个变量给数组" + new_identifier + "进行初始化", linenum);
                            }
                            //排除后,必然是initializer→={initializer_lst}
                            NonterminalStackElement initializer_lst_node = (NonterminalStackElement)initializer_node.branches[2];
                            //获取initializer数组的长度 intializer_lst→expr | expr,initializer_lst | expr,
                            //获取给出的initializer中的值的集合
                            List <Value> given_values = new List <Value>();
                            while (initializer_lst_node.branches.Count == 3)
                            {
                                Value vv = Evaluator.eval_expr((NonterminalStackElement)initializer_lst_node.branches[0], mainFrameStack);
                                vv = ExecutorTools.adjustType(type, vv);
                                given_values.Add(vv);
                                initializer_lst_node = (NonterminalStackElement)initializer_lst_node.branches[2];
                            }
                            Value v = Evaluator.eval_expr((NonterminalStackElement)initializer_lst_node.branches[0], mainFrameStack);
                            v = ExecutorTools.adjustType(type, v);
                            given_values.Add(v);
                            initializer_lst_node = (NonterminalStackElement)initializer_lst_node.branches[2];
                            //根据给出的值数量,确定我们数组的长度
                            array_len = given_values.Count;
                            if (type == "int")
                            {
                                int[] arrayElements = new int[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    if (given_values[i].type != "int")
                                    {
                                        throw new ExecutorException("用" + given_values[i].type + "类型给" + type + "类型数组变量" + new_identifier + "初始化", linenum);
                                    }
                                    IntValue value = (IntValue)given_values[i];
                                    arrayElements[i] = value.value;
                                }
                                bindings.Add(new_identifier, new IntArrayValue("intArray", false, array_len, arrayElements, linenum));
                            }
                            else if (type == "real")
                            {
                                double[] arrayElements = new double[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    if (given_values[i].type != "real")
                                    {
                                        throw new ExecutorException("用" + given_values[i].type + "类型给" + type + "类型数组变量" + new_identifier + "初始化", linenum);
                                    }
                                    RealValue value = (RealValue)given_values[i];
                                    arrayElements[i] = value.value;
                                }
                                bindings.Add(new_identifier, new RealArrayValue("realArray", false, array_len, arrayElements, linenum));
                            }
                            else if (type == "char")
                            {
                                string[] arrayElements = new string[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    if (given_values[i].type != "char")
                                    {
                                        throw new ExecutorException("用" + given_values[i].type + "类型给" + type + "类型数组变量" + new_identifier + "初始化", linenum);
                                    }
                                    CharValue value = (CharValue)given_values[i];
                                    arrayElements[i] = value.value;
                                }
                                bindings.Add(new_identifier, new CharArrayValue("charArray", false, array_len, arrayElements, linenum));
                            }
                            else if (type == "string")
                            {
                                string[] arrayElements = new string[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    if (given_values[i].type != "string")
                                    {
                                        throw new ExecutorException("用" + given_values[i].type + "类型给" + type + "类型数组变量" + new_identifier + "初始化", linenum);
                                    }
                                    StringValue value = (StringValue)given_values[i];
                                    arrayElements[i] = value.value;
                                }
                                bindings.Add(new_identifier, new StringArrayValue("stringArray", false, array_len, arrayElements, linenum));
                            }
                            else
                            {
                                throw new ExecutorException("试图声明一个void类型的变量数组" + new_identifier, linenum);
                            }
                        }
                        //declaratee→identifier[simple_expr]
                        else
                        {
                            NonterminalStackElement simple_expr_node = (NonterminalStackElement)declaratee.branches[2];
                            int array_len = ExecutorTools.get_array_len_from_simple_expr(simple_expr_node, mainFrameStack);
                            if (type == "int")
                            {
                                int[] arrayElements = new int[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    arrayElements[i] = 0;
                                }
                                bindings.Add(new_identifier, new IntArrayValue("intArray", false, array_len, arrayElements, linenum));
                            }
                            else if (type == "real")
                            {
                                double[] arrayElements = new double[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    arrayElements[i] = 0.0;
                                }
                                bindings.Add(new_identifier, new RealArrayValue("realArray", false, array_len, arrayElements, linenum));
                            }
                            else if (type == "char")
                            {
                                string[] arrayElements = new string[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    arrayElements[i] = "\0";
                                }
                                bindings.Add(new_identifier, new CharArrayValue("charArray", false, array_len, arrayElements, linenum));
                            }
                            else if (type == "string")
                            {
                                string[] arrayElements = new string[array_len];
                                for (int i = 0; i < array_len; i++)
                                {
                                    arrayElements[i] = "";
                                }
                                bindings.Add(new_identifier, new StringArrayValue("stringArray", false, array_len, arrayElements, linenum));
                            }
                            else
                            {
                                throw new ExecutorException("试图声明一个void类型的变量数组" + new_identifier, linenum);
                            }
                        }
                    }
                    //declaratee→identifier [simple_expr]  initializer
                    else if (declaratee.branches.Count == 5)
                    {
                        NonterminalStackElement simple_expr_node = (NonterminalStackElement)declaratee.branches[2];
                        //数组声明的长度
                        int array_len = ExecutorTools.get_array_len_from_simple_expr(simple_expr_node, mainFrameStack);
                        //现在还不知道被赋值的数组长度,要根据initializer算
                        NonterminalStackElement initializer_node = (NonterminalStackElement)declaratee.branches[4];
                        //initializer→ = expr | ={ initializer_lst}
                        if (initializer_node.branches.Count != 4)
                        {
                            throw new ExecutorException("试图用单个变量给数组" + new_identifier + "进行初始化", linenum);
                        }
                        //排除后,必然是initializer→={initializer_lst}
                        NonterminalStackElement initializer_lst_node = (NonterminalStackElement)initializer_node.branches[2];
                        //获取initializer数组的长度 intializer_lst→expr | expr,initializer_lst | expr,
                        //获取给出的initializer中的值的集合
                        List <Value> given_values = new List <Value>();
                        while (initializer_lst_node.branches.Count == 3)
                        {
                            Value vv = Evaluator.eval_expr((NonterminalStackElement)initializer_lst_node.branches[0], mainFrameStack);
                            vv = ExecutorTools.adjustType(type, vv);
                            given_values.Add(vv);
                            initializer_lst_node = (NonterminalStackElement)initializer_lst_node.branches[2];
                        }
                        Value v = Evaluator.eval_expr((NonterminalStackElement)initializer_lst_node.branches[0], mainFrameStack);
                        v = ExecutorTools.adjustType(type, v);
                        given_values.Add(v);
                        //赋值
                        if (given_values.Count > array_len)
                        {
                            throw new ExecutorException("数组" + new_identifier + "的初始值设定项长度" + given_values.Count + "大于声明的长度" + array_len, linenum);
                        }
                        if (type == "int")
                        {
                            int[] arrayElements = new int[array_len];
                            for (int i = 0; i < array_len; i++)
                            {
                                if (i < given_values.Count)
                                {
                                    IntValue intv = (IntValue)given_values[i];
                                    arrayElements[i] = intv.value;
                                }
                                else
                                {
                                    arrayElements[i] = 0;
                                }
                            }
                            bindings.Add(new_identifier, new IntArrayValue("intArray", false, array_len, arrayElements, linenum));
                        }
                        else if (type == "real")
                        {
                            double[] arrayElements = new double[array_len];
                            for (int i = 0; i < array_len; i++)
                            {
                                if (i < given_values.Count)
                                {
                                    RealValue intv = (RealValue)given_values[i];
                                    arrayElements[i] = intv.value;
                                }
                                else
                                {
                                    arrayElements[i] = 0.0;
                                }
                            }
                            bindings.Add(new_identifier, new RealArrayValue("realArray", false, array_len, arrayElements, linenum));
                        }
                        else if (type == "char")
                        {
                            string[] arrayElements = new string[array_len];
                            for (int i = 0; i < array_len; i++)
                            {
                                if (i < given_values.Count)
                                {
                                    CharValue intv = (CharValue)given_values[i];
                                    arrayElements[i] = intv.value;
                                }
                                else
                                {
                                    arrayElements[i] = "\0";
                                }
                            }
                            bindings.Add(new_identifier, new CharArrayValue("charArray", false, array_len, arrayElements, linenum));
                        }
                        else if (type == "string")
                        {
                            string[] arrayElements = new string[array_len];
                            for (int i = 0; i < array_len; i++)
                            {
                                if (i < given_values.Count)
                                {
                                    StringValue intv = (StringValue)given_values[i];
                                    arrayElements[i] = intv.value;
                                }
                                else
                                {
                                    arrayElements[i] = "";
                                }
                            }
                            bindings.Add(new_identifier, new StringArrayValue("stringArray", false, array_len, arrayElements, linenum));
                        }
                        else
                        {
                            throw new ExecutorException("试图声明一个void类型的变量数组" + new_identifier, linenum);
                        }
                    }
                    else
                    {
                        throw new ExecutorException("initialize_declaratee_withzero出现不正常的错误,可能是语法树解析declaratee出现问题");
                    }
                }
            }
        }