如何使用Scala解析器组合器解析分层实体

时间:2015-03-21 23:40:46

标签: scala parsing

我尝试使用Scala解析器组合解析实体和构成该实体字段的实体。我希望让每个子实体知道如何解析自己。

我的问题可由具有PersonAddress的{​​{1}}类重现。以下是CarAddress类的外观以及它们如何解析。

Car

当我遇到问题时,我尝试将解析器组合起来解析import scala.util.parsing.combinator._ case class Address(val street: String, val postCode: String) { } object Address extends JavaTokenParsers { def parse: Parser[Address] = (streetPattern ~ postCodePattern) ^^ { case street ~ postCode => Address(street, postCode) } } case class Car(val make: String, val model: String) { } object Car extends JavaTokenParsers { def parse: Parser[Car] = (stringLiteral ~ ":" ~ stringLiteral) ^^ { case make ~ ":" ~ model => Car(make, model); } }

Person

我得到的编译器错误是这样的:

case class Person(val address: Address, val car: Car) {

}

object Person extends JavaTokenParsers {

  def parse: Parser[Person] = (Address.parse ~ Car.parse) ^^ {
    case address ~ car => Person(address, car);
  }

}

如何将两个解析器组合成一个可以解析完整[error] Parser.scala:38: type mismatch; [error] found : Car.Parser[Car] [error] required: Address.Parser[?] [error] def parse: Parser[Person] = (Address.parse ~ Car.parse) ^^ { [error] ^ [error] Parser.scala:39: type mismatch; [error] found : Any [error] required: Address [error] case address ~ car => Person(address, car); [error] ^ [error] Parser.scala:39: type mismatch; [error] found : Any [error] required: Car [error] case address ~ car => Person(address, car); [error] ^ 对象的解析器?

1 个答案:

答案 0 :(得分:1)

为了合并Parser,他们需要具有相同的type Elem定义。当AddressCarPerson个伴随对象与JavaTokenParsers分开扩展时,编译器无法推断出它们都是相同的类型,因为它们将具有不同的实例Elem

尝试将所有解析器放在同一个伴随对象下,如:

object Person extends JavaTokenParsers {
  def address: Parser[Address] = (streetPattern ~ postCodePattern) ^^ {
    case street ~ postCode => Address(street, postCode)
  }

  def car: Parser[Car] = (stringLiteral ~ ":" ~ stringLiteral) ^^ {
    case make ~ ":" ~ model => Car(make, model)
  }

  def parse: Parser[Person] = address ~ car ^^ {
    case a ~ c => Person(a, c)
  }
}