Instead of having /\(((?>[^()]+)|\([^()]*\))+\)/ as in the README, use /\((?>[^()]+|\([^()]*\))+\)/ instead.
The idea is that within a given (?>...)|abc, backtracking is not performed inside any of the alternations in ..., but if the whole group fails, a single backtracking step is still done to match abc. It's simpler to reason about and removes a layer of parentheses. (This also obviously precludes the current x*+/etc. desugaring.)
This would simplify implementation a lot, since you wouldn't have the issue of child expressions causing their parent alternations to continue differently just based on them existing. (Direct code generation from a shift-reduce parser, bypassing the AST, would be a lot more awkward without this change.)
Instead of having
/\(((?>[^()]+)|\([^()]*\))+\)/
as in the README, use/\((?>[^()]+|\([^()]*\))+\)/
instead.The idea is that within a given
(?>...)|abc
, backtracking is not performed inside any of the alternations in...
, but if the whole group fails, a single backtracking step is still done to matchabc
. It's simpler to reason about and removes a layer of parentheses. (This also obviously precludes the currentx*+
/etc. desugaring.)This would simplify implementation a lot, since you wouldn't have the issue of child expressions causing their parent alternations to continue differently just based on them existing. (Direct code generation from a shift-reduce parser, bypassing the AST, would be a lot more awkward without this change.)