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.