예제 #1
0
 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);
     }
 }
예제 #2
0
        //这里情况就不同了,上面是对应着+-*/四则运算的,所以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
0
 //因为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);
     }
 }