Beispiel #1
0
        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();
        }