Slide 1

Slide 1 text

Lightweight Domain-Specific Language Processing in Kiama, Anthony Sloane, GTTSE 2009 Tutorial Anthony M. Sloane Programming Languages Research Group Department of Computing, Macquarie University Sydney, Australia [email protected] Lightweight Language Processing in Kiama and Scala Kiama was supported by The Netherlands NWO projects 638.001.610, MoDSE: Model-Driven Software Evolution, 612.063.512, TFA: Transformations for Abstractions, and 040.11.001, Combining Attribute Grammars and Term Rewriting for Programming Abstractions.

Slide 2

Slide 2 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 2 Kiama

Slide 3

Slide 3 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Embedded Language Processing Formalisms and associated implementation techniques for analysing, translating and executing structured text. Embedded as domain-specific languages in a general-purpose host language. context-free grammars attribute grammars term rewriting systems abstract state machines 3

Slide 4

Slide 4 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Attribute Grammars 4 Context-free grammar Case class definitions Attribute Function defined on nodes Equations Pattern matching function definition Evaluation mechanism Function call, attribute caching An equational formalism suited to specifying static properties of tree and graph structures.

Slide 5

Slide 5 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Variable Liveness 5 In Out y = v {v, w} {v, w, y} z = y {v, w, y} {v, w} x = v {v, w} {v, w, x} while (x) {v, w, x} {v, w, x} { x = w {v, w} {v, w} x = v {v, w} {v, w, x} } return x {x} {}

Slide 6

Slide 6 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Abstract syntax case class Program (body : Stm) extends Attributable abstract class Stm extends Attributable case class Assign (left : Var, right : Var) extends Stm case class While (cond : Var, body : Stm) extends Stm case class If (cond : Var, tru : Stm, fls : Stm) extends Stm case class Block (stms : List[Stm]) extends Stm case class Return (ret : Var) extends Stm case class Empty () extends Stm type Var = String 6

Slide 7

Slide 7 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Variable uses and definitions val uses : Stm ==> Set[Var] = attr { case If (v, _, _) => Set (v) case While (v, _) => Set (v) case Assign (_, v) => Set (v) case Return (v) => Set (v) case _ => Set () } val defines : Stm ==> Set[Var] = attr { case Assign (v, _) => Set (v) case _ => Set () } 7

Slide 8

Slide 8 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Control flow graph 8 y = v; z = y; x = v; while (x) { x = w; x = v; } return x;

Slide 9

Slide 9 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Statement sequencing val following : Stm ==> Set[Stm] = attr { case s => s.parent match { case t @ While (_, _) => Set (t) case b : Block if s isLast => b->following case Block (_) => Set (s.next) case _ => Set () } } } 9

Slide 10

Slide 10 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Control flow successor val succ : Stm ==> Set[Stm] = attr { case If (_, s1, s2) => Set (s1, s2) case t @ While (_, s) => t->following + s case Return (_) => Set () case Block (s :: _) => Set (s) case s => s->following } 10

Slide 11

Slide 11 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dataflow in and out of statements 11 in(s) = uses(s) ∪ (out(s) \ defines(s)) out(s) = ￿ x∈succ(s) in(x)

Slide 12

Slide 12 text

val out : Stm ==> Set[Var] = circular (Set[Var]()) { case s => (s->succ) flatMap (in) } val in : Stm ==> Set[Var] = circular (Set[Var]()) { case s => uses (s) ++ (out (s) -- defines (s)) } Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dataflow in and out of statements 12 in(s) = uses(s) ∪ (out(s) \ defines(s)) out(s) = ￿ x∈succ(s) in(x)

Slide 13

Slide 13 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Stratego A powerful term rewriting language based on primitive match, build, sequence and choice operators rewrite rules built on the primitives generic traversal operators to control application rules an implementation by translation to C Deployed for many program transformation problems including DSL implementation, compiler optimisation, refactoring and web application development. http://strategoxt.org 13

Slide 14

Slide 14 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Strategy-based Rewriting 14 Rewrite rule Pattern-matching function Strategy Higher-order function A transformation of a term that either succeeds, producing a new term, or fails abstract class Strategy extends (Term => Option[Term])

Slide 15

Slide 15 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Applying Strategies A strategy is a function, so it can be applied directly to a term. val s : Strategy val t : Term s (t) rewrite can be used to ignore failure. def rewrite (s : => Strategy) (t : Term) : Term rewrite (s) (t) 15

Slide 16

Slide 16 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Basic Strategies Always succeed with no change. val id : Strategy Always fail. val fail : Strategy Succeed if the current term is equal to t. def term (t : Term) : Strategy Always succeed, changing the term to t. implicit def termToStrategy (t : Term) : Strategy 16

Slide 17

Slide 17 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Combining Strategies Methods of the Strategy class allow strategies to be combined: Generic traversal operators: def all (s : => Strategy) : Strategy def some (s : => Strategy) : Strategy def one (s : => Strategy) : Strategy 17 p <* q sequence p <+ q deterministic choice p + q non-deterministic choice p < q + r guarded choice

Slide 18

Slide 18 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dead code elimination 18 In Out y = v; {v, w} {v, w, y} z = y; {v, w, y} {v, w} x = v; {v, w} {v, w, x} while (x) {v, w, x} {v, w, x} { x = w; {v, w} {v, w} x = v; {v, w} {v, w, x} } return x; {x} {}

Slide 19

Slide 19 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dead code elimination 19 rule { case s @ Assign (v, _) if (! (s->out contains v)) => Empty () } Replace an assignment to a dead variable by an empty statement.

Slide 20

Slide 20 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dead code elimination 20 def alltd (s : => Strategy) : Strategy = s <+ all (alltd (s)) val elimDeadAssign = alltd ( rule { case s @ Assign (v, _) if (! (s->out contains v)) => Empty () } ) Replace all dead assignment statements in a program.

Slide 21

Slide 21 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dead code elimination 21 Remove empty statements and empty blocks. rule { case Empty () :: ss => ss case Block (Nil) => Empty () }

Slide 22

Slide 22 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dead code elimination 22 def bottomup (s : => Strategy) : Strategy = all (bottomup (s)) <* s def attempt (s : => Strategy) : Strategy = s <+ id val elimEmpties = bottomup (attempt ( rule { case Empty () :: ss => ss case Block (Nil) => Empty () } )) Remove empties from the bottom of the tree upwards.

Slide 23

Slide 23 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Dead code elimination 23 def optimise (t : Stm) : Stm = rewrite (rules) (t) val rules = elimDeadAssign <* elimEmpties

Slide 24

Slide 24 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Conclusion So far, so good... Attribution is around 600 lines of code, rewriting is around 1000 lines, including comments and a largish strategy library. All hail to Scala! Ongoing activities: Better types for strategies Support for more language processing paradigms Larger use cases, performance and scalability Expressibility and semantics of paradigm combinations Correctness of semantics of paradigm hosting and combinations 24

Slide 25

Slide 25 text

Lightweight Language Processing in Kiama and Scala, Anthony Sloane, Scala Days 2010 Further information Binary and source downloads, examples, documentation, papers, talks and mailing lists http://kiama.googlecode.com Next release: 1.0.0, when Scala 2.8 is released [email protected] http://www.comp.mq.edu.au/~asloane Twitter: inkytonik 25