Feedback

C# - Simple EvaluierungsEngine

Veröffentlicht von am 31.10.2015
(0 Bewertungen)
Ein simpler aritmetischer parser:

Expression result = "3+5*5";
GFU-Schulungen  [Anzeige]

Visual Studio Team Foundation Server 2017/2015 (TFS) für Entwickler - Kompakt

Nach Teilnahme an dieser Schulung kennen Sie alle wesentlichen Funktionen des TFS für Entwickler. Sie setzen Software-Entwicklung mit dem Visual Studio Team Foundation Server erfolgreich um.

VB.NET Aufbau

Sie verfügen nach der Schulung über fundierte Kenntnisse in der Arbeit mit objektorientierten Modellen in VB.NET und können wiederverwendbare Komponenten eigenständig erzeugen.

using System.Parsers.Mathematics;

namespace System.Parsers.Mathematics
{
	public class Expression
    {
        private readonly List<Stack> _stacks = new List<Stack>();

        internal Expression()
        {
        }

        public object Result { get; set; }
        public string Term { get; internal set; }

        public static Expression Parse(string expr, VariableStack[] vars)
        {
            var returns = new Expression {Term = expr};

            expr = expr.Replace("²", "²0");
            expr = expr.Replace("³", "³0");
            expr = expr.Replace("sqrt[", "√");
            expr = expr.Replace("pi", "π");
            expr = expr.Replace("]", "");
            expr = expr.Replace("√", "1√");
            expr = expr.Replace("π", "1π1");
            expr = expr.Replace("True", "1");
            expr = expr.Replace("False", "0");

            if (vars != null)
                expr = vars.Aggregate(expr, (current, var) => current.Replace(@var.Name, @var.Value.ToString()));

            char[] chars = expr.ToCharArray();
            string result = "";
            var group_stack = new GroupStack(new List<Stack>());

            bool bracket_open = false;
            foreach (char c in chars)
            {
                if (isNum(c))
                {
                    result += c;
                }
                else
                {
                    if (isOP(c))
                    {
                        if (!bracket_open)
                        {
                            returns._stacks.Add(new NumStack(Convert.ToDouble(result)));
                            returns._stacks.Add(new OpStack(c.ToString()));
                        }
                        else
                        {
                            group_stack.Value.Add(new NumStack(Convert.ToDouble(result)));
                            group_stack.Value.Add(new OpStack(c.ToString()));
                        }
                        result = "";
                    }
                    else if (c == '(')
                        bracket_open = true;
                    else if (c == ')')
                    {
                        bracket_open = false;
                        // group_stack.Value.Add(returns.getLastNum(expr, group_stack.Value));
                        returns._stacks.Add(group_stack);
                        group_stack = new GroupStack(new List<Stack>());
                    }
                }
            }

            group_stack.Value = returns.dotbeforestatement(group_stack.Value);
            returns.Calculate();

            return returns;
        }

        internal void Calculate()
        {
            for (int i = 0; i < _stacks.Count - 1; i++)
            {
                Stack stack = _stacks[i];
                var opStack = stack as OpStack;
                if (opStack != null)
                {
                    var first = (NumStack) _stacks[i - 1];
                    var second = (NumStack) _stacks[i + 1];
                    OpStack op = opStack;
                    var _result = new NumStack(0);
                    bool resultisbool = false;
                    bool boolresult = false;

                    switch (op.Value)
                    {
                        case "+":
                            _result = new NumStack(first.Value + second.Value);
                            break;
                        case "-":
                            _result = new NumStack(first.Value - second.Value);
                            break;
                        case "*":
                            _result = new NumStack(first.Value*second.Value);
                            break;
                        case "/":
                            _result = new NumStack(first.Value/second.Value);
                            break;
                        case "^":
                            _result = new NumStack(Math.Pow(first.Value, second.Value));
                            break;
                        case "%":
                            _result = new NumStack(first.Value%second.Value);
                            break;
                        case "&":
                            _result = new NumStack(Convert.ToDouble(first.Value.ToString() + second.Value.ToString()));
                            break;
                        case "²":
                            _result = new NumStack(first.Value*first.Value);
                            break;
                        case "³":
                            _result = new NumStack(first.Value*first.Value*first.Value);
                            break;
                        case "√":
                            _result = new NumStack(Math.Sqrt(second.Value));
                            break;
                        case "π":
                            _result = new NumStack(Math.PI);
                            break;
                        case "<":
                            resultisbool = true;
                            boolresult = first.Value < second.Value;
                            break;
                        case ">":
                            resultisbool = true;
                            boolresult = first.Value > second.Value;
                            break;
                        case "!":
                            resultisbool = true;
                            boolresult = first.Value != second.Value;
                            break;
                    }

                    _stacks.RemoveAt(0);
                    _stacks.RemoveAt(0);
                    _stacks.RemoveAt(0);
                    _stacks.Insert(0, _result);

                    Result = (_stacks[0] as NumStack).Value;

                    if (_stacks.Count != 1)
                    {
                        if (_stacks[0] != null && _stacks[1] != null && _stacks[2] != null)
                        {
                            Calculate();
                        }
                    }
                    if (resultisbool)
                    {
                        Result = boolresult;
                    }
                }
            }
        }

