Scala парсер комбинаторы: извлечение исходной строки, использованной парсером - PullRequest
2 голосов
/ 02 февраля 2012

Итак, у меня есть несколько таких парсеров:

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
}

Более высокая цель препроцессора состоит в том, чтобы пройти и преобразовать блоки с отступом в блоки с фигурными скобками, чтобы позже я мог запустить предварительно обработанный файл через обычный синтаксический анализатор.Есть ли простой способ сделать это?

...