В этой строке здесь:
lazy val name: Parser[Name] =
lastName <~ "," ~> firstName ^^ {case (l ~ f) => Name(f, l)}
вы не хотите использовать <~
и ~>
. Вы создаете парсер, который соответствует ","
и firstName
и сохраняет только ","
, а затем вы создаете парсер, который соответствует lastName
и предыдущему парсеру и сохраняет только lastName
.
Вы можете заменить его следующим:
(lastName <~ ",") ~ firstName ^^ {case (l ~ f) => Name(f, l)}
Однако, хотя это скомпилирует и объединит так, как вы хотите, оно не будет анализировать то, что вы хотите. Я получил этот вывод, когда я пытался:
[1.1] failure: string matching regex `"([^"\p{Cntrl}\\]|\\[\\/bfnrt]|\\u[a-fA-F0-9]{4})*"' expected but `S' found
Schmo, Joe
^
stringLiteral
ожидает что-то похожее на строковый литерал в коде (что-то в кавычках). (JavaTokenParsers
предназначен для разбора содержимого, похожего на Java.) Это работает:
scala> val x = new NameParser
x: NameParser = NameParser@1ea8dbd
scala> x.parseAll(x.name, "\"Schmo\", \"Joe\"")
res0: x.ParseResult[Name] = [1.15] parsed: Name("Joe","Schmo")
Вам, вероятно, следует заменить его регулярным выражением, которое указывает, какие строки вы будете принимать для имен. Если вы посмотрите документацию здесь , вы увидите:
implicit def regex (r: Regex) : Parser[String]
A parser that matches a regex string
Таким образом, вы можете просто поместить туда объект Regex
, и он будет преобразован в синтаксический анализатор, соответствующий ему.