Комбинатор синтаксического анализатора Scala reduce / foldLeft

Я пытаюсь сделать следующее из динамически заполняемого списка:

val primitives = "x" | "y" | "z" // what I want

val primitives2 = List("x", "y", "z") // what I need to transform from

Я подумал, что может сработать что-то вроде этого:

primitives2.reduce(_|_)

Но не пошло. Затем я нашел этот фрагмент, который работает:

primitives2.foldRight(failure("no matching delimiter"): Parser[Any])(_|_)

Однако базовый случай failure("no matching delimiter") сбивает с толку. Это просто эквивалент Nil для объектов Parser?


person Dominic Bou-Samra    schedule 19.01.2013    source источник


Ответы (1)


Я предполагаю, что вы работаете с RegexParsers или одним из его потомков. Если так, то проблема в том, что неявное преобразование из String в Parser[String] не сработает автоматически с reduce(_ | _). Если вы сначала явно конвертируете каждый элемент в своем списке, например:

val anyPrimitive = primitives2.map(literal).reduce(_ | _)

Все будет в порядке, за исключением того, что это приведет к появлению немного сбивающих с толку сообщений об ошибках, например:

scala> parser.parseAll(parser.anyPrimitive, "a")
res8: parser.ParseResult[Any] = 
[1.1] failure: `z' expected but `a' found

a
^

Если вам нужно более четкое сообщение об ошибке, вам нужно будет указать собственное начальное значение, используя подход fold.

person Travis Brown    schedule 19.01.2013