Beispiel #1
0
        private decimal BasicArithmeticalExpression(List <string> tokens)
        {
            // PERFORMING A BASIC ARITHMETICAL EXPRESSION CALCULATION
            // THIS METHOD CAN ONLY OPERATE WITH NUMBERS AND OPERATORS
            // AND WILL NOT UNDERSTAND ANYTHING BEYOND THAT.

            switch (tokens.Count)
            {
            case 1:
                return(decimal.Parse(tokens[0], CultureInfo));

            case 2:
            {
                var op = tokens[0];

                if (op == "-" || op == "+")
                {
                    return(decimal.Parse((op == "+" ? "" : (tokens[1].Substring(0, 1) == "-" ? "" : "-")) + tokens[1], CultureInfo));
                }

                return(OperatorAction[op](0, decimal.Parse(tokens[1], CultureInfo)));
            }

            case 0:
                return(0);
            }

            foreach (var op in OperatorList)
            {
                while (tokens.IndexOf(op) != -1)
                {
                    var opPlace = tokens.IndexOf(op);

                    var numberA = Convert.ToDecimal(tokens[opPlace - 1], CultureInfo);
                    var numberB = Convert.ToDecimal(tokens[opPlace + 1], CultureInfo);

                    var result = OperatorAction[op](numberA, numberB);

                    tokens[opPlace - 1] = result.ToString(CultureInfo);
                    tokens.RemoveRange(opPlace, 2);
                }
            }
            return(Convert.ToDecimal(tokens[0], CultureInfo));
        }
Beispiel #2
0
        private decimal BasicArithmeticalExpression(List <string> _tokens)
        {
            // PERFORMING A BASIC ARITHMETICAL EXPRESSION CALCULATION
            // THIS METHOD CAN ONLY OPERATE WITH NUMBERS AND OPERATORS
            // AND WILL NOT UNDERSTAND ANYTHING BEYOND THAT.

            if (_tokens.Count == 1)
            {
                return(decimal.Parse(_tokens[0], CULTURE_INFO));
            }
            else if (_tokens.Count == 2)
            {
                string op = _tokens[0];
                if (op == "-" || op == "+")
                {
                    return(decimal.Parse((op == "+" ? "" : "-") + _tokens[1], CULTURE_INFO));
                }
                else
                {
                    return(OperatorAction[op](0, decimal.Parse(_tokens[1], CULTURE_INFO)));
                }
            }
            else if (_tokens.Count == 0)
            {
                return(0);
            }
            foreach (string op in OperatorList)
            {
                while (_tokens.IndexOf(op) != -1)
                {
                    int opPlace = _tokens.IndexOf(op);

                    decimal numberA = Convert.ToDecimal(_tokens[opPlace - 1], CULTURE_INFO);
                    decimal numberB = Convert.ToDecimal(_tokens[opPlace + 1], CULTURE_INFO);

                    decimal result = OperatorAction[op](numberA, numberB);

                    _tokens[opPlace - 1] = result.ToString(CULTURE_INFO);
                    _tokens.RemoveRange(opPlace, 2);
                }
            }
            return(Convert.ToDecimal(_tokens[0], CULTURE_INFO));
        }
