igordejanovic / parglare

A pure Python LR/GLR parser - http://www.igordejanovic.net/parglare/
MIT License
135 stars 32 forks source link

Better shift-reduce disambiguation #48

Open igordejanovic opened 6 years ago

igordejanovic commented 6 years ago

Currently there are shift/right, reduce/left disambiguators you can use per production to resolve conflicts during LALR table calculation.

Sometimes it is useful to better specify in which context these disambiguators should be used.

If shift is given, then when the parser sees the production it will choose to shift instead of reduce for any lookahead token. Better control could be achieved if shift could be given one or more lookahead tokens for which it should be used.

Something like:

MyProduction: some terms and non-terms {shift(term1, term2), reduce};

In this case, resolution would be reduce for all tokens except term1 and term2.

igordejanovic commented 6 years ago

Maybe this could be unified with #42 so that the same syntax would be used.

MyProduction: some terms and non-terms {>term1, >term2, shift};

>term1 would mean that this production should be reduced if lookahead is term1. shift as default could be implied if > is used. In the case of non-terminals definition this would enhance static disambiguation during LR table calculation, while for terminal definition it would be used dynamically.

This could be used to resolve reduce-reduce conflicts like:

MyProduction: .... {>SomeOtherNonTerminalRule};

This could mean that in case of R/R conflict with SomeOtherProduction, MyProduction reduction would take place. This should be defined per production and with lookahead so the full syntax would be:

MyProduction: .... {>SomeOtherNonTerminalRule[3]:term1};

Where SomeOtherNonTerminalRule[3]:term1 is the third production defined in the rule SomeOtherNonTerminalRule when lookahead is term1. Production index as well as lookahead may be optional. If not specified it would mean any.