internal static void write_value(Value v, int linenum) { if (v.type == "int") { IntValue value = (IntValue)v; MessageBox.Show(value.value.ToString()); } else if (v.type == "real") { RealValue value = (RealValue)v; MessageBox.Show(value.value.ToString()); } else if (v.type == "number") { NumberValue value = (NumberValue)v; MessageBox.Show(value.value.ToString()); } else if (v.type == "char") { CharValue value = (CharValue)v; MessageBox.Show(value.value); } else if (v.type == "string") { StringValue value = (StringValue)v; MessageBox.Show(value.value); } else if (v.type == "bool") { BoolValue value = (BoolValue)v; MessageBox.Show(value.value.ToString()); } else if (v.type == "intArray") { IntArrayValue value = (IntArrayValue)v; string text = ""; for (int i = 0; i < value.array_elements.Length; i++) { text += value.array_elements[i]; text += "|"; } MessageBox.Show(text); } else if (v.type == "realArray") { RealArrayValue value = (RealArrayValue)v; string text = ""; for (int i = 0; i < value.array_elements.Length; i++) { text += value.array_elements[i]; text += "|"; } MessageBox.Show(text); } else if (v.type == "charArray") { CharArrayValue value = (CharArrayValue)v; string text = ""; for (int i = 0; i < value.array_elements.Length; i++) { text += value.array_elements[i]; text += "|"; } MessageBox.Show(text); } else if (v.type == "stringArray") { StringArrayValue value = (StringArrayValue)v; string text = ""; for (int i = 0; i < value.array_elements.Length; i++) { text += value.array_elements[i]; text += "|"; } MessageBox.Show(text); } else { throw new ExecutorException("出现了没有考虑到的新类型", linenum); } }
//这里情况就不同了,上面是对应着+-*/四则运算的,所以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); } }
//因为3>2>0这里3>2会evaluate成1 public IntValue compareWith(Value v, string op = "") { //直接比较是否相等 if (op == "") { if (this.type != v.type) { if (type == "int" && v.type == "number") { IntValue v1 = (IntValue)this; NumberValue v2 = (NumberValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "real" && v.type == "number") { RealValue v1 = (RealValue)this; NumberValue v2 = (NumberValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "number" && v.type == "int") { NumberValue v1 = (NumberValue)this; IntValue v2 = (IntValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "number" && v.type == "real") { NumberValue v1 = (NumberValue)this; RealValue v2 = (RealValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "int" && v.type == "real") { IntValue v1 = (IntValue)this; RealValue v2 = (RealValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "real" && v.type == "int") { RealValue v1 = (RealValue)this; IntValue v2 = (IntValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else { //类型不同比较直接不同 return(new IntValue("int", true, "0", line_num)); } } else { if (type == "int") { IntValue v1 = (IntValue)this; IntValue v2 = (IntValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "real") { RealValue v1 = (RealValue)this; RealValue v2 = (RealValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "char") { CharValue v1 = (CharValue)this; CharValue v2 = (CharValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "string") { StringValue v1 = (StringValue)this; StringValue v2 = (StringValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else if (type == "bool") { BoolValue v1 = (BoolValue)this; BoolValue v2 = (BoolValue)v; if (v1.value == v2.value) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else { throw new ExecutorException("暂不实现数组类型比较", line_num); } } } //若是大小比较,那么就只有real/int这些number可以compare,其他的不能 else if (computable_types.Contains(v.type) && computable_types.Contains(type)) { double v1 = 0, v2 = 0; bool result; if (type == "int") { v1 = ((IntValue)this).value; } else if (type == "real") { v1 = ((RealValue)this).value; } else { v1 = ((NumberValue)this).value; } if (v.type == "int") { v2 = ((IntValue)v).value; } else if (v.type == "real") { v2 = ((RealValue)v).value; } else { v2 = ((NumberValue)v).value; } if (op == ">") { result = v1 > v2; } else if (op == "<") { result = v1 < v2; } else if (op == ">=") { result = v1 >= v2; } else if (op == "<=") { result = v1 <= v2; } else { throw new ExecutorException("出现了文法中未定义的判断符" + op, line_num); } if (result) { return(new IntValue("int", true, "1", line_num)); } else { return(new IntValue("int", true, "0", line_num)); } } else { throw new ExecutorException("无法直接比较大小的类型", line_num); } }