SearchGrammar.vb

May 14, 2010 at 7:29 PM

For those of you that wanted a SearchGrammar vb version.

 

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports Irony.Parsing
Imports System.Globalization

Public Class SearchGrammar
    Inherits Grammar

    Public Sub New()
        MyBase.New(False)

        ' Terminals
        Dim Term = CreateTerm("Term")
        Dim Phrase As New StringLiteral("Phrase", """")
        Dim ImpliedAnd As New ImpliedSymbolTerminal("ImpliedAnd")


        ' NonTerminals
        Dim BinaryExpression As New NonTerminal("BinaryExpression")
        Dim BinaryOp As New NonTerminal("BinaryOp")
        Dim Expression As New NonTerminal("Expression")
        Dim PrimaryExpression As New NonTerminal("PrimaryExpression")
        Dim ThesaurusExpression As New NonTerminal("ThesaurusExpression")
        Dim ThesaurusOperator As New NonTerminal("ThesaurusOperator")
        Dim ExactExpression As New NonTerminal("ExactExpression")
        Dim ParenthesizedExpression As New NonTerminal("ParenthesizedExpression")
        Dim ProximityExpression As New NonTerminal("ProximityExpression")
        Dim ProximityList As New NonTerminal("ProximityList")

        Me.Root = Expression
        Expression.Rule = PrimaryExpression Or BinaryExpression
        BinaryExpression.Rule = Expression + BinaryOp + Expression
        BinaryOp.Rule = ImpliedAnd Or "and" Or "&" Or "-" Or "or" Or "Or"
        PrimaryExpression.Rule = Term Or ThesaurusExpression Or ExactExpression Or ParenthesizedExpression Or Phrase Or ProximityExpression
        ThesaurusExpression.Rule = "~" + Term
        ExactExpression.Rule = "+" + Term Or "+" + Phrase
        ParenthesizedExpression.Rule = "(" + Expression + ")"
        ProximityExpression.Rule = "<" + ProximityList + ">"
        Grammar.MakePlusRule(ProximityList, Term)

        Grammar.CurrentGrammar.MarkTransient(PrimaryExpression, Expression, ProximityExpression, ParenthesizedExpression, BinaryOp)
        Grammar.CurrentGrammar.MarkPunctuation("<", ">", "(", ")")
        Grammar.CurrentGrammar.RegisterOperators(10, "or", "Or")
        Grammar.CurrentGrammar.RegisterOperators(20, "and", "&", "-")
        Grammar.CurrentGrammar.RegisterOperators(20, ImpliedAnd)
        Grammar.CurrentGrammar.LanguageFlags = LanguageFlags.CanRunSample
    End Sub

    'Creates extended identifier terminal that allows international characters
    ' Following the pattern used for c# identifier terminal in TerminalFactory.CreateCSharpIdentifier method
    Function CreateTerm(ByVal name As String) As IdentifierTerminal
        Dim Term As New IdentifierTerminal(name, "!@#$%^*_'.?-", "!@#$%^*_'.?0123456789")

        Dim oUC() As UnicodeCategory = { _
            UnicodeCategory.UppercaseLetter, _
             UnicodeCategory.LowercaseLetter, _
             UnicodeCategory.TitlecaseLetter, _
             UnicodeCategory.ModifierLetter, _
             UnicodeCategory.OtherLetter, _
             UnicodeCategory.LetterNumber, _
             UnicodeCategory.DecimalDigitNumber, _
             UnicodeCategory.ConnectorPunctuation, _
             UnicodeCategory.SpacingCombiningMark, _
             UnicodeCategory.NonSpacingMark, _
             UnicodeCategory.Format}

        Term.CharCategories.AddRange(oUC)

        'StartCharCategories are the same
        Term.StartCharCategories.AddRange(Term.CharCategories)

        CreateTerm = Term
    End Function

    Public Function ConvertStringToFTS(ByVal strSearchString As String) As String
        Dim oGrammer As New SearchGrammar()
        Dim oParser = New Parser(oGrammer)
        Dim oCompiler = New ParsingContext(oParser)
        Dim oParseTree As ParseTree

        oParser.Context.SetOption(ParseOptions.TraceParser, True)
        oParseTree = oParser.Parse(strSearchString, "<source>")

        Dim strFTS As String = ConvertQuery(oParseTree.Root)

        ConvertStringToFTS = strFTS
    End Function

    Public Enum TermType
        Inflectional = 1
        Thesaurus = 2
        Exact = 3
    End Enum

    Public Function ConvertQuery(ByVal node As ParseTreeNode) As String
        ConvertQuery = ConvertQuery(node, TermType.Inflectional)
    End Function

    Private Function ConvertQuery(ByVal node As ParseTreeNode, ByVal type As TermType) As String
        Dim strResult As String = ""

        ' Note that some NonTerminals don't actually get into the AST tree,
        ' because of some Irony's optimizations - punctuation stripping and
        ' transient nodes elimination. For example, ParenthesizedExpression - parentheses
        ' symbols get stripped off as punctuation, and child expression node
        ' (parenthesized content) replaces the parent ParenthesizedExpression node

        Select Case (node.Term.Name)
            Case "BinaryExpression"
                Dim opSym As String = String.Empty
                Dim op As String = node.ChildNodes(1).FindTokenAndGetText().ToLower()
                Dim sqlOp As String = ""

                Select Case op
                    Case "", "&", "and"
                        sqlOp = " AND "
                        type = TermType.Inflectional
                    Case "-"
                        sqlOp = " AND NOT "
                    Case "Or", "or"
                        sqlOp = " OR "
                    Case Else
                        'Do Nothing
                End Select

                strResult = "(" & ConvertQuery(node.ChildNodes(0), type) & sqlOp & ConvertQuery(node.ChildNodes(2), type) + ")"

            Case "PrimaryExpression"
                strResult = "(" & ConvertQuery(node.ChildNodes(0), type) & ")"

            Case "ProximityList"
                Dim tmp(node.ChildNodes.Count) As String

                type = TermType.Exact

                For i As Integer = 0 To node.ChildNodes.Count
                    tmp(i) = ConvertQuery(node.ChildNodes(i), type)
                Next

                strResult = "(" & String.Join(" NEAR ", tmp) & ")"

            Case "Phrase"

                strResult = """" & node.Token.ValueString & """"

            Case "ThesaurusExpression"
                strResult = " FORMSOF (THESAURUS, " & node.ChildNodes(1).Token.ValueString & ") "

            Case "ExactExpression"
                strResult = """" & node.ChildNodes(1).Token.ValueString & """"

            Case "Term"
                Select Case type
                    Case TermType.Inflectional
                        strResult = node.Token.ValueString
                        If (strResult.EndsWith("*")) Then
                            strResult = """" & strResult & """"
                        Else
                            strResult = " FORMSOF (INFLECTIONAL, " & strResult & ") "
                        End If
                    Case TermType.Exact
                        strResult = node.Token.ValueString
                    Case Else
                        'Do Nothing
                End Select
        End Select

        ConvertQuery = strResult

    End Function
End Class

Jun 2, 2010 at 9:05 AM

Cheers mate.. thanks a lot!

 

May 18, 2011 at 4:11 PM

For future reference there are plenty of c# to vb and visa versa converters online

heres one I recommend

http://www.developerfusion.com/tools/convert/csharp-to-vb/