Разбивая парсер комбинаторы шаг за шагом - PullRequest
0 голосов
/ 22 сентября 2019

У меня есть строка, которая выглядит следующим образом

val input = "abc | (def & ghi) & jkl"

Я хочу разобрать это в

List("abc", "def", "ghi", "jkl")

Я написал следующий класс синтаксического анализатора

import scala.util.parsing.combinator._
class MyParser extends RegexParsers {
  override val skipWhitespace = true
  val simpleValue : Parser[String] = "[^|&!()]+".r // match anything except a blank space, and, or or brackets
  val value : Parser[List[String]] = simpleValue ~ rep("|" ~ value | "&" ~ value) ^^ {case a ~ list => List(a) ++ list.flatMap{case _ ~ l => l}} | "(" ~ value ~ ")" ^^ {case _ ~ a ~ _ => a}
}

По мне так работает эта программа.анализатор запускается и находит символы abc, он может легко сопоставить это с simpleValue.Тогда он игнорирует пустое пространство.Теперь он встречает | Это соответствует этому с rep("|" ~ value).Это войдет в рекурсию.

Внутри рекурсии.он совпадает с "(" с "(" ~ value ~ ")" Он снова входит в рекурсию.

Теперь он может сопоставлять "def" и "ghi" с simpleValue и выходить из 2-й рекурсии с List(def, ghi). Теперь это счетчики ") "так это выходит из 1-й рекурсии.

Здесь он объединит List (abc) со списком (def, ghi)

Теперь он встретит "&" и сопоставит его с rep("&" ~ value).

Вот этоснова идет в рекурсию, последний токен jkl легко сопоставляется с simpleValue.Это

Он должен выйти из рекурсии со значением List (jkl) и объединить его с List (abc, def, ghi, jkl).И мы должны завершить программу.

Однако она не работает с ошибкой

Failure("`&' expected but `(' found", scala.util.parsing.input.CharSequenceReader@10c299b3)

Что не так с моим взглядом на этот код?

...