Как обеспечить указание токена c в конце последовательности в комбинаторах синтаксического анализатора? - PullRequest
0 голосов
/ 07 августа 2020

В этом упрощенном примере мне нужно убедиться, что последний элемент в последовательности - « я » (что означает « в M в режиме ожидания или E nd"). Однако в последовательности также есть « m » (что означает «только в M iddle»). Проблема, похоже, в том, что парсер rep1sep жадный и не допускает возврата. Есть ли оператор, похожий на "|||" что позволит это?

пс. Здесь это не актуально, но оба токена также могут появляться в начале (просто чтобы явно указать на злоупотребление термином «средний»).

ps2. Это не должно быть решено с помощью регулярного выражения; как и в большинстве вопросов, это просто чрезмерное упрощение проблемы, которую собираются решить комбинаторы.

import scala.util.parsing.combinator.{JavaTokenParsers, PackratParsers}
import scala.util.parsing.input.CharSequenceReader

object Test extends JavaTokenParsers with PackratParsers {
  type P[+T] = PackratParser[T]
  private val program = rep1sep("me" | "m", ";") ~ (";" ~> not("m") ~> "me") ^^ {
    case l ~ r => l :+ r 
  }

  def run() {
    val txt2 = "m ;me; me; m; me"
    val chars = new CharSequenceReader(txt2)
    lazy val r = parseAll(phrase(program), new PackratReader(chars))
    println(r)
  }
}

Test.run()
// [1.17] failure: ';' expected but end of source found
...