I tried this
import scala.util.parsing.combinator._
def name = ident ^^ {case ident => if (ident.contains("a")) ident.toUpperCase else ident
println(parseAll(name, "aa")) // parsed: AA
println(parseAll(name, "bb"))
with output
[1.3] parsed: AA
[1.3] parsed: bb
[1.1] failure: `(' expected but `a' found
aa
^
[1.3] failure: end of input expected
f1(aa)
^
As you see, second parsing fails. It seems that failure in the first production stops from trying the second alternative. I actually want depending on the value of first indentifier to choose this or that parser to continue.
It can be done returning
Failure, which will pass the ball to the subsequent alternative (do not confuseFailurewithfailure. The second will stop the parsing)This enables the real semantic dispatching of the productions
Here names are parsed. Parser first tries an identifier. It semantically checks if the identifier is known in the context as function or package. If it does not, it falls back to simple identifier parser. This is stupid but this is what I asked for. The demo parsing is
The errors are expected:
f1is the only defined function andaais not one of them. Therefore, it is consumed as identifier, leaving(b)unconsumed. Similarly,ccis consumed as simple identifier because it is not a defined package.