If we add names/labels to the children of productions we can generate stratego getters and setters.
Getters and setters decouple the number of children of a constructor, such that if one adds or removes a child, or changes the order of children the whole stratego codebase does not have to be rewritten.

Proposed syntax:

  Role.Role = [[@type ID][@inv DotID?] [@mult Multiplicity?][@ord Ordering?][@name SpaceArrowID?]]

Would be the equivalent of:

  Role.Role = [[ID][DotID?] [Multiplicity?][Ordering?][SpaceArrowID?]]
  is-role = ?Role(_, _, _, _, _)
  role-get-type = ?Role(<id>, _, _, _, _)
  role-get-inv  = ?Role(_, <id>, _, _, _)
  role-get-mult = ?Role(_, _, <id>, _, _)
  role-get-ord  = ?Role(_, _, _, <id>, _)
  role-get-name = ?Role(_, _, _, _, <id>)
  role-set-type(s) = Role(s, id, id, id, id)
  role-set-inv (s) = Role(id, s, id, id, id)
  role-set-mult(s) = Role(id, id, s, id, id)
  role-set-ord (s) = Role(id, id, id, s, id)
  role-set-name(s) = Role(id, id, id, id, s)

When using the sort (not the constructor name) for these getters and setters this also introduces abstraction:

  Attr.Attribute           = <<@name ID> : <@type Type><@mult Multiplicity?>>
  Attr.DerivationAttribute = <<@name ID> : <@type Type><@mult Multiplicity?> = <@expr Exp>>
  Attr.DefaultAttribute    = <<@name ID> : <@type Type><@mult Multiplicity?> = <@expr Exp> (default)>

The generated getters and setters abstract over the concrete constructors:

  is-attr = ?Attribute(_, _, _)
  is-attr = ?DerivationAttribute(_, _, _, _)
  is-attr = ?DefaultAttribute(_, _, _, _)

  attr-get-name       = ?Attribute(<id>, _, _)
  attr-get-name       = ?DerivationAttribute(<id>, _, _, _)
  attr-get-name       = ?DefaultAttribute(<id>, _, _, _)
  attr-set-mult(s) = Attribute(id, id, s)
  attr-set-mult(s) = DerivationAttribute(id, id, s, id)
  attr-set-mult(s) = DefaultAttribute(id, id, s, id)

(Note: if we add named child access to stratego SDF3 does not have to generate getters and setters. But I have no idea how hard it is to extend Stratego with:

Role : @type ID * @inv Option(DotID) * @mult Option(Multiplicity) * @ord Option(Ordering) * @name Option(SpaceArrowID) -> Role


Any opinions on this improvement?

Submitted by Daco Harkes on 24 October 2016 at 18:40

On 24 October 2016 at 21:21 Eelco Visser commented:

First impression: that makes for ugly (i.e. unreadable) syntax definitions.

Doing it in Stratego should not be so hard, but requires duplicating signatures which are otherwise generated.

But I see that having generated projection functions is useful. So, I would propose to add some sugar: When omitting the projector name, it is derived from the type name, so that you would be able to write this

Name = ID
Attr.Attribute                 = <<Name> : <Type><Multiplicity?>>
Attr.DerivationAttribute = <<Name> : <Type><Multiplicity?> = <Exp>>
Attr.DefaultAttribute      = <<Name> : <Type><Multiplicity?> = <Exp> (default)>

to get the same projections.

Relying on pattern matching would allow to get more compact strategy names:

type = ?Role(<id>, _, _, _, _)  
set-type(s) = Role(s, id, id, id, id)

(You could call it dynamic dispatch.)

On 25 October 2016 at 11:39 Daco Harkes commented:

Good suggestions!

On 23 November 2016 at 15:43 Jeff Smits commented:

Compact strategy names might conflict (i.e. result in obscure bugs) if you have multiple constructors with the same number of children but from different Sorts. :\

On 14 February 2017 at 13:08 Gabriƫl Konat tagged sdf

On 7 March 2017 at 06:35 Guido Wachsmuth commented:

SDF3 already supports labeled children in productions. It inherited this feature from SDF2. This is valid SDF3:

Role.Role = [[type:ID][inv:DotID?] [mult:Multiplicity?][ord:Ordering?][name:SpaceArrowID?]]

The syntax highlighting uses a light grey for labels, making it less invasive. I actually think this kind of highlighting would be useful for other distractions as well.

Log in to post comments