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.

Tony Sloane

November 10, 2015
Tweet

More Decks by Tony Sloane

Other Decks in Programming

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 [email protected] @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 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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