Beispiel #3
0
 public CustomParser() : base()
 {
     OperatorList.Add("!");
     OperatorList.Add("_");
     OperatorAction.Add("!", (x, y) => Factorial(x));
     OperatorAction.Add("_", (x, y) => 10.130M);
     LocalFunctions["log"] = (input) =>
     {
         if (input.Length == 1)
         {
             return((decimal)Math.Log((double)input[0]));
         }
         else if (input.Length == 2)
         {
             return((decimal)Math.Log((double)input[1], (double)input[0]));
         }
         else
         {
             return(0); // false
         }
     };
     LocalFunctions.Add("ln", x => (decimal)Math.Log((double)x[0]));
     LocalFunctions.Add("logn", x => (decimal)Math.Log((double)x[0]));
 }
        /// <summary>
        /// This constructor will add some basic operators, functions, and variables
        /// to the parser. Please note that you are able to change that using
        /// boolean flags
        /// </summary>
        /// <param name="loadPreDefinedFunctions">This will load "abs", "cos", "cosh", "arccos", "sin", "sinh", "arcsin", "tan", "tanh", "arctan", "sqrt", "rem", "round"</param>
        /// <param name="loadPreDefinedOperators">This will load "%", "*", ":", "/", "+", "-", ">", "&lt;", "="</param>
        /// <param name="loadPreDefinedVariables">This will load "pi", "pi2", "pi05", "pi025", "pi0125", "pitograd", "piofgrad", "e", "phi", "major", "minor"</param>
        public MathParser(bool loadPreDefinedFunctions = true, bool loadPreDefinedOperators = true, bool loadPreDefinedVariables = true)
        {
            if (loadPreDefinedOperators)
            {
                // by default, we will load basic arithmetic operators.
                // please note, its possible to do it either inside the constructor,
                // or outside the class. the lowest value will be executed first!
                OperatorList.Add("^"); // to the power of
                OperatorList.Add("%"); // modulo
                OperatorList.Add(":"); // division 1
                OperatorList.Add("/"); // division 2
                OperatorList.Add("*"); // multiplication
                OperatorList.Add("-"); // subtraction
                OperatorList.Add("+"); // addition

                OperatorList.Add(">"); // greater than
                OperatorList.Add("≥"); // greater or equal than
                OperatorList.Add("<"); // less than
                OperatorList.Add("≤"); // less or equal than
                OperatorList.Add("="); // are equal
                OperatorList.Add("≠"); // not equal

                // when an operator is executed, the parser needs to know how.
                // this is how you can add your own operators. note, the order
                // in this list does not matter.
                OperatorAction.Add("^", Math.Pow);
                OperatorAction.Add("%", (numberA, numberB) => numberA % numberB);
                OperatorAction.Add(":", (numberA, numberB) => numberA / numberB);
                OperatorAction.Add("/", (numberA, numberB) => numberA / numberB);
                OperatorAction.Add("*", (numberA, numberB) => numberA * numberB);
                OperatorAction.Add("+", (numberA, numberB) => numberA + numberB);
                OperatorAction.Add("-", (numberA, numberB) => numberA - numberB);

                OperatorAction.Add(">", (numberA, numberB) => numberA > numberB ? 1 : 0);
                OperatorAction.Add("≥", (numberA, numberB) => numberA >= numberB ? 1 : 0);
                OperatorAction.Add("<", (numberA, numberB) => numberA < numberB ? 1 : 0);
                OperatorAction.Add("≤", (numberA, numberB) => numberA <= numberB ? 1 : 0);
                OperatorAction.Add("=", (numberA, numberB) => Math.Abs(numberA - numberB) < double.Epsilon ? 1 : 0);
                OperatorAction.Add("≠", (numberA, numberB) => Math.Abs(numberA - numberB) < double.Epsilon ? 0 : 1);
            }


            if (loadPreDefinedFunctions)
            {
                // these are the basic functions you might be able to use.
                // as with operators, localFunctions might be adjusted, i.e.
                // you can add or remove a function.
                // please open the "MathosTest" project, and find MathParser.cs
                // in "CustomFunction" you will see three ways of adding
                // a new function to this variable!
                // EACH FUNCTION MAY ONLY TAKE ONE PARAMETER, AND RETURN ONE
                // VALUE. THESE VALUES SHOULD BE IN "DOUBLE FORMAT"!
                LocalFunctions.Add("abs", x => Math.Abs(x[0]));

                LocalFunctions.Add("cos", x => Math.Cos(x[0]));
                LocalFunctions.Add("cosh", x => Math.Cosh(x[0]));
                LocalFunctions.Add("arccos", x => Math.Acos(x[0]));

                LocalFunctions.Add("sec", x => 1.0 / Math.Cos(x[0]));
                LocalFunctions.Add("cosec", x => 1.0 / Math.Sin(x[0]));
                LocalFunctions.Add("cotan", x => 1.0 / Math.Tan(x[0]));

                LocalFunctions.Add("sin", x => Math.Sin(x[0]));
                LocalFunctions.Add("sinh", x => Math.Sinh(x[0]));
                LocalFunctions.Add("arcsin", x => Math.Asin(x[0]));

                LocalFunctions.Add("tan", x => Math.Tan(x[0]));
                LocalFunctions.Add("tanh", x => Math.Tanh(x[0]));
                LocalFunctions.Add("arctan", x => Math.Atan(x[0]));

                LocalFunctions.Add("radtodeg", x => x[0] / Math.PI * 180.0);
                LocalFunctions.Add("degtorad", x => x[0] / 180.0 * Math.PI);

                LocalFunctions.Add("arctan2", x => Math.Atan2(x[0], x[1]));
                LocalFunctions.Add("distance", x => Math.Sqrt(Math.Pow((x[2] - x[0]), 2.0) + Math.Pow((x[3] - x[1]), 2.0)));

                LocalFunctions.Add("max", x => Math.Max(x[0], x[1]));
                LocalFunctions.Add("min", x => Math.Min(x[0], x[1]));
                LocalFunctions.Add("random", x => RandomNumber(x[0], x[1]));

                LocalFunctions.Add("sqrt", x => Math.Sqrt(x[0]));
                LocalFunctions.Add("rem", x => Math.IEEERemainder(x[0], x[1]));
                LocalFunctions.Add("root", x => Math.Pow(x[0], 1.0 / x[1]));

                LocalFunctions.Add("pow", x => Math.Pow(x[0], x[1]));

                LocalFunctions.Add("exp", x => Math.Exp(x[0]));
                //LocalFunctions.Add("log", x => (decimal)Math.Log((double)x[0]));
                //LocalFunctions.Add("log10", x => (decimal)Math.Log10((double)x[0]));

                LocalFunctions.Add("log", delegate(double[] input)
                {
                    // input[0] is the number
                    // input[1] is the base

                    switch (input.Length)
                    {
                    case 1:
                        return(Math.Log(input[0]));

                    case 2:
                        return(Math.Log(input[0], input[1]));

                    default:
                        return(0);    // false
                    }
                });

                LocalFunctions.Add("round", delegate(double[] input)
                {
                    // input[0] is the number
                    // input[1] is the decimals

                    switch (input.Length)
                    {
                    case 1:
                        return(Math.Round(input[0]));

                    case 2:
                        return(Math.Round(input[0], (int)input[1]));

                    default:
                        return(0);    // false
                    }
                });

                //LocalFunctions.Add("round", x => Math.Round(x[0]));
                LocalFunctions.Add("truncate", x => x[0] < 0 ? -Math.Floor(-x[0]) : Math.Floor(x[0]));
                LocalFunctions.Add("floor", x => Math.Floor(x[0]));
                LocalFunctions.Add("ceiling", x => Math.Ceiling(x[0]));
                LocalFunctions.Add("sign", x => Math.Sign(x[0]));

                LocalFunctions.Add("or", x => OrFunction(x));
                LocalFunctions.Add("and", x => AndFunction(x));
                LocalFunctions.Add("if", x => IfFunction(x[0], x[1], x[2]));

                LocalStringFunctions.Add("hex2dec", x => Hex2DecFunction(x));
            }

            if (loadPreDefinedVariables)
            {
                // local variables such as pi can also be added into the parser.
                LocalVariables.Add("pi", 3.14159265358979323846264338327950288); // the simplest variable!
                LocalVariables.Add("pi2", 6.28318530717958647692528676655900576);
                LocalVariables.Add("pi05", 1.57079632679489661923132169163975144);
                LocalVariables.Add("pi025", 0.78539816339744830961566084581987572);
                LocalVariables.Add("pi0125", 0.39269908169872415480783042290993786);
                LocalVariables.Add("pitograd", 57.2957795130823208767981548141051704);
                LocalVariables.Add("piofgrad", 0.01745329251994329576923690768488612);
                LocalVariables.Add("pitorad", 57.2957795130823208767981548141051704);
                LocalVariables.Add("piofrad", 0.01745329251994329576923690768488612);

                LocalVariables.Add("e", 2.71828182845904523536028747135266249);
                LocalVariables.Add("phi", 1.61803398874989484820458683436563811);
                LocalVariables.Add("major", 0.61803398874989484820458683436563811);
                LocalVariables.Add("minor", 0.38196601125010515179541316563436189);
            }
        }
