I'm doing Cay Horstmann's combinator parser exercises, I wonder about the best way to distinguish between strings that represent numbers and strings that represent variables in a match statement:
def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
case a: wholeNumber => Number(a.toInt)
case a: String => Variable(a)
}
The second line there, "case a: wholeNumber" is not legal. I thought about a regexp, but haven't found a way to get it to work with "case".
I would split it up a bit and push the case analysis into the
|
. This is one of the advantages of combinators and really LL(*) parsing in general:I apologize if you're not familiar with the underscore syntax. Basically it just means "substitute the nth parameter to the enclosing function value". Thus
{ Variable(_) }
is equivalent to{ x => Variable(x) }
.Another bit of syntax magic here is the
~>
and<~
operators in place of~
. These operators mean that the parsing of that term should include the syntax of both the parens, but the result should be solely determined by the result ofexpr
. Thus, the"(" ~> expr <~ ")"
matches exactly the same thing as"(" ~ expr ~ ")"
, but it doesn't require the extra case analysis to retrieve the inner result value fromexpr
.