Just a sample to clarify the issue .. (this is pseudo code)
Classic way: Just make a rule for every path. So starting at "start" and selecting outer_rule1 or outer_rule2 and from there going into inner_rule1 and inner_rule2. You can clearly see that the inner rules are nearly equal. E.g. thing about a grammar where the line special separated is one given by symbol ":" and once given by ";"
inner_rule1 = a >> b >> ":"
inner_rule2 = a >> b >> ";"
outer_rule1 = "X" >> inner_rule1
outer_rule2 = "Z" >> inner_rule2
start=outer_rule1 | outer_rule2
You can overcome this issue by placing the separator on top level
inner_rule1 = a >> b
inner_rule2 = a >> b
outer_rule1 = "X" >> inner_rule1 >> ":"
outer_rule2 = "Z" >> inner_rule2 >> ";"
start=outer_rule1 | outer_rule2
but if the inner rules are more complex the separator maybe used also inside a nested rule and now it becomes tricky to use the same rules but exchange the separator ...
complex_inner1= w >> ";"
complex_inner2= r >> ":"
inner_rule1 = a >> +complex_inner1
inner_rule2 = a >> +complex_inner2
outer_rule1 = "X" >> inner_rule1
outer_rule2 = "Z" >> inner_rule2
start=outer_rule1 | outer_rule2
The question is how to make something like this, in this case e.g. with a custom action but we know that custom actions are not the best choice especially when backtracking is used.
complex_inner1= w >> separator
complex_inner2= r >> separator
inner_rule1 = a[separator=";"] >> +complex_inner1
inner_rule2 = a[separator=":"] >> +complex_inner2
outer_rule1 = "X" >> inner_rule1
outer_rule2 = "Z" >> inner_rule2
start=outer_rule1 | outer_rule2