コード例 #1
0
        /// <summary>
        ///  Make token list and translate list tokens to Reverse Polish Notation
        /// </summary>
        /// <returns></returns>
        public string Prepare()
        {
            int x = 0;
            Stack <RPNToken> stack   = new Stack <RPNToken>();
            Stack <RPNToken> postfix = new Stack <RPNToken>();
            string           RetVal  = string.Empty;

            RPNToken     sItem;
            RPNToken     tok;
            RPNTokenType types;

            RPNUtils.GetTokens(m_expr, Tokens);

            while (x < Tokens.Count)
            {
                tok   = Tokens[x];
                types = tok.sType;

                if (types == RPNTokenType.ALPHA)
                {
                    if (!Arguments.Contains(tok.sToken))
                    {
                        Arguments.Add(tok.sToken);
                    }
                }

                //Check for numbers
                if (types == RPNTokenType.NONE ||
                    types == RPNTokenType.NUMBER ||
                    types == RPNTokenType.ALPHA ||
                    types == RPNTokenType.BOOL ||
                    types == RPNTokenType.STRING)
                {
                    //Push number onto postfix stack.
                    postfix.Push(tok);
                }
                else
                {
                    //Check for LPARM
                    if (tok.sToken[0] == '(')
                    {
                        //Push ( onto stack.
                        stack.Push(tok);
                    }
                    //Check for closing param
                    else if (tok.sToken[0] == ')')
                    {
                        sItem = stack.Pop();
                        while (sItem.sToken[0] != '(')
                        {
                            //Post item of stack onto postfix stack.
                            postfix.Push(sItem);
                            sItem = stack.Pop();
                        }
                    }
                    else
                    {
                        //While the stack is not empty pop of rest of items.
                        while (stack.Count > 0)
                        {
                            //Get top item
                            sItem = stack.Pop();
                            //Check order of operators.
                            if (precedence(sItem) >= precedence(tok))
                            {
                                //Push operator on stack
                                postfix.Push(sItem);
                            }
                            else
                            {
                                //Push back onto stack.
                                stack.Push(sItem);
                                break;
                            }
                        }
                        //Push current token.
                        stack.Push(tok);
                    }
                }
                //INC Counter
                x++;
            }

            //Pop off remaining on the stack.
            while (stack.Count > 0)
            {
                //Add to postfix.
                postfix.Push(stack.Pop());
            }

            //Convert stack to string array.
            execTokens = postfix.Reverse().ToList();

            for (x = 0; x < execTokens.Count; x++)
            {
                //Append string to RetVal
                RetVal += execTokens[x].sToken + " ";
            }
            //Return RPN string
            return(RetVal.Trim());
        }
