所以我有一堆这样的解析器:
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
in blockLine
,而不是获取List()
s 和~
s 的嵌套树,我想取回匹配的原始字符串。这样做的目的是进行一些智能文本预处理(使用我稍后将用于实际解析的相同解析器)以在行中间插入一些文本。就像是:
def blockLine = (rawText(id ~ args) <~ ":") ~ ".*?".r ^^ {
case first ~ rest => first + "{" + rest
}
预处理器的更高目的是通过并将缩进分隔的块转换为花括号分隔的块,以便稍后我可以通过普通解析器运行预处理文件。有什么简单的方法可以做到这一点?