Scala combinators - distinguish between numeric strings and variable strings

I am doing parser exercises for Cay Horstmann combinators, I am wondering how best to distinguish between strings representing numbers and strings representing variables in a match expression:

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 was thinking about regex, but could not find a way to make it work with "case".

+6
scala parsing combinators
source share
1 answer

I would split it a bit and drag the case analysis into | . This is one of the advantages of combinators and, in essence, LL (*) parsing:

 def factor: Parser[ExprTree] = ( wholeNumber ^^ { Number(_.toInt) } | "(" ~> expr <~ ")" | ident ^^ { Variable(_) } ) 

I apologize if you are not familiar with the underscore syntax. Basically, it simply means "replace the nth parameter with the value of the enable function." Thus, { Variable(_) } equivalent to { x => Variable(x) } .

Another bit of syntactic magic is the operators ~> and <~ instead of ~ . These operators mean that the parsing of this term should include the syntax of both parameters, but the result should be determined only by the result of expr . Thus, "(" ~> expr <~ ")" matches exactly the same as "(" ~ expr ~ ")" , but an additional case analysis is not required to obtain the internal value of the result from expr .

+6
source share

All Articles