private Expr ConstructBinaryExpr(List <Expr> pathExps)
        {
            // Case 1: Simple addition of @home and "\build\script.xml" as in "@home\build\script.xml"
            if (pathExps.Count == 2)
            {
                return(Exprs.Binary(pathExps[0], Operator.Add, pathExps[1], pathExps[0].Token));
            }
            // Case 2: Add up all the expressions.
            // Start with the last 2 and keep adding backwards.
            // e.g. 0 1 2 3
            // Exp1: Bin( 2, add, 3 )
            // Exp2: Bin( 1, Exp1 )
            // Exp3: Bin( 0, Exp2 )
            // e.g.  Bin( 0, add, Bin( 1, add, Bin( 2, add, 3 ) ) )
            var lastIndex = pathExps.Count - 1;
            var left      = pathExps[lastIndex - 1];
            var right     = pathExps[lastIndex];
            var exp       = Exprs.Binary(left, Operator.Add, right, left.Token);

            for (var ndx = lastIndex - 2; ndx >= 0; ndx--)
            {
                left = pathExps[ndx];
                exp  = Exprs.Binary(left, Operator.Add, exp, left.Token);
            }
            return(exp);
        }
Beispiel #2
0
        /// <summary>
        /// The shunting yard algorithm that processes a postfix list of expressions/operators.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="parser"></param>
        /// <param name="stack"></param>
        /// <returns></returns>
        public static Expr ProcessShuntingYardList(Context context, Parser.Parser parser, List <object> stack)
        {
            int  index    = 0;
            Expr finalExp = null;

            // Shunting yard algorithm handles POSTFIX operations.
            while (index < stack.Count && stack.Count > 0)
            {
                // Keep moving forward to the first operator * - + / && that is found
                // This is a postfix algorithm so it works by creating an expression
                // from the last 2 items behind an operator.
                if (!(stack[index] is TokenData))
                {
                    index++;
                    continue;
                }

                // At this point... we hit an operator
                // So get the last 2 items on the stack ( they have to be expressions )
                // left  is 2 behind current position
                // right is 1 behind current position
                var       left  = stack[index - 2] as Expr;
                var       right = stack[index - 1] as Expr;
                TokenData tdata = stack[index] as TokenData;
                Token     top   = tdata.Token;
                Operator  op    = Operators.ToOp(top.Text);
                Expr      exp   = null;

                if (Operators.IsMath(op))
                {
                    exp = Exprs.Binary(left, op, right, tdata);
                }
                else if (Operators.IsConditional(op))
                {
                    exp = Exprs.Condition(left, op, right, tdata);
                }
                else if (Operators.IsCompare(op))
                {
                    exp = Exprs.Compare(left, op, right, tdata);
                }

                parser.SetupContext(exp, tdata);
                stack.RemoveRange(index - 2, 2);
                index        = index - 2;
                stack[index] = exp;
                index++;
            }
            finalExp = stack[0] as Expr;
            return(finalExp);
        }