I'm pretty sure it's possible to interpret this selective applicative parsing within the style of LR parsing
(in fact, it may be the most well-behaved setting)
I wrote a bunch about how LR(1) parsing works:
https://cofree.coffee/~verity/parser.html
(as always, there's a bunch more to write)
quick overview is that it builds a graph of state nodes, where each state is a partial parse of some rules and the lookahead that one would expect after parsing that rule (based on how you got to the state)
each step looks at the current token in the stream, and decides to shift the token onto the stack and continue parsing the rules, or reduce a finished rule (if you see its lookahead) and get its arguments off of the stack
conflicts occur when there are multiple actions that one could take from a state on a token: shift/reduce conflicts or reduce/reduce conflicts
I'm pretty sure that the only modification this needs to account for selective parsing is that the actions needed to be pruned based on the logic written into the selects
but there's some technical issues that come up (and functional programming to the rescue!)
the first is that there are multiple rules for each state: each state is juggling several rules (sometimes different parts of the same rule!), and one only whens when the others are filtered out by shifting tokens that they don't have, or when a reduction happens and the lookahead unambiguously points to one rule
the second issue is related: the rules in a state are all hypothetical, they aren't finalized until the reduce happens and the information is popped off of the stack
so if there are applicative and selective operations happening, with their own local variables and logic, we need to be able to simulate that for each rule independently
this would happen by peeking at the stack, running the logic for the partial parses based on the stack, and using it to prune the actions to take to advance the parser
so we really need the logic to be pure! we need to be able to keep a firm grasp on whatever global and local state is floating around, so we can try it out and roll it back and memoize it