        #region "ObjectOperators"

        public static Expression operator +(Expression e1, Expression e2)
        {
            return Parse(e1.Result + "+" + e2.Result, null);
        }

        public static bool operator ==(Expression e1, Expression e2)
        {
            return e1 == e2;
        }

        public static bool operator !=(Expression e1, Expression e2)
        {
            return e1 != e2;
        }

        public static Expression operator +(Expression e1, string e2)
        {
            e2 = e2.Replace("=", "");
            return Parse(e2, null);
        }

        public static Expression operator -(Expression e1, Expression e2)
        {
            return Parse(e1.Result + "-" + e2.Result, null);
        }

        public static Expression operator *(Expression e1, Expression e2)
        {
            return Parse(e1.Result + "*" + e2.Result, null);
        }

        public static Expression operator /(Expression e1, Expression e2)
        {
            return Parse(e1.Result + "/" + e2.Result, null);
        }

        public static Expression operator <(Expression e1, Expression e2)
        {
            return Parse(e1.Result + "<" + e2.Result, null);
        }

        public static Expression operator >(Expression e1, Expression e2)
        {
            return Parse(e1.Result + ">" + e2.Result, null);
        }

        public static implicit operator Expression(string v)
        {
            double r;
            return double.TryParse(v, out r) ? Parse(v + "*1", null) : Parse(v, null);
        }

        public static implicit operator double(Expression instance)
        {
            return (double) instance.Result;
        }

        public static implicit operator bool(Expression instance)
        {
            return (bool) instance.Result;
        }

        public static implicit operator string(Expression instance)
        {
            return instance.Result.ToString();
        }

        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }
            return base.Equals(obj);
        }

        #endregion

        #region "Help Functions"

        private static bool isNum(char s)
        {
            double result;
            return double.TryParse(s.ToString(), out result);
        }

        private static bool isOP(char s)
        {
            return s == '+' | s == '-' | s == '*' | s == '/' | s == '^' | s == '%' | s == '&' | s == '²' | s == '3' |
                   s == '<' | s == '>' | s == '!' | s == '√' | s == 'π';
        }

        private bool isPunctiaton(char s)
        {
            return s == '*' | s == '/';
        }

        private NumStack getLastNum(string s, List<Stack> st)
        {
            string[] c = s.Split(Convert.ToChar((st[st.Count - 1] as OpStack).Value));
            return new NumStack(Convert.ToInt32(c[c.Length - 1]));
        }

        private List<Stack> dotbeforestatement(List<Stack> st)
        {
            List<Stack> returns = st;

            for (int i = 0; i < st.Count; i++)
            {
                Stack s = st[i];

                if (s is OpStack)
                {
                    var op = s as OpStack;
                    if (isPunctiaton(Convert.ToChar(op.Value)))
                    {
                        if (st.Count < 3)
                        {
                            Stack firstop = st[i - 2];
                            Stack first = st[i - 1];
                            Stack ops = s;
                            Stack second = st[i + 1];

                            returns.Remove(first);
                            returns.Remove(ops);
                            returns.Remove(second);
                            returns.Remove(firstop);

                            returns.InsertRange(0, new[] {first, ops, second, firstop});
                        }
                    }
                }
            }

            return returns;
        }

        #endregion

        #region "Implementations"

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public Expression Clone()
        {
            return this;
        }

        public override string ToString()
        {
            return Result.ToString();
        }

        #endregion
    }
	
    public abstract class Stack<t> : Stack
    {
        public t Value { get; set; }
        protected Stack(t v)
        {
            Value = v;
        }
        public override string ToString()
        {
            return Value.ToString();
        }
    }

    public abstract class Stack
    {
    }
	
	public class VariableStack : Stack
    {
        public string Name;
        public object Value;

        public VariableStack(string name, object value)
        {
            Name = name;
            Value = value;
        }
    }
	
	public class OpStack : Stack<string>
    {
        public OpStack(string v)
            : base(v)
        {
        }
    }
	
	public class NumStack : Stack<double>
    {
        public NumStack(double v)
            : base(v)
        {
        }
    }
	public class GroupStack : System.Parsers.Mathematics.Stack<List<Stack>>
    {
        public GroupStack(List<System.Parsers.Mathematics.Stack> v) : base(v)
        {
        }
    }
}
Abgelegt unter math.

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!