解析器组合器中的非常典型的结构重复

时间:2013-05-31 21:30:32

标签: scala parser-combinators

在解析一些复杂的文本时,我需要为了重用和可读性的原因拆分正则表达式定义,我似乎经常最终得到这种通用结构的Scala代码(pn - 一个正则表达式模式,{ {1}}变量):

vn

显而易见的问题是代码的可读性和可维护性,因为需要插入新模式,因为有用匹配(val cp1 = p1 ~ p2 ~ p3 ~ p4 ~ p5 ~ p6 ^^ case { dummy1 ~ v2 ~ dummy3 ~ v4 ~ dummy5 ~ v6 => ACaseClass(v2, v4, v6) } )与占位符(vn)分开。

那么,是否有更简洁的方式表达意图?我可以使用dummyn来代替每个_吗?

在SNOBOL语言中,可以编写dummyn(pat . var),将匹配结果分配给变量;同样,在最新的正则表达式语法中,我们将捕获组命名为(pat $ var)。目的很明显是将匹配捕获变量保持在模式附近。

所以,我想写的内容是:

(?P<name>pat)

显然,我假设某种新的运算符val cp1 = p1 ~ ( p2 $$ v2 ) ~ p3 ~ ( p4 $$ v4 ) ~ p5 ~ ( p6 $$ v6 ) $=> ACaseClass(v2, v4, v6) $$可以实现这种更简单的语法。

可以想象宏可以提供帮助,但目前它们已经超出了我的能力范围。欢迎任何投入!

1 个答案:

答案 0 :(得分:2)

为什么不尝试使用_?事实证明它有效。此外,您可以使用~><~来丢弃图案的某些部分,但如果您想丢弃内部部件,则需要使用括号。

object SimpleScala extends JavaTokenParsers {

  def test = "(" ~> wholeNumber ~ ("," ~> wholeNumber <~ ",") ~ wholeNumber <~ ")" ^^ 
    { case i1 ~ i2 ~ i3 => (i1,i2,i3) }

  def test2 = "(" ~ wholeNumber ~ "," ~ wholeNumber ~ ")" ^^ 
    { case _ ~ i1 ~ _ ~i2 ~ _ => (i1,i2) }

  def main(args: Array[String]){
    println(parseAll(test,"(42,34,5)"))
    println(parseAll(test2,"(42,345)"))
  }
}