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); }
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); }
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]); } } } }
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); }
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); }
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); } }
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; } } }
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); } } }
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); }
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); }
public void RemoveOperand(QueryParserNode node) { aOperands.Remove(node); }
public void AddOperand(QueryParserNode node) { aOperands.Add(node); }