我需要以无序的方式解析单词。现在我可以看到以下
def first: Parser[String] = ???
def second: Parser[String] = ???
def unordered = (first ~ second) | (second ~ first)
但我想知道是否有任何原生解决方案?
答案 0 :(得分:2)
我通过将~
和|
解析器合并到名为$
看起来类似于~
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)
}
答案 1 :(得分:1)
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
仔细观察,似乎答案是没有,没有办法更简单地做到这一点。但这种方式看起来并不坏。