Parsey
Parsey copied to clipboard
Is it possible to completely backtrack after `suffixed(by:)`?
Let's say I have two parsers, one for call expressions, and one for subscript expressions:
static let callExpr = atom.suffixed(by: "(" ~~> callArgs <~~ ")")
static let callArgs =
(callArg.many(separatedBy: comma) <~~ comma.?).?
^^^ { (args, loc) in
return { CallExpr(callee: $0, arguments: args ?? [], location: loc) as Node }
}
static let subscriptExpr = atom.suffixed(by: "[" ~~> subscriptArgs <~~ "]")
static let subscriptArgs =
callArg.many(separatedBy: comma) <~~ comma.?
^^^ { (args, loc) in
return { SubscriptExpr(callee: $0, arguments: args, location: loc) as Node }
}
static let atom = ident | literal | "(" ~~> expr <~~ ")"
static let expr = callExpr | subscriptExpr | atom
Both those parsers can successfully parse things like f(1, 2)
and m[0, 8]
respectively. My problem is to find a way to combine them in the expr
parser.
The way I presented it above, the expr
parser can no longer parse subscript expressions. It first tries to parse a call expression, successfully parsing the callee but then failing to parse the arguments. And because it doesn't backtrack until before the callee, it is left with an input of the form [0, 8]
, which can't be parsed by the remaining parsers.
Maybe I could create a function Parser<(Node) -> Node>
, that could choose between call and subscript expressions and I'd be left with a single atom.suffixed(by ...)
parser. But this solution seems rather complex and difficult to maintain if I add things like dot and suffix expressions later on.
I guess the best would be if I could somehow tell the expr
parser to completely backtrack after any of its options failed.
Sorry, I totally missed this issue earlier. Do you still need help on this?
I ended up using a completely different approach (see here) consisting of parsing "trailer" expressions. There are comments in the code.
The suffixed(by:)
approach looks more elegant though. So if there's a better way to parse the kind of expressions I was referring to, I might be interested to modify my implementation.