I'm trying to parse an entity and the entities that make up that entity's fields using Scala parser combinators. I'd like to do this by having each sub entity know how to parse itself.
My problem can be reproduced by a Person
class that has an Address
and a Car
. Here's what the Address
and Car
classes look like and how they're parsed.
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);
}
}
Where I run into problems is when I try to combine the parsers to parse 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);
}
}
The compiler error that I get is this:
[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] ^
How can I combine the two parsers into a parser that can parse a complete Person
object?