Beispiel #5
0
 public CustomParser() : base()
 {
     OperatorList.Add("!");
     OperatorAction.Add("!", (x, y) => Factorial(x));
 }
Beispiel #6
0
        private string BasicArithmeticalExpression(List <string> tokens)
        {
            // PERFORMING A BASIC ARITHMETICAL EXPRESSION CALCULATION
            // THIS METHOD CAN ONLY OPERATE WITH NUMBERS AND OPERATORS
            // AND WILL NOT UNDERSTAND ANYTHING BEYOND THAT.

            //switch (tokens.Count)
            //{
            //    case 1:
            //        if(!tokens.Contains("ld"))
            //        {
            //            return decimal.Parse(tokens[0]);
            //        }
            //    case 2:
            //        {
            //            var op = tokens[0];

            //            if (op == "-" || op == "+")
            //                return decimal.Parse((op == "+" ? "" : "-") + tokens[1], CultureInfo);

            //            return OperatorAction[op](0, decimal.Parse(tokens[1], CultureInfo));
            //        }
            //    case 0:
            //        return "";
            //}

            //foreach (var op in OperatorList)
            //{
            //    while (tokens.IndexOf(op) != -1)
            //    {
            //        var opPlace = tokens.IndexOf(op);

            //        var numberA = Convert.ToDecimal(tokens[opPlace - 1], CultureInfo);
            //        var numberB = Convert.ToDecimal(tokens[opPlace + 1], CultureInfo);

            //        var result = OperatorAction[op](numberA, numberB);

            //        tokens[opPlace - 1] = result.ToString(CultureInfo);
            //        tokens.RemoveRange(opPlace, 2);
            //    }
            //}

            foreach (var op in OperatorList)
            {
                while (tokens.IndexOf(op) != -1)
                {
                    var opPlace = tokens.IndexOf(op);

                    if (!(tokens[opPlace - 1].Contains("ld") || tokens[opPlace + 1].Contains("ld")))
                    {
                        //both are numbers

                        var numberA = decimal.Parse(tokens[opPlace - 1]);
                        var numberB = decimal.Parse(tokens[opPlace + 1]);

                        var result = OperatorAction[op](numberA, numberB);
                        DecimalToIL(result);
                        tokens[opPlace - 1] = "ldloc." + (stackCount - 1);
                        tokens.RemoveRange(opPlace, 2);
                    }
                    else if (tokens[opPlace - 1].Contains("ld") && tokens[opPlace + 1].Contains("ld"))
                    {
                        OutputIL += tokens[opPlace - 1] + "\r\n";
                        OutputIL += tokens[opPlace + 1] + "\r\n";
                        OutputIL += OperatorActionIL[op].Replace("@", stackCount.ToString("x2")) + "\r\n";
                        //OutputIL += "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)" + "\n";
                        OutputIL           += "stloc." + stackCount + "\r\n";
                        tokens[opPlace - 1] = "ldloc." + (stackCount);
                        tokens.RemoveRange(opPlace, 2);
                        stackCount++;
                    }
                    else
                    {
                        if (tokens[opPlace - 1].Contains("ld"))
                        {
                            var numberB = decimal.Parse(tokens[opPlace + 1]);
                            DecimalToIL(numberB); //stack -1

                            OutputIL += tokens[opPlace - 1] + "\r\n";
                            OutputIL += "ldloc." + (stackCount - 1) + "\r\n";
                            OutputIL += OperatorActionIL[op].Replace("@", stackCount.ToString("x2")) + "\r\n";
                            //OutputIL += "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)" + "\n";
                            OutputIL           += "stloc." + stackCount + "\r\n";
                            tokens[opPlace - 1] = "ldloc." + (stackCount);
                            tokens.RemoveRange(opPlace, 2);
                            stackCount++;
                        }
                        else if (tokens[opPlace + 1].Contains("ld"))
                        {
                            var numberA = decimal.Parse(tokens[opPlace - 1]);
                            DecimalToIL(numberA); //stack -1

                            OutputIL += "ldloc." + (stackCount - 1) + "\r\n";
                            OutputIL += tokens[opPlace + 1] + "\r\n";
                            OutputIL += OperatorActionIL[op].Replace("@", stackCount.ToString("x2")) + "\r\n";
                            //OutputIL += "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)" + "\n";
                            OutputIL           += "stloc." + stackCount + "\r\n";
                            tokens[opPlace - 1] = "ldloc." + (stackCount);
                            tokens.RemoveRange(opPlace, 2);
                            stackCount++;
                        }
                    }
                }
            }

            return(tokens[0]);

            //return Convert.ToDecimal(tokens[0], CultureInfo);
        }
