Ejemplo n.º 1
0
        private Data getSentenceRes(List <Element> toks)
        {
            Data         result    = new Data(0);
            Stack <Data> datastack = new Stack <Data>();

            foreach (Element e in toks)
            {
                switch (e.flag)
                {
                case Element.Function: {
                    FunctionElement ele = e as FunctionElement;
                    Function        fun = null;
                    try {
                        fun = CompilerCore.functionlist[e.value];
                    } catch (KeyNotFoundException) {
                        try {
                            fun = CompilerCore.systemaip[e.value];
                        } catch (KeyNotFoundException) {
                            throw new SyntaxErrorException("语法错误,不存在的函数");
                        }
                    } finally {
                        Data r = null;
                        if (fun != null)
                        {
                            List <Data> paras = new List <Data>();
                            for (int i = 0; i < fun.parametername.Count; i++)
                            {
                                Data val = getSentenceRes(ele.paras[i]);
                                paras.Add(val);
                            }
                            fun.parametervalue = paras;
                            r = fun.run();
                        }
                        if (r != null && !r.isEmpty())
                        {
                            datastack.Push(r);
                        }
                    }
                    break;
                }

                case Element.Symbol: {
                    Data dat1 = null;
                    Data dat2 = datastack.Pop();
                    Data res  = null;
                    if (e.value != "!")
                    {
                        dat1 = datastack.Pop();
                    }
                    switch (e.value)
                    {
                    case "^": {
                        //乘方运算,a^b即为a的b次方
                        if (dat1.isStr || dat2.isStr)
                        {
                            throw new SyntaxErrorException("错误:只能进行两数运算");
                        }
                        res = new Data(Math.Pow(dat1.num, dat2.num));
                        break;
                    }

                    case "*": {
                        if (dat1.isStr || dat2.isStr)
                        {
                            throw new SyntaxErrorException("错误:只能进行两数运算");
                        }
                        res = new Data(dat1.num * dat2.num);
                        break;
                    }

                    case "/": {
                        if (dat1.isStr || dat2.isStr)
                        {
                            throw new SyntaxErrorException("错误:只能进行两数运算");
                        }
                        res = new Data(dat1.num / dat2.num);
                        break;
                    }

                    case "%": {
                        if (dat1.isStr || dat2.isStr)
                        {
                            throw new SyntaxErrorException("错误:只能进行两数运算");
                        }
                        res = new Data(dat1.num % dat2.num);
                        break;
                    }

                    case "+": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            res = new Data(dat1.str + dat2.str);
                        }
                        else if (dat1.isStr && !dat2.isStr)
                        {
                            res = new Data(dat1.str + dat2.num);
                        }
                        else if (!dat1.isStr && dat2.isStr)
                        {
                            res = new Data(dat1.num + dat2.str);
                        }
                        else
                        {
                            res = new Data(dat1.num + dat2.num);
                        }
                        break;
                    }

                    /* 减法运算
                     * 1.数字(a)-数字(b)=数字(a-b)
                     * 2.字符串(a)-数字(n)=去掉末尾n位后的字符串a
                     * 3.数字(n)-字符串(a)=去掉开头n位后的字符串a
                     * 4.字符串(a)-字符串(b)=去掉字符串a中的出现的字符串b
                     */
                    case "-": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            res = new Data(dat1.str.Replace(dat2.str, ""));
                        }
                        else if (!dat1.isStr && !dat2.isStr)
                        {
                            res = new Data(dat1.num - dat2.num);
                        }
                        else if (!dat1.isStr && dat2.isStr)
                        {
                            res = new Data(dat2.str.Substring(0, (int)dat1.num));
                        }
                        else
                        {
                            res = new Data(dat1.str.Substring(dat1.str.Length - (int)dat2.num));
                        }
                        break;
                    }

                    /* 大于和小于运算
                     * 数字a>b为真,则运算符的值为1,反之为0
                     * 字符串则是循环比较每一个字符,对字符比较谁的编码值更大
                     */
                    case ">": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            res = Data.comparestr(dat1.str, dat2.str, 1);
                        }
                        else if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num > dat2.num)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            throw new SyntaxErrorException("语法错误");
                        }
                        break;
                    }

                    case "<": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            res = Data.comparestr(dat1.str, dat2.str, 2);
                        }
                        else if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num < dat2.num)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            throw new SyntaxErrorException("语法错误,该运算符不支持字符串和数字直接运算");
                        }
                        break;
                    }

                    case ">=": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            res = Data.comparestr(dat1.str, dat2.str, 3);
                        }
                        else if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num >= dat2.num)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            throw new SyntaxErrorException("语法错误");
                        }
                        break;
                    }

                    case "<=": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            res = Data.comparestr(dat1.str, dat2.str, 4);
                        }
                        else if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num <= dat2.num)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            throw new SyntaxErrorException("语法错误");
                        }
                        break;
                    }

                    case "&": {
                        if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num != 0 && dat2.num != 0)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            throw new SyntaxErrorException("语法错误");
                        }
                        break;
                    }

                    case "|": {
                        if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num == 0 && dat2.num == 0)
                            {
                                res = new Data(0);
                            }
                            else
                            {
                                res = new Data(1);
                            }
                        }
                        else
                        {
                            throw new SyntaxErrorException("语法错误");
                        }
                        break;
                    }

                    case "!": {
                        if (!dat2.isStr)
                        {
                            if (dat2.num == 0)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            throw new SyntaxErrorException("语法错误");
                        }
                        break;
                    }

                    case "==": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            if (dat1.str == dat2.str)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num == dat2.num)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else if (!dat1.isStr && dat2.isStr)
                        {
                            if (dat1.num == Convert.ToDouble(dat2.str))
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            if (dat2.num == Convert.ToDouble(dat1.str))
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        break;
                    }

                    case "!=": {
                        if (dat1.isStr && dat2.isStr)
                        {
                            if (dat1.str != dat2.str)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else if (!dat1.isStr && !dat2.isStr)
                        {
                            if (dat1.num != dat2.num)
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else if (!dat1.isStr && dat2.isStr)
                        {
                            if (dat1.num != Convert.ToDouble(dat2.str))
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        else
                        {
                            if (dat2.num != Convert.ToDouble(dat1.str))
                            {
                                res = new Data(1);
                            }
                            else
                            {
                                res = new Data(0);
                            }
                        }
                        break;
                    }

                    case "=": {
                        dat2.variablename = dat1.variablename;
                        this.variables[dat1.variablename] = dat2;
                        res = dat2;
                        break;
                    }

                    default: {
                        throw new SyntaxErrorException("无法识别的符号");
                    }
                    }
                    datastack.Push(res);
                    break;
                }

                case Element.Variable: {
                    Data dat = null;
                    try {
                        dat = variables[e.value];
                    } catch (KeyNotFoundException) {
                        dat = new Data(0);
                        dat.variablename = e.value;
                        variables.Add(e.value, dat);
                    } finally {
                        datastack.Push(dat);
                    }
                    break;
                }

                case Element.Number: {
                    datastack.Push(new Data(Convert.ToDouble(e.value)));
                    break;
                }

                case Element.String: {
                    datastack.Push(new Data(EscapeChar(e.value.Trim('\"'))));
                    break;
                }

                default: {
                    break;
                }
                }
            }
            if (datastack.Count > 0)
            {
                result = datastack.Pop();
            }
            return(result);
        }
