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); }
/// <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); }