//falsey的几种情况,根据C语言测试: \0的char类型,0的int/real,然后我再加一条string为""时,数组均返回true public bool getBoolean() { if (type == "char") { CharValue v = (CharValue)this; return(v.value != "\0"); } else if (type == "string") { StringValue v = (StringValue)this; return(v.value != ""); } else if (type == "int") { IntValue v = (IntValue)this; return(v.value != 0); } else if (type == "real") { RealValue v = (RealValue)this; return(v.value != 0); } else if (type.Contains("Array")) { return(true); } else if (type == "func") { throw new ExecutorException("类型错误,出现了错误的类型:函数", line_num); } else if (type == "bool") { BoolValue v = (BoolValue)this; return(v.value); } else { throw new ExecutorException("文法发生了变化", line_num); } }
//这里情况就不同了,上面是对应着+-*/四则运算的,所以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); } }
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); } }
/* * 初始化所有变量:规则(未给出初始化值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出现问题"); } } } }
//因为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); } }