//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); } }
//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); } }
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); } }