Share
Embed
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
Transcript
22 slides
-
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 -
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 -
Structure A Plus Plus Num 1 Num 2 Plus Num
3 Num 4 (1 + 2) + (3 + 4) Top 3 / 22 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
Trees as Relations: Next n p c1 c2 c3 next
parent 15 / 22 -
Trees as Relations: Prev n p c1 c2 c3 next
prev parent 16 / 22 -
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 -
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 -
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 -
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 -
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 -
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