私は順序付けられていない方法で単語を解析する必要があります。今のところ私はそれを見ることができますScalaパーサーコンビネータでは、順序付けられていないパーサー
def first: Parser[String] = ???
def second: Parser[String] = ???
def unordered = (first ~ second) | (second ~ first)
しかし、私はそれのためのネイティブな解決策があるのだろうか?
私は順序付けられていない方法で単語を解析する必要があります。今のところ私はそれを見ることができますScalaパーサーコンビネータでは、順序付けられていないパーサー
def first: Parser[String] = ???
def second: Parser[String] = ???
def unordered = (first ~ second) | (second ~ first)
しかし、私はそれのためのネイティブな解決策があるのだろうか?
APIはそれほど大きくありません:https://static.javadoc.io/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.6/scala/util/parsing/combinator/Parsers.html、これを通じて探しhttps://static.javadoc.io/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.6/scala/util/parsing/combinator/Parsers $ Parser.html
、より簡単にこれを行う方法はありません、答えは何ではありません表示されます。しかし、この方法はまったく悪くはないようです。
私はそれは~
trait ExtParsers extends JavaTokenParsers {
def unordered[T,U](tp: Parser[T], tu: Parser[U]): Parser[$[T, U]] =
tp ~ tu ^^ { case (x ~ y) => $(x, y) } | tu ~ tp ^^
{ case (x ~ y) => $(y, x) }
case class $[+a, +b](_1: a, _2: b)
implicit class ExtParser[+T](val parser: Parser[T]) {
def $[U](tu: Parser[U]): Parser[$[T, U]] = unordered(parser, tu)
}
}
object MyParser extends ExtParsers {
def unord: Parser[String] =
(ident $ stringLiteral $ wholeNumber $ floatingPointNumber) ^^ {
case (id $ sl $ wn $ fpn) =>
s"ident=$id string=$sl int=$wn float=$fpn"
}
}
に似ていますし、試験に合格した$
という名前のカスタムパーサーに~
と|
パーサを組み合わせることによって、これを達成:
@Test def test() {
val expected = "ident=value string=\"test\" int=10 float=10.99"
assertEquals(expected,
MyParser.parseAll(MyParser.unord, "value \"test\" 10 10.99").get)
assertEquals(expected,
MyParser.parseAll(MyParser.unord,"\"test\" value 10 10.99").get)
assertEquals(expected,
MyParser.parseAll(MyParser.unord,"10 value \"test\" 10.99").get)
}
うん、それはそうなります。 (現在の解決策については、これらの条件の数が増えると複雑になる可能性があります。 – ikryvorotenko