I've mastered this syntax for building a left-associative tree for infix operators:
term * (
"+" ^^^ { (a:Expr, b:Expr) => new FunctionCall(plus, a::b::Nil) } |
"-" ^^^ { (a:Expr, b:Expr) => new FunctionCall(minus, a::b::Nil) } )
Though I have to confess I don't fully understand how it works. What I want to do now is to achieve a similar effect for syntax that might look like
a[b](c)(d)[e]
which should parse as
sub(call(call(sub(a, b), c), d), e)
Can the high-level "^^^" magic be extended to cover a case where it's not a pure infix operator? Or do I have to implement some kind of fold-left logic myself? If so, any hints as to what it might look like?
I have solved the problem as follows. I'm happy with the solution, but if any Scala experts out there can help me improve it, that's very welcome.
def subscript: Parser[Expr => Expr] = {
"[" ~> expr <~ "]" ^^ {
case sub => {
{ (base: Expr) => new FunctionCall(subscriptFn, base :: sub :: Nil)}
}
}
}
def argumentList: Parser[Expr => Expr] = {
"(" ~> repsep(expr, ",") <~ ")" ^^ {
case args => {
{ (base: Expr) => new FunctionCall(base :: args)}
}
}
}
def postfixExpr: Parser[Expr] = {
primary ~ rep ( subscript | argumentList ) ^^ {
case base ~ suffixes => {
(base /: suffixes)((b:Expr, f:Expr=>Expr) => f(b))
}
}
}