//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); } } }
/* 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); }
//执行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); }
//自顶向下,深度优先遍历语法树(与生成树顺序一致) 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); } } } }
//当该节点为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应该有且只有三个子结点"); } }
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; }
/* 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)); } }
//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); } }
//当该节点为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); } }
//传入代表数组长度的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); }
//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; } } }
/* 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); }
//执行某个具体的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应该只有这些"); } }
//执行函数(传入参数,返回类型等等) //注意创建一个新的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; } } } }
//这里情况就不同了,上面是对应着+-*/四则运算的,所以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); } }
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); }
//执行五种语法动作之一 语法动作 - 目前的第一个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"); } }
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()); } }
/* * 初始化所有变量:规则(未给出初始化值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出现问题"); } } } }