如何以未指定的顺序解析属性集?

时间:2013-03-08 20:03:31

标签: parsing scala

我有一个处理自定义属性文件的Regex解析器。在我的文件中,我有以下结构:

...
[NodeA]
propA=val1
propB=val2
propC=val3

[NodeB]
...

我定义了一个解析NodeA的解析器,如下所示:

lazy val parserA: Parser[String] = "propA" ~> "=" ~> mPropA 
lazy val parserB: Parser[String] =  
...

lazy val nodeA: Parser[NodeA] = "[" ~> "NodeA" ~> "]" ~> parserA ~> parserB ~> parserB ^^ { 
   case iPropA ~ iPropB ~ iPropC => new NodeA(iPropA, iPropB, iPropC)
}

这样可以正常工作。问题是如果NodeA带有不同的属性顺序,在这种情况下我得到一个解析错误。例如:

[NodeA]
propC=val3
propA=val1
propB=val2

有没有办法定义我的解析器,以便接受NodeA属性的未指定顺序?

1 个答案:

答案 0 :(得分:2)

我仍然感觉不理解你的问题,但是:

import scala.util.parsing.combinator.JavaTokenParsers

object Test extends App with JavaTokenParsers {

  case class Prop(name: String, value: String)
  case class Node(name: String, propA: Prop, propB: Prop, propC: Prop)

  lazy val prop = (ident <~ "=") ~ ident ^^ {
    case p ~ v => (p, v)
  }

  lazy val node = "[" ~> ident <~ "]"

  lazy val props = repN(3, prop) ^^ {
    _.sorted map Prop.tupled
  }

  lazy val nodes = rep(node ~ props) ^^ {
    _ map { case node ~ List(a, b, c) => Node(node, a, b, c) }
  }

  val in =
"""[NodeA]
propA=val1
propB=val2
propC=val3

[NodeB]
propC=val3
propA=val1
propB=val2"""

  println(parseAll(nodes, in))
}