Ejemplo n.º 1
0
        /*
         * 初始化所有变量:规则(未给出初始化值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出现问题");
                    }
                }
            }
        }
Ejemplo n.º 2
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);
     }
 }
Ejemplo n.º 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);
     }
 }