public WhenConstructed() { this.node = new BinaryOperatorNode(this.left, binaryOperatorKind, this.right); }
private SingleValueNode ParseSingleValueFunctionCall() { BinaryOperatorNode binaryNode = null; SingleValueFunctionCallNode node = null; var stack = new Stack<SingleValueFunctionCallNode>(); while (this.tokens.Count > 0) { var token = this.tokens.Dequeue(); switch (token.TokenType) { case TokenType.OpenParentheses: this.groupingDepth++; stack.Push(node); break; case TokenType.CloseParentheses: this.groupingDepth--; if (stack.Count > 0) { var lastNode = stack.Pop(); if (stack.Count > 0) { stack.Peek().Parameters.Add(lastNode); } else { if (binaryNode != null) { binaryNode.Right = lastNode; } else { node = lastNode; } } } break; case TokenType.FunctionName: node = new SingleValueFunctionCallNode(token.Value); break; case TokenType.LogicalOperator: binaryNode = new BinaryOperatorNode(node, BinaryOperatorKindParser.ToBinaryOperatorKind(token.Value), null); break; case TokenType.PropertyName: if (stack.Count > 0) { stack.Peek().Parameters.Add(new SingleValuePropertyAccessNode(token.Value)); } else { binaryNode.Right = new SingleValuePropertyAccessNode(token.Value); } break; case TokenType.Decimal: case TokenType.Double: case TokenType.False: case TokenType.Single: case TokenType.Int32: case TokenType.Int64: case TokenType.DateTime: case TokenType.DateTimeOffset: case TokenType.Guid: case TokenType.String: case TokenType.Null: case TokenType.Time: case TokenType.True: if (stack.Count > 0) { stack.Peek().Parameters.Add(ConstantNodeParser.ParseConstantNode(token)); } else { binaryNode.Right = ConstantNodeParser.ParseConstantNode(token); } break; } } if (binaryNode != null) { return binaryNode; } return node; }
private SingleValueNode ParseSingleValuePropertyAccess() { SingleValueNode result = null; SingleValueNode leftNode = null; BinaryOperatorKind operatorKind = BinaryOperatorKind.None; SingleValueNode rightNode = null; while (this.tokens.Count > 0) { var token = this.tokens.Dequeue(); switch (token.TokenType) { case TokenType.ArithmeticOperator: case TokenType.LogicalOperator: if (operatorKind != BinaryOperatorKind.None) { result = new BinaryOperatorNode(leftNode, operatorKind, rightNode); leftNode = null; rightNode = null; } operatorKind = BinaryOperatorKindParser.ToBinaryOperatorKind(token.Value); break; case TokenType.OpenParentheses: this.groupingDepth++; break; case TokenType.CloseParentheses: this.groupingDepth--; break; case TokenType.FunctionName: if (leftNode == null) { leftNode = new SingleValueFunctionCallNode(token.Value); } else if (rightNode == null) { rightNode = new SingleValueFunctionCallNode(token.Value); } break; case TokenType.PropertyName: if (leftNode == null) { leftNode = new SingleValuePropertyAccessNode(token.Value); } else if (rightNode == null) { rightNode = new SingleValuePropertyAccessNode(token.Value); } break; case TokenType.Decimal: case TokenType.Double: case TokenType.False: case TokenType.Single: case TokenType.Int32: case TokenType.Int64: case TokenType.DateTime: case TokenType.DateTimeOffset: case TokenType.Guid: case TokenType.String: case TokenType.Null: case TokenType.Time: case TokenType.True: rightNode = ConstantNodeParser.ParseConstantNode(token); break; } } result = result == null ? new BinaryOperatorNode(leftNode, operatorKind, rightNode) : new BinaryOperatorNode(result, operatorKind, leftNode ?? rightNode); return result; }
private void UpdateExpressionTree() { var initialGroupingDepth = this.groupingDepth; var node = this.ParseSingleValueNode(); if (this.groupingDepth == initialGroupingDepth) { if (this.nodeStack.Count == 0) { if (this.nextBinaryOperatorKind == BinaryOperatorKind.None) { this.nodeStack.Push(node); } else { this.nodeStack.Push(new BinaryOperatorNode(node, this.nextBinaryOperatorKind, null)); } } else { var leftNode = this.nodeStack.Pop(); var binaryNode = leftNode as BinaryOperatorNode; if (binaryNode != null && binaryNode.Right == null) { binaryNode.Right = node; if (this.nextBinaryOperatorKind != BinaryOperatorKind.None) { binaryNode = new BinaryOperatorNode(binaryNode, this.nextBinaryOperatorKind, null); } } else { binaryNode = new BinaryOperatorNode(leftNode, this.nextBinaryOperatorKind, node); } this.nodeStack.Push(binaryNode); } } else if (this.groupingDepth > initialGroupingDepth) { this.nodeStack.Push(new BinaryOperatorNode(node, this.nextBinaryOperatorKind, null)); } else if (this.groupingDepth < initialGroupingDepth) { var binaryNode = (BinaryOperatorNode)this.nodeStack.Pop(); binaryNode.Right = node; if (this.nextBinaryOperatorKind == BinaryOperatorKind.None) { this.nodeStack.Push(binaryNode); while (this.nodeStack.Count > 1) { var rightNode = this.nodeStack.Pop(); var binaryParent = (BinaryOperatorNode)this.nodeStack.Pop(); binaryParent.Right = rightNode; this.nodeStack.Push(binaryParent); } } else { if (this.groupingDepth == 0 && this.nodeStack.Count > 0) { var binaryParent = (BinaryOperatorNode)this.nodeStack.Pop(); binaryParent.Right = binaryNode; this.nodeStack.Push(new BinaryOperatorNode(binaryParent, this.nextBinaryOperatorKind, null)); } else { this.nodeStack.Push(new BinaryOperatorNode(binaryNode, this.nextBinaryOperatorKind, null)); } } } }
/// <summary> /// Binds the specified <see cref="BinaryOperatorNode"/>. /// </summary> /// <param name="binaryOperatorNode">The <see cref="BinaryOperatorNode"/> to bind.</param> protected abstract void BindBinaryOperatorNode(BinaryOperatorNode binaryOperatorNode);