1

私は次のテストを持っています。そしてクラス。今、私はルールを書く方法を見つける必要があります、そしてそれはとても単純に見えました;-)。しかし、私はどこにも速く行きません。タグが言うように、私はこれのために子豚を使って学びたいです。

Public Class Plant
    Public Property Genus As String
    Public Property Species As String
    Public Property SubSpecies As String
    Public Property IsHybrid As Boolean
End Class

Public Class ParserTests
    <Test>
    Public Sub IfGenusCanBeFoundWhenOnlyGenusAndSpiecesAreThere()
        Dim parser = New ParseLatinPlantName
        Dim result = parser.Parse("Salvia sylvatica")
        Assert.AreEqual("Salvia", result.Genus)
    End Sub

    <Test>
    Public Sub IfSpeciesCanBeFoundWhenOnlyGenusAndSpiecesAreThere()
        Dim parser = New ParseLatinPlantName
        Dim result = parser.Parse("Salvia sylvatica")
        Assert.AreEqual("sylvatica", result.Species)
    End Sub

    <Test>
    Public Sub IfSubSpeciesCanBeFoundWhenSubSpeciesIsProvided()
        Dim parser = New ParseLatinPlantName
        Dim result = parser.Parse("Salvia sylvatica sp. crimsonii")
        Assert.AreEqual("crimsonii", result.SubSpecies)
    End Sub

    <Test>
    Public Sub IfIsHybridIsTrueWhenxIsInNameCanBeFoundWhenSubSpeciesIsProvided()
        Dim parser = New ParseLatinPlantName
        Dim result = parser.Parse("Salvia x jamensis")
        Assert.IsTrue(result.IsHybrid)
    End Sub

End Class

そして、これが私がこれまでに試したことです。

Public Class ParseLatinPlantName

        Public Function Parse(ByVal name As String) As Plant
            Dim config = ParserFactory.Fluent()
            Dim expr = config.Rule()
            Dim name1 = config.Expression()
            name1.ThatMatches("[a-z]+").AndReturns(Function(f) f)

            Dim space1 = config.Expression()
            space1.ThatMatches(" ").AndReturns(Function(f) f)

            expr.IsMadeUp.By(name).As("Genus").Followed.By(name).As("Species").WhenFound(Function(f) New Plant With {.Genus = f.Genus})

            Dim parser = config.CreateParser()
            Dim result = DirectCast(parser.Parse(name), Plant)
            Return result
        End Function
    End Class

アップデート

Randompunterのおかげで、最初の2つのテストに合格しました。

Public Class ParseLatinPlantName

        Public Function Parse(ByVal name As String) As Plant
            Dim config = ParserFactory.Fluent()
            Dim expr = config.Rule()
            Dim name1 = config.Expression()
            name1.ThatMatches("\w+").AndReturns(Function(f) f)

            expr.IsMadeUp.By(name1).As("Genus") _
                    .Followed.By(name1).As("Species") _
                    .WhenFound(Function(f) New Plant With {.Genus = f.Genus, .Species = f.Species})

            Dim parser = config.CreateParser()
            Dim result = DirectCast(parser.Parse(name), Plant)
            Return result
        End Function
    End Class
4

1 に答える 1

4

まず、オリジナル(その後、修正された式は小文字のみに一致しました)。\w+これは、他の文字と一致するものに変更することで修正されました。

文法で次の2文字を超える文字が許可されていないため、2番目の2つのテストは失敗しました。これを機能させるには、ルールを追加する必要があります。

たとえば、亜種が提供されている例があります。これが.spxxxが渡すオプションのものである形式をとると仮定すると、これには別のルールを提供する必要があります。

これは、オプションの亜種のテストに合格します

Public Class ParseLatinPlantName

    Public Function Parse(ByVal name As String) As Plant
        Dim config = ParserFactory.Fluent()
        Dim expr = config.Rule()
        Dim subSpecies = config.Rule()
        Dim sp = config.Expression()
        sp.ThatMatches("sp\.").AndReturns(Function(f) f)
        Dim name1 = config.Expression()
        name1.ThatMatches("\w+").AndReturns(Function(f) f)
        Dim nothing1 = config.Rule()


        expr.IsMadeUp.By(name1).As("Genus") _
                .Followed.By(name1).As("Species") _
                .Followed.By(subSpecies).As("Subspecies") _
                .WhenFound(Function(f) New Plant With {.Genus = f.Genus, .Species = f.Species, .SubSpecies = f.Subspecies})
        subSpecies.IsMadeUp.By(sp).Followed.By(name1).As("Subspecies").WhenFound(Function(f) f.Subspecies) _
            .Or.By(nothing1)

        Dim parser = config.CreateParser()
        Dim result = DirectCast(parser.Parse(name), Plant)
        Return result
    End Function
End Class

すみません、おそらく非常に粗雑なVBです。それは何年も前のことです。「sp」に明示的に一致する式があることに注意してください。他の種類の名前と区別するため。このルールは、何にも一致しない別のルールとも一致します。これにより、亜種の部分をオプションにすることができます。

ハイブリッドルールから何を解析したいかわかりません。名前の後にxが続き、その後に他の名前が続くものでなければならないと思います。そうすれば、ハイブリッドになります。これに一致させるには、パーサーに別のルールを追加します。

次のパーサーは、すべてのテストに合格します。

Public Class ParseLatinPlantName

    Public Function Parse(ByVal name As String) As Plant
        Dim config = ParserFactory.Fluent()
        Dim expr = config.Rule()
        Dim subSpecies = config.Rule()
        Dim hybridIndicator = config.Expression
        hybridIndicator.ThatMatches("x").AndReturns(Function(f) f)

        Dim sp = config.Expression()
        sp.ThatMatches("sp\.").AndReturns(Function(f) f)
        Dim name1 = config.Expression()
        name1.ThatMatches("\w+").AndReturns(Function(f) f)
        Dim nothing1 = config.Rule()


        expr.IsMadeUp.By(name1).As("Genus") _
                .Followed.By(name1).As("Species") _
                .Followed.By(subSpecies).As("Subspecies") _
                .WhenFound(Function(f) New Plant With {.Genus = f.Genus, .Species = f.Species, .SubSpecies = f.Subspecies}) _
                .Or.By(name1).As("FirstSpecies").Followed.By(hybridIndicator).Followed.By(name1).As("SecondSpecies") _
                .WhenFound(Function(f) New Plant With {.IsHybrid = True})

        subSpecies.IsMadeUp.By(sp).Followed.By(name1).As("Subspecies").WhenFound(Function(f) f.Subspecies) _
            .Or.By(nothing1)

        Dim parser = config.CreateParser()
        Dim result = DirectCast(parser.Parse(name), Plant)
        Return result
    End Function
End Class

重複する式は、優先順位に従って宣言することが重要です。名前として認識されるname1hybridIndicatorに宣言すると、解析が失敗します。xまた、おそらくお気づきかもしれませんが、Pigletはデフォルトで空白を無視するため、ルールを作成する必要はありません。この設定が望ましくない場合は、コンフィギュレーターでオフにするオプションがあります。(Ignoreメソッドを使用します)

于 2012-10-23T13:35:22.970 に答える