コード例 #2
0
ファイル: RPNUtils.cs プロジェクト: Vladimir-Novick/RPNLib
        public static bool GetTokens(string expr, List <RPNToken> Tokens)
        {
            int      i   = 0;
            string   tok = string.Empty;
            RPNToken token;

            bool IsGood = true;

            Tokens.Clear();

            while (i <= expr.Length)
            {
                tok   = string.Empty;
                token = new RPNToken();

                if (i > expr.Length - 1)
                {
                    break;
                }

                if (RPNUtils.IsWhiteSpace(expr[i]))
                {
                    while (RPNUtils.IsWhiteSpace(expr[i]))
                    {
                        i++;
                        if (i > expr.Length - 1)
                        {
                            break;
                        }
                    }
                }

                if (i > expr.Length - 1)
                {
                    break;
                }

                if (expr[i] == '\'')
                {
                    do
                    {
                        tok += expr[i];
                        i++;
                        if (i > expr.Length - 1)
                        {
                            throw new Exception($"Invalid string [{tok}] , Expression [{expr}]");
                        }
                    } while (!(expr[i] == '\''));

                    if (i <= expr.Length - 1)
                    {
                        tok += expr[i];
                        i++;
                    }
                    else
                    {
                        throw new Exception($"Invalid string [{tok}] , Expression [{expr}]");
                    }

                    token.sType  = RPNTokenType.STRING;
                    token.sToken = tok;
                    Tokens.Add(token);
                }

                if (i > expr.Length - 1)
                {
                    break;
                }

                if (expr[i] == '[')
                {
                    while (!(expr[i] == ']'))
                    {
                        tok += expr[i];
                        i++;
                        if (i > expr.Length - 1)
                        {
                            break;
                        }
                    }
                    if (i <= expr.Length - 1)
                    {
                        {
                            tok += expr[i];
                            i++;
                        }
                    }
                    else
                    {
                        throw new Exception($"Invalid string [{tok}] , Expression [{expr}]");
                    }
                    token.sType  = RPNTokenType.ALPHA;
                    token.sToken = tok;
                    Tokens.Add(token);
                }

                if (i > expr.Length - 1)
                {
                    break;
                }

                if (expr[i] == '"')
                {
                    while (!(expr[i] == '"'))
                    {
                        tok += expr[i];
                        i++;
                        if (i > expr.Length - 1)
                        {
                            throw new Exception($"Invalid string [{tok}] , Expression [{expr}]");
                        }
                    }
                    if (i <= expr.Length - 1)
                    {
                        {
                            tok += expr[i];
                            i++;
                        }
                    }
                    else
                    {
                        throw new Exception($"Invalid string [{tok}] , Expression [{expr}]");
                    }
                    token.sType  = RPNTokenType.STRING;
                    token.sToken = tok;
                    Tokens.Add(token);
                }

                if (i > expr.Length - 1)
                {
                    break;
                }

                if (char.IsLetter(expr[i]) || (expr[i] == ':'))
                {
                    do
                    {
                        tok += expr[i];
                        i++;

                        if (i > expr.Length - 1)
                        {
                            break;
                        }
                    } while (char.IsLetter(expr[i]) || (char.IsDigit(expr[i]) || (expr[i] == '_')));
                    token.sType = RPNTokenType.ALPHA;
                    var t = tok.ToLower();
                    if (t.Equals("true") || t.Equals("false"))
                    {
                        token.sType = RPNTokenType.BOOL;
                        tok         = t;
                    }
                    else
                    {
                        if (i < expr.Length)
                        {
                            if (expr[i] == '(')
                            {
                                tok += "$";

                                token.sType = RPNTokenType.FUNCTION;
                            }
                            if (expr[i] == '$')
                            {
                                tok += "$";
                                i++;

                                token.sType = RPNTokenType.FUNCTION;
                            }
                        }
                    }
                    token.sToken = tok;
                    Tokens.Add(token);
                }
                else if (char.IsDigit(expr[i]))
                {
                    while (char.IsDigit(expr[i]) || (expr[i] == '.'))
                    {
                        tok += expr[i];
                        i++;
                        if (i > expr.Length - 1)
                        {
                            break;
                        }
                    }
                    token.sType  = RPNTokenType.NUMBER;
                    token.sToken = tok;
                    Tokens.Add(token);
                }
                else
                if ((i + 1 < expr.Length) && ((isDoubleOperation(expr[i].ToString() + expr[i + 1]))))
                {
                    tok = expr[i].ToString();
                    tok = tok + expr[i + 1];
                    i++;
                    token.sType       = RPNTokenType.OPERAND;
                    token.sToken      = tok;
                    token.OperandType = RPNOperandType.ARIFMETICAL;
                    OperationConvertor.GetOperation.TryGetValue(tok, out token.Operation);
                    Tokens.Add(token);
                    i++;

                    if (i > expr.Length - 1)
                    {
                        break;
                    }
                }
                else
                if (isOperation(expr[i]))
                {
                    tok          = expr[i].ToString();
                    token.sType  = RPNTokenType.OPERAND;
                    token.sToken = tok;

                    token.OperandType = RPNOperandType.ARIFMETICAL;
                    OperationConvertor.GetOperation.TryGetValue(tok, out token.Operation);

                    if (token.Operation == RPNOperandType.MINUS)
                    {
                        if (Tokens.Count == 0)
                        {
                            token.Operation = RPNOperandType.JUSTMINUS;
                            token.sToken    = tok = "~";
                        }
                        else
                        if (Tokens.Count > 0 && ((Tokens[Tokens.Count - 1].sType == RPNTokenType.OPERAND)))
                        {
                            if (Tokens[Tokens.Count - 1].Operation != RPNOperandType.END_PARENTHESES)
                            {
                                token.Operation = RPNOperandType.JUSTMINUS;
                                token.sToken    = tok = "~";
                            }
                        }
                    }
                    if (token.Operation == RPNOperandType.PLUS)
                    {
                        if (Tokens.Count > 0 && Tokens[Tokens.Count - 1].sType == RPNTokenType.OPERAND)
                        {
                            if (Tokens[Tokens.Count - 1].Operation != RPNOperandType.END_PARENTHESES)
                            {
                                token.Operation = RPNOperandType.JUSTPLUS;
                            }
                        }
                    }
                    Tokens.Add(token);
                    i++;
                    if (i > expr.Length - 1)
                    {
                        break;
                    }
                }
                else
                {
                    IsGood = false;
                    Tokens.Clear();
                    if (i < expr.Length)
                    {
                        throw new Exception($"Invalid token type [{expr[i]}] Expression [{expr}]");
                    }
                    else
                    {
                        throw new Exception($"Invalid Expression [{expr}]");
                    }
                }
            }
            return(IsGood);
        }
