Example #1
0
        private void Compile(string exp)
        {
            // tokenize the expression using 3 regex capture groups:
            //  ([A-Za-z]+\d*)  :  at least one alpha character followed by 0 or more digits
            //  ([-/\+\*\(\)])  :  any of the +, -, *, / operators or parens
            //  (\d+\.?\d+)     :  a constant number that may contain a decimal number
            //
            // after tokenizing make sure that the resulting token list doesnt
            // contain any empty strings and then listify the enumerable
            var tokens = Regex.Split(exp, @"([A-Za-z]+\d*)|([-/\+\*\(\)])|(\d+\.?\d+)")
                         .Where(s => s != String.Empty)
                         .ToList <string>();

            // convert token list to prefix expression which is then trivial to iterate through
            // and linearly build the expression tree
            var nodeStack = new Stack <Node>();

            foreach (var tok in InfixToPrefix(tokens))
            {
                if (Char.IsLetter(tok[0]))
                {
                    nodeStack.Push(new VarNode(tok));

                    /*
                     * if(!vars.ContainsKey(tok))
                     *  vars[tok] = 0;  // default value of 0
                     */
                    locals.Add(tok);
                }
                else if (Char.IsDigit(tok[0]))
                {
                    nodeStack.Push(new ConstNode(Double.Parse(tok)));
                }
                else
                {
                    var on = new OpNode(tok[0]);
                    on.right = nodeStack.Pop();
                    on.left  = nodeStack.Pop();
                    nodeStack.Push(on);
                }
            }

            root = nodeStack.Pop();
        }
Example #2
0
        // This is a compile utility function that will serve as a recursive call for compile
        // it will take an expression and an operator to return a branch node of the expression
        private Node Compile(string expression, char operation)
        {
            bool flag = false;
            // we want to read from the right to find the rightmost lowest precedence operator
            int i        = expression.Length - 1;
            int pCounter = 0;

            while (!flag)
            {
                // increment parenthesis counter
                if (expression[i] == '(')
                {
                    pCounter++;
                }
                // decrement parenthesis counter
                else if (expression[i] == ')')
                {
                    pCounter--;
                }

                if (pCounter == 0 && expression[i] == operation) // when we reach an operator, evaluate expression
                {
                    // create and return subtree with current operation being the root node
                    // and the left and right expressions as their own compiled subtrees
                    OpNode opNode = new OpNode(operation);
                    // left subtree is the beginning of the string to the current index
                    opNode.L = Compile(expression.Substring(0, i));
                    // right subtree is the next index to the end of the string
                    opNode.R = Compile(expression.Substring(i + 1));
                    return(opNode);
                }
                else
                {
                    if (i == 0) // reached the left end of the expression - terminate
                    {
                        flag = true;
                    }
                    i--; // continue reading the next part of the expression to the left
                }
            }
            return(null);
        }
Example #3
0
        // private Eval helper function for public Eval()
        // takes input node argument and evaluates it
        private double Eval(Node NodeArg)
        {
            ConstantNode cNode = NodeArg as ConstantNode;

            if (cNode != null)
            {
                return(cNode.m_constant);
            }

            VarNode vNode = NodeArg as VarNode;

            if (vNode != null)
            {
                return(VarDictionary[vNode.m_var]);
            }

            // if node is operator, recursively evaluate left and right subtrees
            // and perform respective operations on them
            OpNode oNode = NodeArg as OpNode;

            if (oNode != null)
            {
                switch (oNode.m_operand) // evalutate the left subtree and then right subtree
                {
                case '+':
                    return(Eval(oNode.L) + Eval(oNode.R));

                case '-':
                    return(Eval(oNode.L) - Eval(oNode.R));

                case '*':
                    return(Eval(oNode.L) * Eval(oNode.R));

                case '/':
                    return(Eval(oNode.L) / Eval(oNode.R));
                }
            }
            return(0);
        }