Итак, у меня есть несколько таких парсеров:
object MyParser extends RegexParsers{
override val skipWhitespace = false
def blockLine = ((id ~ args) <~ ":") ~ ".*?".r ^^ {
case (blockID ~ argList) ~ rest => ???
}
def args = (("[" ~> rep1sep(arg, ", ") <~ "]")?) ^^ {
case Some(argList) =>
argList.zipWithIndex.map{
case ((Some(k), v), index) => k -> v
case ((None, v), index) => "arg" + index -> v
}
case None => List()
}
def arg = ((id <~ "=")?) ~ argtext ^^ {
case Some(name) ~ value => Some(name) -> value.toString()
case None ~ value=> None -> value
}
def argtext = "[^\\[\\],]+".r
def id = "[a-zA-Z]*".r
... many other parsers not shown...
}
По сути, я хочу повторно использовать парсеры id
и args
в blockLine
, но вместо того, чтобы получить вложенное дерево List()
s и ~
s, я хочу вернуть исходную строку, которая была сопоставлена.Цель этого состоит в том, чтобы сделать некоторую умную предварительную обработку текста (используя те же парсеры, которые я буду использовать позже для фактического анализа), чтобы вставить некоторый текст в середину строки.Что-то вроде:
def blockLine = (rawText(id ~ args) <~ ":") ~ ".*?".r ^^ {
case first ~ rest => first + "{" + rest
}
Более высокая цель препроцессора состоит в том, чтобы пройти и преобразовать блоки с отступом в блоки с фигурными скобками, чтобы позже я мог запустить предварительно обработанный файл через обычный синтаксический анализатор.Есть ли простой способ сделать это?