/* * 初始化所有变量:规则(未给出初始化值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出现问题"); } } } }
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); } }
//因为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); } }