Current the priorities system requires one to duplicate their rules into the priorities list, which is error prone and requires one to always update rules in two places or some weirdness ensues.

One solution would be to assign a symbolic priority name to each rule, and define the relations between these rules.

For example:

context-free syntax
  "(" E ")" -> E{brackets}
  E "*" E -> E{cons("Mul"),pri(p),left}
  E "/" E -> E{cons("Div"),pri(p),left}
  E "%" E -> E{cons("Mod"),pri(p),left}
  E "+" E -> E{cons("Sum"),pri(s),left}
  E "-" E -> E{cons("Sub"),pri(s),left}
  E "and" E -> E{cons("Or"),pri(a),left}
  E "or" E -> E{cons("Or"),pri(o),left}

context-free priorities
  p > s > a > o

Note:

  1. I ran into this approach in using Dypgen, a GLR parser for Ocaml. Dypgen has a slightly more flexible way of using priorities because you can specify for any reference to a term, a restriction on the priority of that term. This allows one to specify left associativity by saying the left term may have priority >= the current term but the right term must have priority > the current term. You can read more about it in the dypgen documentation if you are curious. Switching to that approach for priorities isn’t my suggestion here, just symbolic priority names so I don’t have to repeat those rules all the time.
  2. The weirdness that ensues is that the rule defined in the priorities is still added to the system, but with no “cons” name, causing strange looking ambiguities or unexpected anonymous AST nodes to show up.
Submitted by Dobes Vandermeer on 16 October 2012 at 06:13

On 16 October 2012 at 06:15 Dobes Vandermeer commented:

See also https://yellowgrass.org/issue/Spoofax/251 which comments on the fact you aren’t warned if you don’t keep your rules and priorities in sync. This approach may allow one to more easily report an error if a priority symbol is used but not defined, or defined but not used.


On 16 October 2012 at 07:51 maartje commented:

Tobi Vollebregt did something similar in TemplateLang. Below a small example fragment:


templates
Exp.Plus = <<Exp> + > {left}
Exp.Times = <<Exp> * > {left}

context-free priorities
Exp.Times >
Exp.Plus


On 13 November 2012 at 13:16 Maartje tagged sdf

Log in to post comments