private static string FormsOf(string text, FormsOfType type) { if (IsComplexExpression(text)) { return(text); } if (text[text.Length - 2] == '*') { return(text); } switch (type) { case FormsOfType.None: return(text); case FormsOfType.Inflectional: return($"FORMSOF(INFLECTIONAL, {text})"); case FormsOfType.Thesaurus: return($"FORMSOF(THESAURUS, {text})"); case FormsOfType.Both: return($"(FORMSOF(INFLECTIONAL, {text}) OR FORMSOF(THESAURUS, {text}))"); default: throw new ParsingException("Unknown FormsOfType.", ErrorKind.UnknownFormsOfType); } }
private static void ProcessOr(Stack <string> stack, FormsOfType type) { var o2 = stack.Pop(); var o1 = stack.Pop(); var result = $"({FormsOf(o1, type)} OR {FormsOf(o2, type)})"; stack.Push(result); }
/// <summary> /// Compiles a given postfix notation expression into a CONTAINSTABLE search condition. /// </summary> /// <param name="searchExpression">The input search expression.</param> /// <param name="type">The FORMSOF type to generate.</param> /// <returns>The CONTAINSTABLE search condition.</returns> public static string Translate(string searchExpression, FormsOfType type = FormsOfType.Both) { if (searchExpression == null) { throw new ArgumentNullException(nameof(searchExpression), "String cannot be null."); } var lexemes = Lexer.Tokenize(searchExpression); if (lexemes.Length == 0) { throw new ParsingException("The tokenized search expression contains no lexical elements.", ErrorKind.InvalidEmptyExpression); } lexemes = FixAndKeywordCommonIssuesForUserFriendliness(lexemes); var postfixNotation = Parser.GetPostfixNotation(lexemes); postfixNotation = FixApostrophesForUserFriendliness(postfixNotation); var translation = CodeGenerator.Generate(postfixNotation, type); return(translation); }
/// <summary> /// Generates CONTAINSTABLE search condition code for a given postfix notation expression. /// </summary> /// <param name="postfixNotation">The input postfix notation.</param> /// <param name="type">The FORMSOF type to generate.</param> /// <returns>The CONTAINSTABLE search condition.</returns> public static string Generate(LexicalElement[] postfixNotation, FormsOfType type = FormsOfType.Both) { if (postfixNotation == null) { throw new ArgumentNullException(nameof(postfixNotation), "Postfix notation array cannot be null."); } if (postfixNotation.Length == 0) { throw new ParsingException("Invalid empty expression.", ErrorKind.InvalidEmptyExpression); } var stack = new Stack <string>(postfixNotation.Length); foreach (var currentElement in postfixNotation) { if (currentElement.Type.IsOperator()) { var operandCount = currentElement.Type.GetOperandCount(); if (stack.Count < operandCount) { throw new ParsingException( $"Missing operand for operator. Expected {operandCount} operands, found {stack.Count} potential operands", currentElement, ErrorKind.MissingOperand); } switch (currentElement.Type) { case LexicalElementType.And: ProcessAnd(stack, type); break; case LexicalElementType.Not: ProcessNot(stack, type); break; case LexicalElementType.Or: ProcessOr(stack, type); break; case LexicalElementType.Near: ProcessNear(stack, currentElement, false); break; case LexicalElementType.OrderedNear: ProcessNear(stack, currentElement, true); break; } } else { if (currentElement.Type != LexicalElementType.Term) { throw new ParsingException("Expected \"Term\" token type. Found unexpected token", currentElement, ErrorKind.UnexpectedTokenType); } stack.Push(Quote(currentElement.Text)); } } if (stack.Count != 1) { throw new ParsingException($"Evaluation failed. The stack contains {stack.Count} items.", ErrorKind.StackHasMoreOrLessThanOneItem); } var result = stack.Pop(); result = FormsOf(result, type); return(result); }