예제 #1
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应该只有这些");
            }
        }