public void Build() { TokenParser tp = new TokenParser(_query); IEnumerator <Token> enumerator = tp.GetEnumerator(); Stack <Token> tokens = new Stack <Token>(); Stack <TokenType> allowedStack = new Stack <TokenType>(); while (enumerator.MoveNext()) { if (allowedStack.Count > 0) { _allowed = allowedStack.Pop(); } Token token = enumerator.Current; TokenType type = token.Type; if ((_allowed & type) == type) { switch (type) { case TokenType.Group: break; case TokenType.Operator: var op = token.Text; if (op == "OR") { if (tokens.Count > 0) { _orExpr.Add(tokens.Pop()); } } else if (op == "AND") { if (tokens.Count > 0) { _andExpr.Add(tokens.Pop()); } } allowedStack.Push(_allowed); _allowed ^= TokenType.Operator; allowedStack.Push(_allowed); break; case TokenType.Property: var property = token; enumerator.MoveNext(); token = enumerator.Current; if (token == null) { break; } if (token.Type != TokenType.Phrase && token.Type != TokenType.Word) { continue; } property.Text += token.Text; token = property; break; case TokenType.Phrase: case TokenType.Word: break; } bool addToStack = true; while (token != null && tokens.Count > 0) { var lastToken = tokens.Pop() ?? new Token(); if (lastToken.Type == TokenType.Operator && lastToken.Text == "AND") { token.ParentOperator = "AND"; _andExpr.Add(token); addToStack = false; } else if (lastToken.Type == TokenType.Operator && lastToken.Text == "OR") { token.ParentOperator = "OR"; _orExpr.Add(token); addToStack = false; } else if (lastToken.Type == TokenType.Operator && lastToken.Text == "NOT") { token.ParentOperator = "NOT"; _notExpr.Add(token); addToStack = false; } else if (lastToken.Type == TokenType.Operator && lastToken.Text == "ANY") { token.ParentOperator = "ANY"; _orExpr.Add(token); addToStack = false; } else if (lastToken.Type == TokenType.Operator && lastToken.Text == "ALL") { token.ParentOperator = "ALL"; _andExpr.Add(token); addToStack = false; } else if (lastToken.Type == TokenType.Operator && lastToken.Text == "NONE") { token.ParentOperator = "NONE"; _notExpr.Add(token); addToStack = false; } else { if (lastToken.Text.StartsWith("-")) { lastToken.Text = lastToken.Text.Trim('-'); lastToken.ParentOperator = "NONE"; _notExpr.Add(lastToken); } else { lastToken.ParentOperator = "ALL"; _andExpr.Add(lastToken); } } } if (addToStack) { tokens.Push(token); } } } while (tokens.Count > 0) { var lastToken = tokens.Pop(); if (lastToken.Text.StartsWith("-")) { lastToken.Text = lastToken.Text.Trim('-'); _notExpr.Add(lastToken); } else { lastToken.ParentOperator = "ALL"; _andExpr.Add(lastToken); } } GroupEqualPropertyKeys(); }