コード例 #3
0
        public object Exec()
        {
            double tempDouble;
            object ret = "";
            int    i   = 0;
            double a   = 0;
            double b   = 0;
            bool   a1  = true;
            bool   b1  = true;
            string tok = string.Empty;

            //Go though the tokens
            al = new Stack <object>();
            int x = 0;

            while (i < Tokens.Count)
            {
                tok = Tokens[i].sToken;

                switch (Tokens[i].sType)
                {
                case RPNTokenType.NONE:
                    break;

                case RPNTokenType.BOOL:
                    if (tok.ToLower().Equals("true"))
                    {
                        al.Push(true);
                        break;
                    }
                    else
                    {
                        al.Push(false);
                        break;
                    }
                    break;

                case RPNTokenType.ALPHA:
                    if (vars.TryGetValue(tok, out RPNArguments arg))
                    {
                        a = arg.value;
                        al.Push(a);
                    }
                    else
                    {
                        throw new Exception($"Value [{tok}] not exists");
                    }
                    break;

                case RPNTokenType.NUMBER:
                    tempDouble = 0;
                    RPNUtils.TryToDouble(tok, out tempDouble);
                    al.Push(tempDouble);
                    break;

                case RPNTokenType.STRING:
                    al.Push(tok.Substring(1, tok.Length - 2));
                    break;

                case RPNTokenType.FUNCTION:

                    if (Environment != null)
                    {
#if DEBUG
                        String argumentList = "";
#endif

                        String funcName = Tokens[i].sToken;
                        funcName = funcName.Substring(0, funcName.Length - 1);


                        var func = Environment.FindFunction(funcName);
                        if (func != null)
                        {
                            FunctionAttribute funcAttrib = (FunctionAttribute)Attribute.GetCustomAttribute(func.GetType(), typeof(FunctionAttribute));
                            List <object>     arguments  = new List <object>();



                            if (funcAttrib.ParamTypes != null && funcAttrib.ParamTypes.Length > 0)
                            {
                                foreach (var paramType in funcAttrib.ParamTypes)
                                {
                                    object obj = al.Pop();
                                    func.Params.Add(obj);
#if DEBUG
                                    argumentList += " ";
                                    argumentList += obj.ToString();
#endif
                                }
                            }

                            object retObject = func.Calc();

                            al.Push(retObject);
#if DEBUG
                            Console.WriteLine($"Function , {funcName}({argumentList})  = {retObject.ToString()}");
#endif

                            //   al.Push(r);
                        }
                    }
                    break;

                case RPNTokenType.OPERAND:
                    object r = 0;

                    switch (Tokens[i].Operation)
                    {
                    case RPNOperandType.JUSTPLUS:
                        a = Convert.ToDouble(al.Pop());
                        r = +a;
#if DEBUG
                        Console.WriteLine($"JustPlus , {r}  = {a.ToString()}");
#endif

                        break;

                    case RPNOperandType.PLUS:
                        a = Convert.ToDouble(al.Pop());
                        var b11 = al.Pop();
                        if (b11 is DateTime)
                        {
                            DateTime dDateTime = (DateTime)b11;
                            r = dDateTime.AddHours(a);
                        }
                        else
                        {
                            b = Convert.ToDouble(b11);
                            r = a + b;
                        }

#if DEBUG
                        Console.WriteLine($"{b.ToString()} + {a.ToString()} = {r.ToString()}");
#endif
                        break;

                    case RPNOperandType.JUSTMINUS:
                        a = Convert.ToDouble(al.Pop());
                        r = -a;
                        break;

                    case RPNOperandType.MINUS:
                        var t = al.Pop();
                        a = Convert.ToDouble(t);
                        var b12 = al.Pop();
                        if (b12 is DateTime)
                        {
                            DateTime dDateTime = (DateTime)b12;
                            r = dDateTime.AddHours(-a);
                        }
                        else
                        {
                            b = Convert.ToDouble(b12);
                            r = b - a;
                        }
#if DEBUG
                        Console.WriteLine($"{b} - {a} = {r}");
#endif

                        break;

                    case RPNOperandType.MULITIPLY:
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = a * b;
#if DEBUG
                        Console.WriteLine($"{b} * {a} = {r}");
#endif

                        break;

                    case RPNOperandType.DIVIDE:
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b / a);

#if DEBUG
                        Console.WriteLine($"{b} / {a} = {r}");
#endif
                        break;

                    case RPNOperandType.EXPONENTIATION:
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = Math.Pow(b, a);
#if DEBUG
                        Console.WriteLine($"{b} ^ {a} = {r}");
#endif
                        break;

                    case RPNOperandType.DIV:          // "/="
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b / a);
#if DEBUG
                        Console.WriteLine($"{b} /= {a} = {r}");
#endif
                        break;

                    case RPNOperandType.MOD:          //"%=",
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b %= a);
#if DEBUG
                        Console.WriteLine($"{b} %= {a} = {r}");
#endif
                        break;

                    case RPNOperandType.LESS:          //"<",
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b < a);
#if DEBUG
                        Console.WriteLine($"{b} < {a} = {r}");
