private static void executeMain() { if (globalSymbolTable.Keys.Contains("main")) { if (globalSymbolTable["main"].type == "func") { int return_val = 0; FuncValue main_func = ((FuncValue)globalSymbolTable["main"]); ExecutorTools.executeFunction(main_func, new List <Value>(), main_func.line_num); } } else { throw new ExecutorException("不存在main函数,无法执行!"); } }
//当该节点为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); } }
//这里情况就不同了,上面是对应着+-*/四则运算的,所以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); } }
//执行函数(传入参数,返回类型等等) //注意创建一个新的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; } } } }