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

Respect Your Parents: How Attribution and Rewriting Can Get Along

Respect Your Parents: How Attribution and Rewriting Can Get Along

Updated version of SLE 2014 talk, some shortening and some new examples.

61f8010a7249d7ec93e197e96999fe6c?s=128

Tony Sloane

November 10, 2015
Tweet

Transcript

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

    Anthony M. Sloane Matthew Roberts Leonard G. C. Hamey Programming Languages and Verification Research Group Department of Computing Macquarie University @plvmq Anthony.Sloane@mq.edu.au @inkytonik
  2. Setting Kiama language processing library bringing language processing closer to

    developers shallow embedding in Scala sub-languages attribute grammars strategic term rewriting abstract state machines pretty-printing Structures structure definition is not under our control immutable trees and graphs with node identity Attribution attributes are first-class values storage is outside the attributed structure memoisation of attribute values is based on node identity 2 / 22
  3. Structure A Plus Plus Num 1 Num 2 Plus Num

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

    Num 2 Plus Num 3 Num 5 0 + (1 + 2) + (3 + 5) Top Plus Num 0 4 / 22
  5. Structures A and B Share Some Sub-Structure Plus Plus Num

    1 Num 2 Plus Num 3 Num 5 Top Plus Num 0 Num 4 Plus Plus Top 5 / 22
  6. Height Is Fine 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 / 22
  7. Height Attribute Equations 7 / 22

  8. 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) ... 8 / 22
  9. Depth, Which 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 9 / 22
  10. Depth Attribute Equations 10 / 22

  11. Can Attribution and Rewriting Get Along? Attribution: decorating a structure

    many attributes need to consider nodes in context Rewriting: transforming a structure into another structure it is common to share nodes between or within the trees Problem: if a node is shared between structures, what is its context? 11 / 22
  12. Our Solution Relations General mechanism for representing binary relations Trees

    Bundle structure root with the relations defined by reachability child, parent, prev, next, siblings, . . . Bonus: relations become powerful pattern matchers Attribute families Context-dependent attributes are families, indexed by a Tree Equations use the tree relations to access the context 12 / 22
  13. Trees as Relations: Child n p c1 c2 c3 13

    / 22
  14. Trees as Relations: Parent n p c1 c2 c3 parent

    14 / 22
  15. Trees as Relations: Next n p c1 c2 c3 next

    parent 15 / 22
  16. Trees as Relations: Prev n p c1 c2 c3 next

    prev parent 16 / 22
  17. Pattern-matching by using Relations as Extractor Objects r is a

    relation between T and U val r : Relation[T,U] = ... a is an attribute on T of type V a(t) applies a to t of type T val a : 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 } 17 / 22
  18. Depth Attribute in Kiama 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 depthModule = new DepthModule (tree) val n : Node = ... ... depthModule.depth (n) ... 18 / 22
  19. Generic Query: Extracting LLVM IR Value Types Store ::= "store"

    Type Value "," Type Value. Conversion ::= ConvOp Type Value "to" Type. Type Named prev tipe name collect[Vector , (Name , Type)] { case tree.prev.pair (Named (name), tipe : Type) => (name , tipe) } 19 / 22
  20. Rewriting and Attribution Rewrite rules don’t need to change val

    simplify = bottomup (rule { case Plus (Num (0), r) => r case Plus (l, Num (0)) => l }) User of context-dependent attribute must provide the Tree val m, n : Node = ... val orig = Plus (Plus (Num (0), m), n) val treeOrig = new Tree[Node ,Node] (orig) val dOrig = new DepthModule (treeOrig).depth (m) val simp = rewrite (simplify) (orig) val treeSimp = new Tree[Node ,Node] (simp) val dSimp = new DepthModule (treeSimp).depth (m) 20 / 22
  21. Lazy Cloning Sharing within a single structure can be introduced

    by rewrites rule { case Plus (l, r) => Plus (l, Plus (l, r)) } If context-dependent attribution is to be performed: sharing breaks uniqueness of node identity in the structure solution: the Tree class lazily clones shared sub-structure hence we only clone if context-attribution requires it 21 / 22
  22. Can Attribution and Rewriting Get Along? Yes! Attribution: decorating a

    structure many attributes need to consider nodes in context Rewriting: transforming a structure into another structure it is common to share nodes between or within the trees Problem: if a node is shared between structures, what is its context? Solution: Trees make node contexts explicit via relations attribute families are defined using Trees first-class relations provide pattern matching support more detail: see our SLE 2014 paper implemented in the upcoming Kiama 2.0 https://bitbucket.org/inkytonik/kiama 22 / 22