Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Respect Your Parents: How Attribution and Rewriting Can Get Along

61f8010a7249d7ec93e197e96999fe6c?s=47 Tony Sloane
September 29, 2014

Respect Your Parents: How Attribution and Rewriting Can Get Along

Talk from Software Language Engineering Conference (SLE 2014).

61f8010a7249d7ec93e197e96999fe6c?s=128

Tony Sloane

September 29, 2014
Tweet

Transcript

  1. Respect Your Parents: How Attribution and Rewriting Can Get Along

    Anthony M. Sloane Matthew Roberts Leonard G. C. Hamey Programming Languages Research Group Department of Computing Macquarie University Anthony.Sloane@mq.edu.au @inkytonik 1 / 24
  2. Can Attribution and Rewriting Get Along? Attribution: decorating Tree A

    many attributes need to consider nodes in context Rewriting: transforming tree A into tree B it is common to share nodes between trees Problem: if a node is shared between Tree A and Tree B, what is its context? 2 / 24
  3. Tree A Plus Plus Num 1 Num 2 Plus Num

    3 Num 4 (1 + 2) + (3 + 4) Top 3 / 24
  4. Rewrite Tree A into Tree B Plus Plus Num 1

    Num 2 Plus Num 3 Num 5 0 + (1 + 2) + (3 + 5) Top Plus Num 0 4 / 24
  5. Both Trees Plus Plus Num 1 Num 2 Plus Num

    3 Num 5 Top Plus Num 0 Num 4 Plus Plus Top 5 / 24
  6. Node Height Plus Plus Num 1 Num 2 Plus Num

    3 Num 5 Top Plus Num 0 Num 4 Plus Plus Top 0 0 0 0 0 1 1 1 2 3 0 2 6 / 24
  7. Height Attribute 7 / 24

  8. Node Depth Plus Plus Num 1 Num 2 Plus Num

    3 Num 5 Top Plus Num 0 Num 4 Plus Plus Top 2 2 2 2 3 1 1 2 1 0 1 0 2 3 3 3 8 / 24
  9. Depth Attribute 9 / 24

  10. Solution Relations General mechanism for representing binary relations Trees Bundle

    root with the relations defined by reachability child, parent, siblings, prev, next, . . . Attribute families Context-dependent attributes are families, indexed by a tree Family definitions use the tree relations to access the context 10 / 24
  11. Relations class Relation[T,U] (val graph : Seq[(T,U)]) { def domain

    : Seq[T] def range : Seq[U] def image (t : T) : Seq[U] def preimage (u : U) : Seq[T] def invert : Relation[U,T] def compose[S] (st : Relation[S,T]) : Relation[S,U] def union (r : Relation[T,U]) : Relation[T,U] ... } 11 / 24
  12. Trees as Relations n p c1 c2 c3 12 /

    24
  13. Trees as Relations n p c1 c2 c3 parent 13

    / 24
  14. Trees as Relations n p c1 c2 c3 next parent

    14 / 24
  15. Trees as Relations n p c1 c2 c3 next prev

    parent 15 / 24
  16. Trees as Relations n p c1 c2 c3 siblings next

    prev parent 16 / 24
  17. Trees class Tree[T,U <: T] (val root : U) {

    val child : Relation[T,T] val parent : Relation[T,T] val next : Relation[T,T] val pre : Relation[T,T] val siblings : Relation[T,T] ... def isFirst (t : T) : Boolean def isLast (t : T) : Boolean def isRoot (t : T) : Boolean ... } 17 / 24
  18. Height Attribute in Kiama object HeightModule { val height :

    Node => Int = attr { case Num (_) => 0 case Plus (l, r) => 1 + height (l).max (height (r)) } } val n : Node = ... ... heightModule.height (n) ... 18 / 24
  19. Depth Attribute in Kiama (Old) object DepthModule { val depth

    : Node => Int = attr { case n if n.parent == null => 0 case n => depth (n.parent) + 1 } } val n : Node = ... ... depthModule.depth (n) ... 19 / 24
  20. Depth Attribute in Kiama (New) class DepthModule (tree : Tree[Node

    ,Node ]) { val depth : Node => Int = attr { case tree.parent (p) => depth (p) + 1 case _ => 0 } } val root : Node = ... val tree = new Tree[Node ,Node] (root) val n : Node = ... val depthModule = new DepthModule (tree) ... depthModule.depth (n) ... 20 / 24
  21. Pattern-matching with Relations case tree.parent (p) => Assume r is

    a relation between T and U and the attribute anAttr is applied to a value t of type T val r : Relation[T,U] = ... val anAttr : T => V = attr { case r (p1) => // if (t,u) in r and p1 matches u case r.pair (p0 , p1) => // if (t,u) in r, p0 matches t and p1 matches u } 21 / 24
  22. Nested Matching case tree.parent.pair (tree.next (n), _ : Block) =>

    // has a Block parent and a next sibling (n) Block n next 22 / 24
  23. Kiama Experience Changes: Removed old mutable node properties. Added implementations

    of Tree and Relation. Converted our extensive test suite including Prolog, Oberon-0 and MiniJava compilers (over 11,000 lines of Scala) to use attribute families. Results: Analysis objects are now analysis modules. Attribute definitions are often simpler with relational pattern matching. Rewriting didn’t change at all. No discernible differences in performance of sequential testing. Parallel testing of attribution on shared trees is now possible. 23 / 24
  24. Can Attribution and Rewriting Get Along? Yes! Attribution: decorating a

    tree many attributes need to consider nodes in context Rewriting: transforming tree A into tree B it is common to share nodes between trees Problem: if a node is shared, what is its context? Solution: trees make contexts explicit via node relations attribute families are defined generically on trees first-class relations provide pattern matching support implemented in upcoming Kiama 2.0 (kiama.googlecode.com) Scala is a powerful host language. . . 24 / 24