//执行某个具体的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应该只有这些"); } }