Ejemplo n.º 2
0
        private List <Element> construct(string code)
        {
            List <string> toks = CompilerCore.AdcancedSplit(code.Trim(' ', '\t', '\r'));
            //整理代码,中缀运算符改后缀
            List <Element> restok   = new List <Element>();
            Stack <string> elestack = new Stack <string>();

            foreach (string data in toks)
            {
                if (data.Length == 0)
                {
                    continue;
                }
                Element tmpEle;
                if (data.Contains("(") && data.Contains(")"))  //是函数
                {
                    tmpEle = new FunctionElement(data, Element.Function);
                    restok.Add(tmpEle);
                }
                else if (data.Contains("[") && data.Contains("]"))    //是数组
                {
                    tmpEle = new Element(data, Element.Array);
                    restok.Add(tmpEle);
                }
                else if (data[0] >= '0' && data[0] <= '9')    //是数字
                {
                    tmpEle = new Element(data, Element.Number);
                    restok.Add(tmpEle);
                }
                else if (data[0] >= 'a' && data[0] <= 'z' || data[0] >= 'A' && data[0] <= 'Z')    //是一个变量
                {
                    tmpEle = new Element(data, Element.Variable);
                    restok.Add(tmpEle);
                }
                else if (data[0] == '"')    //是字符串
                {
                    tmpEle = new Element(data, Element.String);
                    restok.Add(tmpEle);
                }
                else    //是符号
                {
                    if (elestack.Count == 0 || data == "(")
                    {
                        elestack.Push(data);
                    }
                    else
                    {
                        if (data == ")")
                        {
                            while (elestack.Peek() != "(" && elestack.Count > 0)
                            {
                                restok.Add(new Element(elestack.Pop(), Element.Symbol));
                            }
                            if (elestack.Count == 0)
                            {
                                throw new SyntaxErrorException("syntax error,the number of '(' and ')' don't match!");
                            }
                            elestack.Pop();
                        }
                        else
                        {
                            if (CompilerCore.operator_priority[data] >= CompilerCore.operator_priority[elestack.Peek()])
                            {
                                elestack.Push(data);
                            }
                            else
                            {
                                if (elestack.Peek() == "(")
                                {
                                    elestack.Push(data);
                                }
                                else
                                {
                                    while (CompilerCore.operator_priority[data] < CompilerCore.operator_priority[elestack.Peek()] && elestack.Count > 0)
                                    {
                                        if (elestack.Peek() == "(")
                                        {
                                            elestack.Pop();
                                            break;
                                        }
                                        restok.Add(new Element(elestack.Pop(), Element.Symbol));
                                    }
                                    elestack.Push(data);
                                }
                            }
                        }
                    }
                }
            }
            //将栈中的剩余运算符按序插入到表达式后面
            while (elestack.Count > 0)
            {
                if (elestack.Peek() == "(")
                {
                    elestack.Pop();
                    continue;
                }
                restok.Add(new Element(elestack.Pop(), Element.Symbol));
            }
            return(restok);
        }