Пример #1
0
        private static QueryParserNode  ProcessTerm()
        {
            QueryParserNode nodeTerm;
            QueryParserNode result = nodeTerm = ProcessPrimaryLevel();

            GetNextToken();
            if (strToken == "[")
            {
                SectionNode nodeOp = new SectionNode();

                GetNextToken();
                nodeOp.SectionName = strToken;
                nodeOp.AddOperand(nodeTerm);
                _errorMessage = "Error in the query syntax - expected ']' symbol in document section specifier";
                Expect("]");
                _errorMessage = null;

                result = nodeOp;
            }
            else
            {
                BackToken();
            }

            return(result);
        }
Пример #2
0
        public static QueryPostfixForm ParseQuery(string query)
        {
            Initialize();
            _query = query.Trim().ToLower();

            QueryPostfixForm form;

            try
            {
                QueryParserNode nodeRoot = ParseExpression();
                QueryParserNode newRoot  = null;

                PropagateSectionOpInside(ref newRoot, nodeRoot);
                if (newRoot == null)
                {
                    newRoot = nodeRoot;
                }

                form = new QueryPostfixForm();
                Tree2Postfix(newRoot, form);
            }
            catch (Exception)
            {
                form = null;
            }

            return(form);
        }
Пример #3
0
        private static void PropagateSectionOpInside(ref QueryParserNode parent, QueryParserNode subtreeRoot)
        {
            if (subtreeRoot.NodeType == QueryParserNode.Type.eoTerm)
            {
                return;
            }

            if (subtreeRoot.NodeType == QueryParserNode.Type.eoSection)
            {
                Debug.Assert(((OpNode)subtreeRoot).BranchesNumber == 1, "Illegal parsing of section operator");
                QueryParserNode child = ((OpNode)subtreeRoot)[0];
                ArrayList       branches;

                //  if section op is applied to the tree - perform conversion -
                //  propagate section op into every operand of the tree, and
                //  tree root becomes new local root.

                if (child.NodeType != QueryParserNode.Type.eoTerm &&
                    child.NodeType != QueryParserNode.Type.eoSection)
                {
                    //-------------------------------------------------------------
                    if (parent == null)
                    {
                        parent = child;
                    }
                    else
                    {
                        ((OpNode)parent).RemoveOperand(subtreeRoot);
                        ((OpNode)parent).AddOperand(child);
                    }

                    //-------------------------------------------------------------
                    branches = ((OpNode)child).Branches();
                    for (int i = 0; i < branches.Count; i++)
                    {
                        SectionNode newSectionOp = new SectionNode();
                        newSectionOp.SectionName = ((SectionNode)subtreeRoot).SectionName;
                        newSectionOp.AddOperand((QueryParserNode)branches[i]);
                        branches[i] = newSectionOp;
                    }

                    ((OpNode)child).SetOperands(branches);
                }

                //-----------------------------------------------------------------
                if (child.NodeType != QueryParserNode.Type.eoTerm)
                {
                    branches = ((OpNode)child).Branches();
                    for (int i = 0; i < branches.Count; i++)
                    {
                        PropagateSectionOpInside(ref child, (QueryParserNode)branches[i]);
                    }
                }
            }
        }
Пример #4
0
        private static QueryParserNode ParseExpression()
        {
            QueryParserNode nodeLeftOperand = ProcessTerm();

            GetNextToken();

            //---------------------------------------------------------------------
            //  if next token == "" => EOS, no more processing, return left operand
            //  as result,
            //  if next token == ")" => we reached the endo of parenthed expression,
            //  return left operand as result, else process two operands and Op,
            //  return Op as root.
            //---------------------------------------------------------------------

            if ((strToken == "") || (strToken == ")") || (strToken == "+\""))
            {
                BackToken();
                return(nodeLeftOperand);
            }

            QueryParserNode.Type typeNode;
            if (!isPhrasalMode)
            {
                switch (strToken)
                {
                case "and":  typeNode = QueryParserNode.Type.eoAnd; break;

                case "or":   typeNode = QueryParserNode.Type.eoOr;  break;

                case "near": typeNode = QueryParserNode.Type.eoNear; break;

                default:     typeNode = QueryParserNode.Type.eoAnd; BackToken(); break;
                }
            }
            else
            {
                typeNode = QueryParserNode.Type.eoPhraseNear;
                BackToken();
            }

            OpNode          nodeOp           = new OpNode(typeNode);
            QueryParserNode nodeRightOperand = ParseExpression();

            nodeOp.AddOperand(nodeLeftOperand);
            nodeOp.AddOperand(nodeRightOperand);

            return(nodeOp);
        }
Пример #5
0
        private static void Tree2Postfix(QueryParserNode root, QueryPostfixForm form)
        {
            if (root == null)
            {
                return;
            }

            if (root.NodeType != QueryParserNode.Type.eoTerm)
            {
                foreach (QueryParserNode node in ((OpNode)root).Branches())
                {
                    Tree2Postfix(node, form);
                }
            }
            form.Add(root);
        }
