问题
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 FormulaParser.formula
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 ConditionParser.Parser
, so its ~
method expects something with that same type, not something of type FormulaParser.Parser
.
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?
回答1:
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
.
来源:https://stackoverflow.com/questions/40166258/reuse-parser-within-another-parser-with-scala-parser-combinators