#endif
                        break;

                    case RPNOperandType.GREATER:          //">",
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b > a);
#if DEBUG
                        Console.WriteLine($"{b} > {a} = {r}");
#endif
                        break;

                    case RPNOperandType.LESSOREQUAL:          //"<=",
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b <= a);
#if DEBUG
                        Console.WriteLine($"{b} <= {a} = {r}");
#endif
                        break;

                    case RPNOperandType.GREATEOREQUAL:          //">=",
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b >= a);
#if DEBUG
                        Console.WriteLine($"{b} >={a} = {r}");
#endif
                        break;

                    case RPNOperandType.NOTEQUAL:          //"!=",
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b != a);
#if DEBUG
                        Console.WriteLine($"{b} !={a} = {r}");
#endif
                        break;

                    case RPNOperandType.EQUAL:          //"=="
                        a = Convert.ToDouble(al.Pop());
                        b = Convert.ToDouble(al.Pop());
                        r = (b == a);
#if DEBUG
                        Console.WriteLine($"{b} =={a} = {r}");
#endif
                        break;

                    case RPNOperandType.OR:          //"||",
                        a1 = Convert.ToBoolean(al.Pop());
                        b1 = Convert.ToBoolean(al.Pop());
                        r  = (b1 || a1);
#if DEBUG
                        Console.WriteLine($"{b1} || {a1} = {r}");
#endif
                        break;


                    case RPNOperandType.AND:          //"&&",

                        a1 = Convert.ToBoolean(al.Pop());
                        b1 = Convert.ToBoolean(al.Pop());
                        r  = (b1 && a1);
#if DEBUG
                        Console.WriteLine($"{b1} && {a1} = {r}");
#endif
                        break;

                    case RPNOperandType.NOT:          //"!",
                        a1 = Convert.ToBoolean(al.Pop());
                        r  = (!a1);
#if DEBUG
                        Console.WriteLine($" !{a1} = {r}");
#endif
                        break;
                    }
                    al.Push(r);
                    break;
                }
                i++;
            }

            while (x < al.Count)
            {
                ret = al.Pop();
            }

            return(ret);
        }