示例#1
0
        /// <summary>
        /// Parses a query segment and converts it to an expression
        /// tree.
        /// </summary>
        /// <param name="query">Query segment to convert</param>
        /// <param name="defaultConjunction">Implicit conjunction type</param>
        /// <returns>Root node of expression tree</returns>
        private INode ParseNode(string query, ConjunctionTypes defaultConjunction)
        {
            TermForms        termForm    = TermForms.Inflectional;
            bool             termExclude = false;
            ConjunctionTypes conjunction = defaultConjunction;
            bool             resetState  = true;
            INode            root        = null;
            INode            node;
            string           term;

            TextParser parser = new TextParser(query);

            while (!parser.EndOfText)
            {
                if (resetState)
                {
                    // Reset modifiers
                    termForm    = TermForms.Inflectional;
                    termExclude = false;
                    conjunction = defaultConjunction;
                    resetState  = false;
                }

                parser.MovePastWhitespace();
                if (!parser.EndOfText && Punctuation.IndexOf(parser.Peek()) < 0)
                {
                    // Extract query term
                    int start = parser.Position;
                    parser.MoveAhead();
                    while (!parser.EndOfText &&
                           Punctuation.IndexOf(parser.Peek()) < 0 &&
                           !Char.IsWhiteSpace(parser.Peek()))
                    {
                        parser.MoveAhead();
                    }

                    // Allow trailing wildcard
                    if (parser.Peek() == '*')
                    {
                        parser.MoveAhead();
                        termForm = TermForms.Literal;
                    }

                    // Interpret token
                    term = parser.Extract(start, parser.Position);
                    if (String.Compare(term, "AND", true) == 0)
                    {
                        conjunction = ConjunctionTypes.And;
                    }
                    else if (String.Compare(term, "OR", true) == 0)
                    {
                        conjunction = ConjunctionTypes.Or;
                    }
                    else if (String.Compare(term, "NEAR", true) == 0)
                    {
                        conjunction = ConjunctionTypes.Near;
                    }
                    else if (String.Compare(term, "NOT", true) == 0)
                    {
                        termExclude = true;
                    }
                    else
                    {
                        root       = AddNode(root, term, termForm, termExclude, conjunction);
                        resetState = true;
                    }
                    continue;
                }
                else if (parser.Peek() == '"')
                {
                    // Match next term exactly
                    termForm = TermForms.Literal;
                    // Extract quoted term
                    term       = ExtractQuote(parser);
                    root       = AddNode(root, term.Trim(), termForm, termExclude, conjunction);
                    resetState = true;
                }
                else if (parser.Peek() == '(')
                {
                    // Parse parentheses block
                    term       = ExtractBlock(parser, '(', ')');
                    node       = ParseNode(term, defaultConjunction);
                    root       = AddNode(root, node, conjunction, true);
                    resetState = true;
                }
                else if (parser.Peek() == '<')
                {
                    // Parse angle brackets block
                    term       = ExtractBlock(parser, '<', '>');
                    node       = ParseNode(term, ConjunctionTypes.Near);
                    root       = AddNode(root, node, conjunction);
                    resetState = true;
                }
                else if (parser.Peek() == '-')
                {
                    // Match when next term is not present
                    termExclude = true;
                }
                else if (parser.Peek() == '+')
                {
                    // Match next term exactly
                    termForm = TermForms.Literal;
                }
                else if (parser.Peek() == '~')
                {
                    // Match synonyms of next term
                    termForm = TermForms.Thesaurus;
                }
                // Advance to next character
                parser.MoveAhead();
            }
            return(root);
        }
        /// <summary>
        /// Parses a query segment and converts it to an expression
        /// tree.
        /// </summary>
        /// <param name="query">Query segment to convert</param>
        /// <param name="defaultConjunction">Implicit conjunction type</param>
        /// <returns>Root node of expression tree</returns>
        private INode ParseNode(string query, ConjunctionTypes defaultConjunction)
        {
            TermForms termForm = TermForms.Inflectional;
            bool termExclude = false;
            ConjunctionTypes conjunction = defaultConjunction;
            bool resetState = true;
            INode root = null;
            INode node;
            string term;

            TextParser parser = new TextParser(query);
            while (!parser.EndOfText)
            {
                if (resetState)
                {
                    // Reset modifiers
                    termForm = TermForms.Inflectional;
                    termExclude = false;
                    conjunction = defaultConjunction;
                    resetState = false;
                }

                parser.MovePastWhitespace();
                if (!parser.EndOfText && Punctuation.IndexOf(parser.Peek()) < 0)
                {
                    // Extract query term
                    int start = parser.Position;
                    parser.MoveAhead();
                    while (!parser.EndOfText &&
                        Punctuation.IndexOf(parser.Peek()) < 0 &&
                        !Char.IsWhiteSpace(parser.Peek()))
                        parser.MoveAhead();

                    // Allow trailing wildcard
                    if (parser.Peek() == '*')
                    {
                        parser.MoveAhead();
                        termForm = TermForms.Literal;
                    }

                    // Interpret token
                    term = parser.Extract(start, parser.Position);
                    if (String.Compare(term, "AND", true) == 0)
                        conjunction = ConjunctionTypes.And;
                    else if (String.Compare(term, "OR", true) == 0)
                        conjunction = ConjunctionTypes.Or;
                    else if (String.Compare(term, "NEAR", true) == 0)
                        conjunction = ConjunctionTypes.Near;
                    else if (String.Compare(term, "NOT", true) == 0)
                        termExclude = true;
                    else
                    {
                        root = AddNode(root, term, termForm, termExclude, conjunction);
                        resetState = true;
                    }
                    continue;
                }
                else if (parser.Peek() == '"')
                {
                    // Match next term exactly
                    termForm = TermForms.Literal;
                    // Extract quoted term
                    term = ExtractQuote(parser);
                    root = AddNode(root, term.Trim(), termForm, termExclude, conjunction);
                    resetState = true;
                }
                else if (parser.Peek() == '(')
                {
                    // Parse parentheses block
                    term = ExtractBlock(parser, '(', ')');
                    node = ParseNode(term, defaultConjunction);
                    root = AddNode(root, node, conjunction, true);
                    resetState = true;
                }
                else if (parser.Peek() == '<')
                {
                    // Parse angle brackets block
                    term = ExtractBlock(parser, '<', '>');
                    node = ParseNode(term, ConjunctionTypes.Near);
                    root = AddNode(root, node, conjunction);
                    resetState = true;
                }
                else if (parser.Peek() == '-')
                {
                    // Match when next term is not present
                    termExclude = true;
                }
                else if (parser.Peek() == '+')
                {
                    // Match next term exactly
                    termForm = TermForms.Literal;
                }
                else if (parser.Peek() == '~')
                {
                    // Match synonyms of next term
                    termForm = TermForms.Thesaurus;
                }
                // Advance to next character
                parser.MoveAhead();
            }
            return root;
        }