Roberto Bonvallet Roberto Bonvallet - 9 months ago 53
Scala Question

Reuse parser within another parser with Scala parser combinators

I have a parser for arithmetic expressions:

object FormulaParser extends JavaTokenParsers {
def apply(input: String) = parseAll(formula, input)
// ...

val formula: Parser[Formula] =
comparison | comparable | concatenable | term | factor

I need to parse a different language that can contain formulas. Let's say I need to parse something like
X < formula
. Unfortunately I cannot reuse
in my new parser:

object ConditionParser extends JavaTokenParsers {
def apply(input: String) = parseAll(condition, input)
// ...

val condition: Parser[Condition] =
"X" ~ ("<=" | "<") ~ FormulaParser.formula ^^ { ... } // doesn't work

because the parser on the left-hand side of
is an instance of
, so its
method expects something with that same type, not something of type

The whole point of using parser combinators is, well, combining parsers! It seems silly to me that my first attempt didn't work, although I understand why it happens (we are reusing base parsers by extending a base trait).

Is there a simple way to combine parsers defined in different types?

Answer Source

In order to reuse parsers, you need to use inheritance. So if you make FormulaParsers a class or a trait, ConditionParser can inherit from it and reuse its parsers.

This is also how you're already reusing the parsers defined in JavaTokenParsers.