private Expression BinaryExpression(bool noIn, ref bool isLHS) { var e = UnaryExpression(ref isLHS); var stack = new Seq<SREntry>(); while (true) { var op = default(BinaryOperator); switch (Current.Tag) { case InputElementTag.Times: op = new BinaryOperator(Current.Loc, BinaryOp.Times); break; case InputElementTag.Slash: op = new BinaryOperator(Current.Loc, BinaryOp.Div); break; case InputElementTag.Percent: op = new BinaryOperator(Current.Loc, BinaryOp.Mod); break; case InputElementTag.Plus: op = new BinaryOperator(Current.Loc, BinaryOp.Plus); break; case InputElementTag.Minus: op = new BinaryOperator(Current.Loc, BinaryOp.Minus); break; case InputElementTag.LTLT: op = new BinaryOperator(Current.Loc, BinaryOp.LeftShift); break; case InputElementTag.GTGT: op = new BinaryOperator(Current.Loc, BinaryOp.RightShift); break; case InputElementTag.GTGTGT: op = new BinaryOperator(Current.Loc, BinaryOp.UnsignedRightShift); break; case InputElementTag.LT: op = new BinaryOperator(Current.Loc, BinaryOp.LessThan); break; case InputElementTag.GT: op = new BinaryOperator(Current.Loc, BinaryOp.GreaterThan); break; case InputElementTag.LTEq: op = new BinaryOperator(Current.Loc, BinaryOp.LessThanOrEqual); break; case InputElementTag.GTEq: op = new BinaryOperator(Current.Loc, BinaryOp.GreaterThanOrEqual); break; case InputElementTag.Instanceof: op = new BinaryOperator(Current.Loc, BinaryOp.InstanceOf); break; case InputElementTag.In: if (!noIn) op = new BinaryOperator(Current.Loc, BinaryOp.In); break; case InputElementTag.EqEq: op = new BinaryOperator(Current.Loc, BinaryOp.Equals); break; case InputElementTag.BangEq: op = new BinaryOperator(Current.Loc, BinaryOp.NotEquals); break; case InputElementTag.EqEqEq: op = new BinaryOperator(Current.Loc, BinaryOp.StrictEquals); break; case InputElementTag.BangEqEq: op = new BinaryOperator(Current.Loc, BinaryOp.StrictNotEquals); break; case InputElementTag.Amp: op = new BinaryOperator(Current.Loc, BinaryOp.BitwiseAND); break; case InputElementTag.Hat: op = new BinaryOperator(Current.Loc, BinaryOp.BitwiseXOR); break; case InputElementTag.Bar: op = new BinaryOperator(Current.Loc, BinaryOp.BitwiseOR); break; case InputElementTag.AmpAmp: op = new BinaryOperator(Current.Loc, BinaryOp.LogicalAND); break; case InputElementTag.BarBar: op = new BinaryOperator(Current.Loc, BinaryOp.LogicalOR); break; default: break; } if (op == null) { while (stack.Count > 0) Reduce(ref e, stack); return e; } else { isLHS = false; Consume(); var dummy = true; var r = UnaryExpression(ref dummy); while (stack.Count > 0 && stack.Peek().Op.Precedence >= op.Precedence) Reduce(ref e, stack); stack.Push(new SREntry() { Op = op, Exp = r }); } } }
private void Reduce(ref Expression bottom, Seq<SREntry> stack) { var top = stack.Pop(); if (stack.Count == 0) bottom = new BinaryExpression(bottom.Loc.Union(top.Exp.Loc), bottom, top.Op, top.Exp); else stack.Peek().Exp = new BinaryExpression(stack.Peek().Exp.Loc.Union(top.Exp.Loc), stack.Peek().Exp, top.Op, top.Exp); }