Я пытаюсь создать небольшой синтаксический анализатор, в котором токены (к счастью) никогда не содержат пробелов. Пробелы (пробелы, табуляции и символы новой строки) по сути являются разделителями токенов (за исключением случаев, когда есть скобки и т. Д.).
Я расширяю класс RegexParsers
. Если я включаю skipWhitespace
, синтаксический анализатор жадно объединяет токены, когда следующий токен совпадает с регулярным выражением предыдущего. С другой стороны, если я выключаю skipWhitespace
, он жалуется на то, что пробелы не являются частью определения. Я пытаюсь максимально сопоставить BNF, и, учитывая, что пробел почти всегда является разделителем (кроме скобок или некоторых других случаев, когда разделитель явно определен в BNF), существует далеко, чтобы избежать размещения регулярного выражения с пробелами во всех мои определения?
ОБНОВЛЕНИЕ
Это небольшой тестовый пример, в котором токены соединяются вместе:
import scala.util.parsing.combinator.RegexParsers
object TestParser extends RegexParsers {
def test = "(test" ~> name <~ ")"
def name : Parser[String] = (letter ~ (anyChar*)) ^^ { case first ~ rest => (first :: rest).mkString}
def anyChar = letter | digit | "_".r | "-".r
def letter = """[a-zA-Z]""".r
def digit = """\d""".r
def main(args: Array[String]) {
val s = "(test hello these should not be joined and I should get an error)"
val res = parseAll(test, s)
res match {
case Success(r, n) => println(r)
case Failure(msg, n) => println(msg)
case Error(msg, n) => println(msg)
}
}
}
В приведенном выше случае я просто соединяю струны вместе. Аналогичный эффект произойдет, если я изменю test
на следующее, ожидая, что он выдаст мне список отдельных слов после теста, но вместо этого он объединяет их вместе и просто дает мне список из одного элемента с длинной строкой без пробелов посередине:
def test = "(test" ~> (name+) <~ ")"