Пример #6
0
        private static void  BinaryOp(QueryParserNode node, Stack opStack)
        {
            #region Preconditions
            if (opStack.Count < 2)
            {
                throw new ApplicationException("QueryProcessor -- Insufficient number of operands in the operating stack");
            }
            #endregion Preconditions

            //  First, check One or both arguments to be stopwords.
            object o1 = opStack.Pop(), o2 = opStack.Peek();
            opStack.Push(o1);

            //  If both arguments are stopwords - push them both, leave the stopword
            //  sign as the result for subsequent calculations.
            //  If only one argument is stopword - leave its counterpart as the result.
            if (o1 is StopwordTerm)
            {
                opStack.Pop();
            }
            else
            if (o2 is StopwordTerm)
            {
                opStack.Pop();    // o1
                opStack.Pop();    // o2
                opStack.Push(o1); // o1 again instead of the couple.
            }
            //  both arguments are normal terms which might be met in the index.
            else
            {
                Entry[] result;
                Entry[] rightIndices = ExtractOperandFromStack(opStack);
                Entry[] leftIndices  = ExtractOperandFromStack(opStack);

                if (node.NodeType == QueryParserNode.Type.eoOr)
                {
                    result = Join(leftIndices, rightIndices);
                }
                else
                {
                    result = Intercross(leftIndices, rightIndices, ((OpNode)node).RequiredProximity);
                }

                opStack.Push(result);
            }
        }
Пример #7
0
        private static void IteratePostfixExpression(IList <QueryParserNode> postfixForm, IntHashTable tokens, Stack <List <long> > opStack)
        {
            for (int i = 0; i < postfixForm.Count; i++)
            {
                QueryParserNode node = postfixForm[i];
                switch (node.NodeType)
                {
                case QueryParserNode.Type.eoTerm:
                    PushTermOnStack(((TermNode)node).Term, tokens, opStack); break;

                case QueryParserNode.Type.eoSection:
                    UnarySectionOp(((SectionNode)node).SectionName, opStack); break;

                default:
                    BinaryOp(node, opStack); break;
                }
            }
        }
Пример #8
0
 private static void IteratePostfixExpression(IList <QueryParserNode> postfixForm, TermIndexAccessor termIndex, Stack opStack)
 {
     for (int i = 0; i < postfixForm.Count; i++)
     {
         QueryParserNode node = postfixForm[i];
         if (node.NodeType == QueryParserNode.Type.eoTerm)
         {
             PushTermOnStack(((TermNode)node).Term, termIndex, opStack);
         }
         else
         if (node.NodeType == QueryParserNode.Type.eoSection)
         {
             UnarySectionOp(((SectionNode)node).SectionName, opStack);
         }
         else
         {
             BinaryOp(node, opStack);
         }
     }
 }
Пример #9
0
        private static QueryParserNode  ProcessPrimaryLevel()
        {
            QueryParserNode nodePrimaryToken = null;

            GetNextToken();
            if (strToken != "")
            {
                if (strToken == "(")
                {
                    nodePrimaryToken = ParseExpression();
                    _errorMessage    = "Error in the query syntax - expected ')' symbol in expression";
                    Expect(")");
                    _errorMessage = null;
                }
                else
                if (strToken == "\"+")
                {
                    isPhrasalMode    = true;
                    nodePrimaryToken = ParseExpression();
                    Expect("+\"");
                    isPhrasalMode = false;
                }
                else
                {
                    string normToken = OMEnv.LexemeConstructor.GetNormalizedToken(strToken);

                    if (isDelimitableToken(normToken))
                    {
                        nodePrimaryToken = SplitTokenToTree(normToken);
                    }
                    else
                    {
                        nodePrimaryToken = new TermNode(normToken);
                    }
                }
            }

            return(nodePrimaryToken);
        }
Пример #10
0
        private static void  BinaryOp(QueryParserNode node, Stack <List <long> > opStack)
        {
            #region Preconditions
            if (opStack.Count < 2)
            {
                throw new ApplicationException("QueryProcessor -- Insufficient number of operands in the operating stack");
            }
            #endregion Preconditions

            List <long> result;
            List <long> right = opStack.Pop(), left = opStack.Pop();

            if (node.NodeType == QueryParserNode.Type.eoOr)
            {
                result = Join(left, right);
            }
            else
            {
                result = Intercross(left, right, ((OpNode)node).RequiredProximity);
            }

            opStack.Push(result);
        }
Пример #11
0
 public void  RemoveOperand(QueryParserNode node)
 {
     aOperands.Remove(node);
 }
Пример #12
0
 public void  AddOperand(QueryParserNode node)
 {
     aOperands.Add(node);
 }