Beispiel #7
0
        /// <summary>
        /// This constructor will add some basic operators, functions, and variables
        /// to the parser. Please note that you are able to change that using
        /// boolean flags
        /// </summary>
        /// <param name="loadPreDefinedOperators">This will load "%", "*", ":", "/", "+", "-", ">", "&lt;", "="</param>
        public ILMathParser(bool loadPreDefinedOperators = true)
        {
            if (loadPreDefinedOperators)
            {
                OperatorList.Add("/"); // division 2
                OperatorList.Add("*"); // multiplication
                OperatorList.Add("-"); // subtraction
                OperatorList.Add("+"); // addition

                OperatorList.Add(">"); // greater than
                OperatorList.Add("<"); // less than
                OperatorList.Add("="); // are equal


                OperatorActionIL.Add("/", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Division(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)");
                OperatorAction.Add("/", (x, y) => x - y);

                OperatorActionIL.Add("*", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Multiply(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)");
                OperatorAction.Add("*", (x, y) => x - y);

                OperatorActionIL.Add("-", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Subtraction(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)");
                OperatorAction.Add("-", (x, y) => x - y);

                OperatorActionIL.Add("+", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)");
                OperatorAction.Add("+", (x, y) => x + y);

                OperatorActionIL.Add(">", "call bool [mscorlib]System.Decimal::op_GreaterThan(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)\r\n" +
                                     "brtrue.s q@\r\n" +
                                     "ldc.i4.0 \r\n" +
                                     "br.s p@\r\n"
                                     + "q@: ldc.i4.1\r\n"
                                     + "p@: nop\r\n"
                                     + "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)");
                OperatorAction.Add(">", (x, y) => x > y ? 1 : 0);

                OperatorActionIL.Add("<", "call bool [mscorlib]System.Decimal::op_LessThan(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)\r\n" +
                                     "brtrue.s q@\r\n" +
                                     "ldc.i4.0 \r\n" +
                                     "br.s p@\r\n"
                                     + "q@: ldc.i4.1\r\n"
                                     + "p@: nop\r\n"
                                     + "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)");
                OperatorAction.Add("<", (x, y) => x < y ? 1 : 0);

                OperatorActionIL.Add("=", "call bool [mscorlib]System.Decimal::op_Equality(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)\r\n" +
                                     "brtrue.s q@\r\n" +
                                     "ldc.i4.0 \r\n" +
                                     "br.s p@\r\n"
                                     + "q@: ldc.i4.1\r\n"
                                     + "p@: nop\r\n"
                                     + "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)");
                OperatorAction.Add("=", (x, y) => x == y ? 1 : 0);



                //OperatorListIL.Add("+",);
                // by default, we will load basic arithmetic operators.
                // please note, its possible to do it either inside the constructor,
                //// or outside the class. the lowest value will be executed first!
                //OperatorList.Add("%"); // modulo
                //OperatorList.Add("^"); // to the power of
                //OperatorList.Add(":"); // division 1
                //OperatorList.Add("/"); // division 2
                //OperatorList.Add("*"); // multiplication
                //OperatorList.Add("-"); // subtraction
                //OperatorList.Add("+"); // addition

                //OperatorList.Add(">"); // greater than
                //OperatorList.Add("<"); // less than
                //OperatorList.Add("="); // are equal


                //// when an operator is executed, the parser needs to know how.
                //// this is how you can add your own operators. note, the order
                //// in this list does not matter.
                //_operatorAction.Add("%", (numberA, numberB) => numberA % numberB);
                //_operatorAction.Add("^", (numberA, numberB) => (decimal)Math.Pow((double)numberA, (double)numberB));
                //_operatorAction.Add(":", (numberA, numberB) => numberA / numberB);
                //_operatorAction.Add("/", (numberA, numberB) => numberA / numberB);
                //_operatorAction.Add("*", (numberA, numberB) => numberA * numberB);
                //_operatorAction.Add("+", (numberA, numberB) => numberA + numberB);
                //_operatorAction.Add("-", (numberA, numberB) => numberA - numberB);

                //_operatorAction.Add(">", (numberA, numberB) => numberA > numberB ? 1 : 0);
                //_operatorAction.Add("<", (numberA, numberB) => numberA < numberB ? 1 : 0);
                //_operatorAction.Add("=", (numberA, numberB) => numberA == numberB ? 1 : 0);
            }
        }