SlideShare a Scribd company logo
1 of 149
Download to read offline
Building DSLs with
  The Spoofax Language Workbench

                                 Eelco Visser
                       Delft University of Technology
                            http://eelcovisser.org



Joint work with Lennart Kats, Karl-Trygve Kalleberg, Maartje de Jonge, and many others
The Meta-Languages Wars

   Internal DSLs vs External DSLs

        Textual vs Graphical

Partial vs Complete Code Generation

Project-Specific vs Multi-Project DSLs

 Code Generation vs Interpretation

   Dynamically vs Statically Typed
The Meta-Languages Wars

   Internal DSLs vs External DSLs

        Textual vs Graphical

Partial vs Complete Code Generation

Project-Specific vs Multi-Project DSLs

 Code Generation vs Interpretation

   Dynamically vs Statically Typed
WebDSL
                                   http://webdsl.org



      separation of concerns & linguistic integration



Eelco Visser. WebDSL: A Case Study in Domain-Specific Language Engineering. GTTSE 2007: 291-373
1,190,303
publications



 http://researchr.org
publication
                     records




correct & extend
author
profiles
bibliographies

       tagging

  reputation system

access control rules

     user groups

 conference calendar

community engineering

        etc.
18,000 lines of WebDSL code

138 (generated) tables in mysql
Concerns in web applications
-   Data model

-   User interface templates

-   Actions

-   Access control rules

-   Data validation



WebDSL
-   Linguistic integration

-   Cross concern, static consistency checking
WebLib: a model of researchr
Data Model
entity Publication {
  key        :: String (id)
  title      :: String (name,searchable)
  authors    -> List<Author>
  journal    :: String (searchable)
  volume     :: Int
  issue      :: Int
  year       :: Int (searchable)
  month      :: String (searchable)
  firstpage :: Int
  lastpage   :: Int
  cites      -> Set<Publication>
  citedBy    -> Set<Publication> (inverse=Publication.cites)
}

entity Author {
  key           ::   String (id)
  name          ::   String
  publications ->    Set<Publication> (inverse=Publication.authors)
  created       ::   DateTime
  modified      ::   DateTime
}
User Interface
Full Text Search
define page search() {
  var query : String
  action show() {
  	var pubs : List<Publication> := searchPublication(query);
  	if(pubs.length > 0) {
      replace(results, results(query,pubs));
    } else {
      replace(results, noresults());           entity Publication {
                                                 title      :: String (name,searchable)
    }
                                                 journal    :: String (searchable)
  }                                              year       :: Int (searchable)
  main{                                          month      :: String (searchable)
  	 section{                                     ...
                                               }
  	   header{"Search"}
  	   form{ input(query)[onkeyup:=show()] }
  	   placeholder results{}
  	 }
  }
}
Page & Template Definitions
define page root() {
  main{
    section{
      header{"Welcome to WebLib: Your Digital Library"}
      aboutWeblib()
      recent()
      tips()
    }
  }
}

define aboutWeblib() {
  par{ "WebLib is a digital library ..." }
}
XML Embedding
define no-span main() {
  <div class="page-wrap">
    top()
    <div class="body">
      messages()
      elements()
    </div>
    <div class="clear"></div>
  </div>
  footer()
}
Page Navigation
define tips() {
  section{
    header{"What Can You Do Here?"}
    list{
      listitem{ navigate(newauthor()){ "Add an author" } }
      listitem{ navigate(newpublication()){ "Add a publication" } }
      listitem{ navigate(search()){ "Search" } }
    }
  }
}

define page search() { ... }
HQL Embedding




extend entity Person {
  publications -> List<Publication> :=
                  select p
                    from Publication as p, Author as a
                   where (a.person = ~this) and (p = a.publication)
}
Forms & Data Binding
define page editpublication(pub : Publication) {
  main{
    section{
      header{"Edit Publication '" output(pub.title) "'"}
      form{
        group{
          label("Key:"    ){ input(pub.key)      }
          label("Title:" ){ input(pub.title)     }
          label("Authors:"){ input(pub.authors) }
          ...
        }
        submit action{
          pub.modified := now();
          return publication(pub);
        } { "Save" }
      }
    }
  }
}
Access Control

Danny M. Groenewegen, Eelco Visser. Declarative Access Control for WebDSL:
Combining Language Integration and Separation of Concerns. ICWE 2008: 175-188
Access Control Rules
                       define showReview(review : Review) {
                         action delete() { ... }
                         section{ ...
                           navigate(editReview(review)){"[Edit]"}
                           submitlink delete() {"[X]"}
                         }
                       }
Access Control Rules
                                     define showReview(review : Review) {
                                       action delete() { ... }
                                       section{ ...
                                         navigate(editReview(review)){"[Edit]"}
                                         submitlink delete() {"[X]"}
                                       }
                                     }
access control rules

  principal is User with credentials username, password

 predicate isReviewer(review : Review) {
 	 review.reviewer == securityContext.principal
 }
 rule template showReview(review : Review, pubLink : Bool) {
   review.public || isReviewer(review)
   rule action delete() {
     loggedIn() && isReviewer(review)
   }
 }
 rule page editReview(review : Review) {
   loggedIn() && isReviewer(review)
 }
Data Validation


Danny M. Groenewegen, Eelco Visser. Integration of Data Validation and
User Interface Concerns in a DSL for Web Applications. SLE 2009: 164-173
Data Validation: Form Input Validation


label("Acronym (without year)"){
  input(acronym){

        validate(!isEmptyString(acronym),
                 "Provide acronym")

        validate(!(/[ ]/.find(acronym)),
                 "Acronym should not contain spaces")

        validate(!(/[0-9][0-9][0-9][0-9]/.find(acronym)),
                 "Acronym should not contain year")

    }
}
Data Validation: Data Invariants



entity Publication {
  key :: String (id, index(25),

                 validate(isUniquePublication(this),
                          "that key is already in use"),

                 validate(isValidKeyForURL(key),
                          "Key should consist of letters, digits, : and -"))
    ...
}
Data Validation: Assertions


extend entity Person {
  invitation -> Invitation (inverse=Invitation.invitee)

    function invite(email : Email, invitation : WikiText) : Invitation {

        validate(findUser(email) == null
                 && findInvitationByEmail(email).length == 0,
                 "That email address is already in use.");

        ...
    }
}
Concerns in web applications
-   Data model

-   User interface templates

-   Actions

-   Access control rules

-   Data validation



WebDSL
-   Linguistic integration

-   Cross concern, static consistency checking
IDEs for DSLs
parse                 check
  Model                AST                   Errors



                         desugar



Traditional
Compiler               core
Architecture

                          generate



                       Code
Compiler Ingredients
Syntax definition
   ★ concrete syntax
   ★ abstract syntax

Static semantics
   ★ error checking
   ★ name resolution
   ★ type analysis

Model-to-model transformation
   ★ express constructs in core language

Code generation
   ★ translate core language models to implementation
IDEs Required
Editor Services for Modern IDEs
Syntactic Editor Services
   ★ syntax checking
   ★ bracket matching
   ★ syntax highlighting
   ★ code folding
   ★ outline view

Semantic Editor Services
   ★ error checking
   ★ reference resolving
   ★ hover help
   ★ code completion
   ★ refactoring
parse
Editor
                          AST

              feedback




                          core
Integrated
Development
Environment

                          Code
Architectural Requirements for IDEs


Editor services are based on AST
   ★ services analyze structure, not text of source

Error recovery
   ★ continue services in presence of syntactic errors

Incremental processing
   ★ effort of applying analysis, transformation, generation should be
      proportional to change in source

Separate compilation (analysis, transformation)
   ★ keep track of dependencies
Holy Grail of Software Language Definition




  Automatically derive efficient,
scalable, incremental compiler +
 usable IDE from high-level,
 declarative language
      definition
The Spoofax
Language Workbench
The Spoofax/IMP Language Workbench



Syntax definition: SDF
   ★ declarative, modular syntax definition

Transformation, analysis, generation: Stratego
   ★ rewrite rules, strategies, dynamic rules

Editor services
   ★ domain-specific languages for configuration

Based on IMP framework by IBM Research
Syntax Definition
Syntax
                                        Definition




                                                            Pretty-Print
                  Parse Table           Signature
                                                               Table




                    Parse              Transform            Pretty-Print


                                                                            @Entity
entity User {
                                                                           class User {
 name :: String
                                                                             String _user;
 pw :: Secret
                                                                             public User
}
                                                                               getUser() {
def output(u :

                     syntax definition is basis of language definition
                                                                               return _user;
User) {
                                                                              }
Lexical & Context-Free Syntax
Structure of Sentences




    composed from
Context-Free Grammar




         sort
                                          regular expression




symbol

          Definition
                               grammar production
           Property*
         {Stat “;”}*
            “entity”
Lexical Syntax




                                                     regular expression




character class


        characters in lexical syntax not separated by layout
Syntax of Data Models
Recognizing
Well-Formed
  Sentences
Lexical Syntax: Identifiers & Literals




follow restriction: symbol may not               reserved words
be followed by character from this class:
BlogEntry is one ID
Lexical Syntax: Strings



                                    escape




complement

             escape escape
Lexical Syntax: Whitespace




LAYOUT? is inserted between symbols in CF productions




                          normalize
Modular Syntax Definition
Parsing & Abstract Syntax



building structured representation of sentence
Linking Concrete & Abstract Syntax
Terms to Represent Abstract Syntax




Entity(“Blog”,
  [Property(“name”,SimpleType(“String”)),
   Property(“author”, SimpleType(“User”))]
)
Parsing in Spoofax
Signatures



defining the structure of abstract syntax terms
Syntax
                                        Definition




                                                            Pretty-Print
                  Parse Table           Signature
                                                               Table




                    Parse              Transform            Pretty-Print


                                                                            @Entity
entity User {
                                                                           class User {
 name :: String
                                                                             String _user;
 pw :: Secret
                                                                             public User
}
                                                                               getUser() {
def output(u :

                     syntax definition is basis of language definition
                                                                               return _user;
User) {
                                                                              }
Signatures




declare arguments and types of constructors
    signature is generated from grammar
Disambiguation
Arithmetic Expressions




note: this style produces good abstract syntax
Plus(Times(Var(“x”),Int(2)),Var(“z”))
Associativity
Priority
Parsing after Disambiguation
Brackets
Language Composition
Embedding HQL
                                                      module expressions
                                                      imports Common
                                                      imports HQL
                                                      exports
                                                        context-free syntax
                                                          SelectStatement -> Exp
define page index() {
  list{
    for(p : Post in select p from Post as p order by (p.title)) {
      listitem{ output(p) }
    }
  }
}

            ForElem("p", SimpleType("Post")
            , QueryRule(
                SelectFrom(
                  Some(Select(None(), [AliasedExpression(Path(["p"]), None())]))
                , FromClause([FromRangeJoin(FromClass(Path(["Post"]), Some(AsAlias(Alias("p"
                )
              , Some(OrderByClause([OrderElement(Paren([Path(["p", "title"])]), None())]))
              )
            , [CallElems("listitem", [CallArgs("output", [Var("p")])])]
            )
Presentational
Editor Services
Editor Services

Syntax highlighting
   ★ token coloring

Code folding
   ★ folding & unfolding code fragments

Outline view
   ★ table of contents

Syntax properties
   ★ bracket matching, indentation

Syntax completion
   ★ match on syntactic triggers & replace with template
Editor Services Composition

module nwl.main

imports nwl-Builders nwl-Colorer nwl-Folding nwl-Outliner
        nwl-References nwl-Syntax nwl-Completions

language General properties

  name            : nwl
  id              : nwl
  extends         : Root

  description     : "Spoofax/IMP-generated editor for the nwl language"
  url             : http://strategoxt.org

  extensions    : nwl
  table         : include/nwl.tbl
  start symbols : Start
Syntax
                         Definition




Default Syntax         Default               Default
 Highlighting        Code Folding          Outline View



     Custom Syntax            Custom             Custom
+     Highlighting   +      Code Folding   +    Outline View




                          Editor
Code Folding


          module nwl-Folding.generated
          folding Default folding
            Start.Module
            Definition.Entity
            Property.Property
            Definition.TemplateDef
            Element.CallArgs
            PageRef.PageRef
            Element.Action


          module nwl-Folding
          imports nwl-Folding.generated
          folding
            Element.CallElems
            Element.Call
            Element.ForElem
            Element.ForAllElem
Outline View


          module nwl-Outliner.generated
          outliner Default outliner
            Start.Module
            Definition.Entity
            Property.Property
            Definition.TemplateDef
            Element.CallArgs
            Exp.MethodCall
            Element.CallElems
            Element.Call
            Element.ForElem
            Element.ForAllElem
            PageRef.PageRef
            Element.Action
            Statement.For
            Statement.While
            Statement.If
            Element.Submit
            Element.XmlElem
module nwl-Colorer.generated
                              colorer Default, token-based highlighting
Default Syntax Highlighting     keyword    : 127 0 85 bold
                                identifier : default
                                string     : blue
                                number     : darkgreen
                                var        : 255 0 100 italic
                                operator   : 0 0 128
                                layout     : 100 100 0 italic
                              colorer System colors
                                darkred   = 128 0 0
                                red       = 255 0 0
                                darkgreen = 0 128 0
                                green     = 0 255 0
                                darkblue = 0 0 128
                                blue      = 0 0 255
                                cyan      = 0 255 255
                                magenta   = 255 0 255
                                yellow    = 255 255 0
                                white     = 255 255 255
                                black     = 0 0 0
                                gray      = 128 128 128
                                grey      = gray
                                orange    = 255 165 0
                                pink      = 255 105 180
                                brown     = 139 69 19
                                default   = _
Custom Syntax Highlighting




                module nwl-Colorer
                imports nwl-Colorer.generated
                colorer
                  Element : darkgreen
Syntax Properties

module nwl-Syntax.generated
language Syntax properties (static defaults)

 // Comment constructs:
 line comment                            : "//"
 block comment                           : "/*" * "*/"

 // Fences (used for matching,
 // inserting, indenting brackets):
 fences                                  : [ ]
                                           ( )
                                           { }
 // Automatic indent hints
 // (indent after these tokens):
 indent after                            : "="
                                           ":"
 // Regular expression for identifiers:
 identifier lexical                     : "[A-Za-z0-9_]+"
Parse Error Recovery
Parse Error Recovery




  also for composite languages
Builders
Semantic Editor Services
Builders: Analysis & Transformation Services

module nwl-Builders
builders
  provider: include/nwl.ctree

  observer: editor-analyze

  builder : "Generate Java code" =
    generate-java (openeditor) (realtime)

  builder : "Show ATerm (selection)" =
    generate-aterm (openeditor) (realtime) (meta)

  builder : "Normalize (selection)" =
    show-normalized (openeditor) (realtime) (meta)

  builder : "Normalize Pretty (selection)" =
    show-normalized-pp (openeditor) (realtime) (meta)
Term Rewriting
Term Rewriting



Term rewrite rules
   ★ transform term to term
   ★ pattern matching
   ★ variable binding
   ★ substitution

Rewriting strategy
   ★ algorithm for applying rewrite rules
Term Rewrite Rule


                         left-hand side pattern
label/name



      desugar :
        Property(x, t) -> Property(x, t, [])



             variable
                                                  right-hand side pattern
Rewrite Strategy


                                  generic strategy
strategy definition



     desugar-all = innermost(desugar)



                                              strategy instantiation



              apply transformation s exhaustively to all sub-
 innermost(s)
                terms of subject term in bottom-up order
Constant Folding
y := a + (3 * 5 + 2);


        Assign(
          Var("y")
        , Plus(
            Var("a")
          , Plus(Times(IntLit("3"), IntLit("5")), IntLit("2"))
parse     )
        )


                   Assign(
                     Var("y")
                   , BinOp(Var("a"), "+", IntLit("17"))
 desugar + eval    )


                                                  y := (a + 17);
                                   pretty-print
Constant Folding Rules

strategies

 eval-all = innermost(desugar + eval)

rules

 eval :
   BinOp(IntLit(x), "+", IntLit(y)) -> IntLit(<addS>(x, y))

 eval :
   BinOp(IntLit(x), "-", IntLit(y)) -> IntLit(<subtS>(x, y))

 eval :
   BinOp(IntLit(x), "*", IntLit(y)) -> IntLit(<mulS>(x, y))

 eval :
   BinOp(IntLit(x), "/", IntLit(y)) -> IntLit(<divS>(x, y))
Conditional Rewrite Rules

                                    bound in condition

            eval :
              BinOp(IntLit(x), "+", IntLit(y)) -> IntLit(z)
condition     where z := <addS>(x, y)




               match          apply transformation


     eval :
       BinOp(IntLit(x), "+", IntLit(y)) -> IntLit(<addS>(x, y))
Code Generation by
Model Transformation
Rewriting with Concrete Object Syntax


elem-to-java-servlet :
  tc@elem|[ x(e)[passign*]{elem*} ]| ->
  <wrap-input-render-java-code>
  bstm* |[
    String x_temp = ident+"~inputident"+uniqueid;
     ~*<render-error-messages-with-error-template(|java:expr|[ x_temp ]|,
            <ErrorTemplateInput>)> bstm*|[
        bstm_call*
     ]|
  ]|
  where <is-input-template> tc
  with inputident := <get-inputnumber> tc
        ; x_temp := <newname> "temp"
        ; bstm_call* := <control-flow-tcall-helper(|"render",expr|[ x_temp ]|)> tc




                        Stratego + embedded Java
Consistency Checking
Consistency Checking


Syntax definition
   ★ what are well-formed sentences?

Static analysis
   ★ not all ‘well-formedness’ properties are context-free
   ★ consistency of compositions
   ★ consistency of expressions wrt declarations

Error reporting
   ★ indicate errors in editor
   ★ use sensible error message
Consistency Checking: Ingredients

Editor Interface
   ★ collecting and displaying errors, warnings

Error checking
   ★ checking static constraints and reporting errors

Type analysis
   ★ computing types of expressions

Name resolution
   ★ disambiguation of names

Reference resolving
   ★ linking identifiers to declarations
Consistency Checking: Generic Approach


Rename
   ★ make identifiers unique

Map
   ★ map identifiers to declarations

Project
   ★ compute properties of declarations, expressions

Check
   ★ check constraints
Editor Interface

module nwl-Builders

imports nwl-Builders.generated

builders

  provider: include/nwl.ctree

  observer: editor-analyze
editor/nwl-Builders.esv
                                                                    trans/static-analysis.str
                          module static-analysis

                          imports include/nwl
                          imports entities
                          imports utils

                          rules // static analysis

                             editor-analyze:
                               (ast, path, fullpath) -> (errors, warnings, notes)
                               with ...
Editor Interface




editor-analyze:
  (ast, path, fullpath) -> (errors, warnings, notes)
  with
    errors   := <collect-all(check, conc)> ast;
    warnings := <collect-all(constraint-warning, conc)> ast;
    notes    := <collect-all(constraint-note, conc)> ast
Error Checking Rules




                 check :
                   context -> (target, error)
                   where assumption
                   where require(constraint)

                 require(s) = not(s)




– Context: identifying points in the code to check
– Assumptions: only report an error if certain assumptions hold (validating the context and avoiding spurious errors)
– Constraints: checking for constraints at the context
– Formulating an error message
– Attribution of the error to a particular character range in the source text (usually, only part of the context
Error Checking: Binary Operators



check :
  e@BinOp(e1, op, e2) ->
    (e, $[operator [op] not defined for [<pp>t1] and [<pp>t2]])
  where t1 := <type-of> e1
  where t2 := <type-of> e2
  where require(<type-of> e)
Pretty-Printing with String Interpolation


 pp : Entity(x, prop*) ->
      $[entity [x] {
           [<map(pp)>prop*]
        }]
 pp : Property(x,t) ->
      $[[x] : [<pp>t]
       ]
 pp : SimpleType(x) -> x
 pp : SetType(t) -> $[Set<[<pp> t]>]
 pp : [] -> $[]
 pp : [t] -> <pp>t
 pp : [t1,t2|ts] -> $[[<pp>t1],[<pp>[t2|ts]]]
Type Analysis




type-of : e -> t




 compute type of expression
Type Analysis: Literals




type-of :
  StringLit(x) -> SimpleType("String")

type-of :
  IntLit(x) -> SimpleType("Int")
Type Analysis: Binary Operators


type-of :
  BinOp(e1, op, e2) -> t
  where t := <function-type>(op, [<type-of>e1, <type-of>e2])

function-type :
  ("+", [SimpleType("String"), SimpleType("String")]) -> SimpleType("String")

function-type :
  ("+", [SimpleType("Int"), SimpleType("Int")]) -> SimpleType("Int")

function-type :
  ("-", [SimpleType("Int"), SimpleType("Int")]) -> SimpleType("Int")
Type Analysis: What is Type of Variable?


define page root(x : Int) {
  action exptest() {
    for(y : Int in {1,2,x}) {
      x := x + y;
    }
  }
                                               type-of :
}
                                                 Var(x) -> t
                                                 where t := ???

       Assign(
         Var("x")
       , BinOp(Var("x"), "+", Var("y"))
       )


             type of variable not part of variable use
Variables: Map


declare-all =
  alltd(declare)

declare :
  Param(x, t) -> Param(x, t)
  with rules(
         TypeOf : x -> t
       )

type-of :
  Var(x) -> t
  where t := <TypeOf> x
Scope




                    define page root(x : Int) {
                      action exptest() {
                        for(x : Int in {1,2,x}) {
                          print(x);
                        }
                      }
                    }




multiple occurrences of same identifier corresponding to different declarations
Variables: Map + Rename
rename-all = alltd(rename)

rename :
  Param(x, t) -> Param(y, t)
  with y := <rename-var>(x, t)
                                          unique annotation
rename-var :
  (x, t) -> y
  with y := x{<new>};
                                                 map variable to type
       rules(
         TypeOf   : y -> t
         RenameId : x -> y
       )
                                      rename occurrences
rename :
  Var(x) -> Var(y) where y := <RenameId> x

type-of :
  Var(x) -> t where t := <TypeOf> x
Term Annotations




                   t{t1,...,tn}




add additional information to term without affecting signature
Variables: Check




check :
  e@Var(x) -> (e, $[Variable '[x]' not declared])
  where require(<type-of>e)
Variable Binding Constructs




 rename :
   For(x, t, e1, stat1*) -> For(y, t, e2, stat2*)
   with e2 := <rename-all> e1
   with {| RenameId
          : y := <rename-var>(x, t)
          ; stat2* := <rename-all> stat1*
          |}




For defines local variable x in body stat1*’
Editor Interface with Analysis



editor-analyze:
  (ast, path, fullpath) -> (errors, warnings, notes)
  with
    ast2     := <analyze> ast;
    errors   := <collect-all(check, conc)> ast2;
    warnings := <collect-all(constraint-warning, conc)> ast2;
    notes    := <collect-all(constraint-note, conc)> ast2

analyze = rename-all
Rename, Map, Project, Check


Rename
   ★ make local variables unique

Map
   ★ variables to their type

Project
   ★ compute type of expressions

Check
   ★ check constraints using types
Reference Resolution
Reference Resolution




Aiding program navigation
  ★ Hover-click on identifier to jump to declaration

Reuse name resolution infrastructure
Reference Resolution

module nwl-References

imports nwl-References.generated

references

  reference _ : editor-resolve



 editor-resolve:
   (source, position, ast, path, fullpath) -> target
   where
     target := <compute-target> source
From Use to Declaration



editor-resolve:
  (SimpleType(type), position, ast, path, fullpath) -> target
  where
    Entity(target,_) := <declaration-of> type

editor-resolve:
  (ref@PageRef(x,e*), position, ast, path, fullpath) -> target
  where
    TemplateDef(_,target,_,_) := <declaration-of> ref
Experience
Experience
Bootstrapped
  ★ SDF, Stratego, ATerm, PP
  ★ Editor service language

Spoofax
  ★ WebDSL
  ★ Mobl: mobile web applications
  ★ Acoda: migration of data models
  ★ Aster: attribute grammars
  ★ PIL: platform independent language
  ★ Student languages

SDF+Stratego
  ★ Java, AspectJ, XML, PHP, SQL, Jimple, Octave, Dot, ...
Future Work (in progress)
Higher-level definition of scope & type system
   ★ cover scope systems of real languages

Refactoring
   ★ layout preservation, generic refactoring strategies

Systematic language design
   ★ how do we decide that a language design is good?

Interaction design
   ★ higher-level specifications of interaction

Combining textual and visual
Textual IDE in the browser
- the end -
   Lennart C. L. Kats, Eelco Visser. The Spoofax Language Workbench. Rules
   for Declarative Specification of Languages and IDEs. OOPSLA 2010



                   http://spoofax.org


http://webdsl.org                                   http://mobl.org
Context-sensitive
 Transformation
define page blog(b : Blog) {
       Template Inlining                   header{output(b.name)}
                                           list{
                                             for(p : Post in b.posts) {
                                               listitem{ outputPost(p) }
                                             }
                                           }
                                         }
                                         define outputPost(pst : Post) {
                                           navigate post(pst) { output(pst.name)   }
                                         }
                                         define list()     { <ul> elements </ul>   }
                                         define listitem() { <li> elements </li>   }
                                         define header()   { <h1> elements </h1>   }

define page blog ( b : Blog ) {
  <h1>
    output(b.name)
  </h1>
  <ul>
    for ( p : Post in b.posts ) {
       <li>
         navigate post(p) { output(p.name) }
       </li>
    }
  </ul>
}
Context-sensitive Transformation



Local-to-local
   ★ replace term by another term

Local-to-global
   ★ local term influence terms in other parts of model

Global-to-local
   ★ global information influences transformation of local terms
define page blog(b : Blog) {
                                           header{output(b.name)}
                                           list{
                                             for(p : Post in b.posts) {
                                               listitem{ outputPost(p) }
                                             }
                                           }
 Inlining is Global-to-Local             }
                                         define outputPost(pst : Post) {
                                           navigate post(pst) { output(pst.name)   }
                                         }
                                         define list()     { <ul> elements </ul>   }
                                         define listitem() { <li> elements </li>   }
                                         define header()   { <h1> elements </h1>   }

define page blog ( b : Blog ) {
  <h1>
    output(b.name)
  </h1>
  <ul>
    for ( p : Post in b.posts ) {
       <li>
         navigate post(p) { output(p.name) }
       </li>
    }
  </ul>
}
Inlining as Rewrite Problem




outputPost(p) -> navigate post(p) { output(p.name) }
where define outputPost(pst : Post) {
        navigate post(pst) { output(pst.name) }
      }




          (this is not a valid Stratego rewrite rule)
Rewrite Rules are Context-free




desugar :
  Property(x, t) -> Property(x, t, [])
Simplification: Parameterless Templates


                                define page blog(b : Blog) {
                                  ...
                                  footer()
                                }
                                define footer() {
                                  navigate url(http://webdsl.org) { “WebDSL” }
                                }




define page blog ( b : Blog ) {
  ...
  container() { navigate url(http://webdsl.org) { “WebDSL” } }
}
Rewrite in Context



Inline :
  [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*]
  where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1*




    local traversal              bound in context




      container needed to replace single call with multiple elements
Intermezzo:
Rewriting Strategies
transformation
                              is
partial* function from terms to terms


          * transformation may fail to apply to a term
Defining Transformations: Rules & Strategies


Rewrite rules are basic transformations
   ★ transform term matching lhs to instantiation of rhs
   ★ evaluate condition (where clause)

Strategies combine rules into complex transformations
   ★ select rules to apply
   ★ select algorithm to apply rules

Strategy combinators
   ★ composition of custom transformations
Strategy Combinators


id
     ★ Identity

fail
     ★ failure

s1 ; s2
     ★ sequential composition

s1 <+ s2
     ★ choice
Variables
{x, y : s}
     ★ term variable scope

?t
     ★ match term pattern t

!t
     ★ build term pattern t

t1 := t2
     ★ match term t2 to term (pattern) t1

<s> t
     ★ apply strategy s to term t
Rewrite Rules




l : t1 -> t2 where s
  ★ named, scoped rewrite rule
  ★ all variables in t1, t2, s are in scope of the rule

(t1 -> t2 where s)
  ★ unscoped rewrite rule
  ★ variables are in scope of enclosing scope
Rewrite in Context



Inline :
  [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*]
  where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1*




                                bound in context
Inline :
  [def@TemplateDef(f,[],elem*) | def1*] -> [def | def2*]
  where def2* := <alltd((Call(f) -> Call("container", elem*)))> def1*




f                            elem*


      [ TemplateDef(
          "footer"
        , []
        , [Navigate(PageRef("webdsl", []), [String("WebDSL")])]
        )
      , TemplateDef(
          "blog"
        , [Param("b", SimpleType("Blog"))]
        , [Call("footer")]
        )
      ]

                      Call(f)
def1*
Strategy Definitions

f(x,y|a,b) = s
  ★ x, y are strategy parameters
  ★ a, b are term parameters
  ★ s uses all parameters

f(x) = s          f = s
  ★ term parameters are optional
  ★ all parameters are optional

Examples
  ★ try(s) = s <+ id

  ★ repeat(s) = try(s; repeat(s))
Rules with Parameters

Transform all elements of a list
 map(s) : [] -> []

 map(s) : [x|xs] -> [<s>x | <map(s)> xs]


Invert order of elements of a list
 inverse(|ys) : [] -> ys

 inverse(|ys) : [x|xs] -> <inverse(|[x|ys])> xs


Pair elements of two lists
 zip(s) : ([],[]) -> []

 zip(s) : ([x|xs],[y|ys]) -> [<s>(x,y) | <zip(s)>(xs,ys)]
Traversal Combinators



all(s)
  ★ apply s to all direct sub-terms (children)

one(s)
  ★ apply s to exactly one sub-term

some(s)
  ★ apply s to at least one sub-term
Traversal Strategies


topdown(s) = s; all(topdown(s))
  ★ apply s to all sub-terms in top-down order

bottomup(s) = all(bottomup(s)); s
  ★ apply s to all sub-terms in bottom-up order

oncetd(s) = s <+ one(oncetd(s))
  ★ apply s to one sub-term

alltd(s) = s <+ all(alltd(s))
  ★ apply s to frontier
Rewrite in Context: Local Traversal



Inline :
  [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*]
  where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1*




    local traversal
Dynamic Rewrite Rules
Rewrite in Context: Not Optimal
Inline :
  [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*]
  where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1*




                 requires def before use
                 local traversal for each declaration
Dynamic Rewrite Rules
Inline :
  [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*]
  where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1*




declare-inline :
  TemplateDef(f,[],elem1*) -> TemplateDef(f,[],elem1*)
  where rules(
    InlineTemplate : Call(f) -> Call("container", elem1*)
  )

inline =
  alltd(declare-inline);
  topdown(try(InlineTemplate))




        separate traversal from rule definition (binding closures)
Inlining as Rewrite Problem (Revisited)


  outputPost(p) -> navigate post(p) { output(p.name) }
  where define outputPost(pst : Post) {
          navigate post(pst) { output(pst.name) }
        }

                            (informal)



declare-inline :
  TemplateDef(f,[],elem1*) -> TemplateDef(f,[],elem1*)
  where rules(
    InlineTemplate : Call(f) -> Call("container", elem1*)
  )

                  (formal; but not yet complete)
define page blog(b : Blog) {
       Template Parameter                  header{output(b.name)}
                                           list{
                                             for(p : Post in b.posts) {
                                               listitem{ outputPost(p) }
                                             }
                                           }
                                         }
                                         define outputPost(pst : Post) {
                                           navigate post(pst) { output(pst.name)   }
                                         }
                                         define list()     { <ul> elements </ul>   }
                                         define listitem() { <li> elements </li>   }
                                         define header()   { <h1> elements </h1>   }

define page blog ( b : Blog ) {
  <h1>
    output(b.name)
  </h1>
  <ul>
    for ( p : Post in b.posts ) {
       <li>
         navigate post(p) { output(p.name) }
       </li>
    }
  </ul>
}
Inlining Templates with Parameters
declare-inline :
  def@TemplateDef(mod*,f,param*,elem1*) -> def
  where rules(
    InlineTemplate :
      Call(f, e*, []) -> Call("container", [], elem3*)
      where elem3* := <substitute> (param*, e*, elem1*)
  )

substitute :
  (param*, e*, elem1*) -> elem2*
  where {| Subst
         : <zip(bind-arg)> (param*, e*)
         ; elem2* := <alltd(Subst)> elem1*
         |}

bind-arg :
  (Param(x, t), e) -> (Param(x, t), e)
  where rules( Subst : Var(x) -> e )
Element Parameters

              define list() { <ul> elements </ul> }




declare-inline :
  def@TemplateDef(mod*,f,param*,elem1*) -> def
  where rules(
    InlineTemplate :
      Call(f, e*, elem2*) -> Call("container", [], elem3*)
      where {| Subst
             : rules(
                 Subst : Elements() -> Call("container",[],elem2*)
               )
             ; elem3* := <substitute> (param*, e*, elem1*)
             |}
  )
Removing Intermediate Structures



rules // remove containers

 desugar-container :
   [Call("container",[], elem1*) | elem2*] -> [elem1*, elem2*]

 desugar :
   elem1* -> elem2*
   where elem2* := <at-suffix(desugar-container)> elem1*




     container needed to replace single call with multiple elements
Inlining Strategy


module template-inlining

imports libstratego-lib
imports include/nwl
imports desugar

strategies

  inline-all =
    desugar-all;
    alltd(declare-inline);
    innermost(desugar <+ InlineTemplate)

rules

  declare-inline : ...
module template-inlining

                    imports libstratego-lib
                    imports include/nwl
                    imports desugar

                    strategies

                     inline-all =
                       desugar-all;
                       alltd(declare-inline);
                       innermost(desugar <+ InlineTemplate)

                    rules

                     declare-inline :
                       TemplateDef(mod*,f,param*,elem1*) -> TemplateDef(mod*,f,param*,elem1*)
                       where rules(
                         InlineTemplate :
                           Call(f, e*, elem2*) -> Call("container", [], elem3*)

Template Inlining          where {| Subst
                                  : rules( Subst : Elements() -> Call("container", [], elem2*) )
                                  ; elem3* := <substitute> (param*, e*, elem1*)

 Transformation        )
                                  |}



                     substitute :
                       (param*, e*, elem1*) -> elem2*
                       where {| Subst
                              : <zip(bind-arg)> (param*, e*)
                              ; elem2* := <alltd(Subst)> elem1*
                              |}

                     bind-arg :
                       (Param(x, t), e) -> (Param(x, t), e)
                       where rules( Subst : Var(x) -> e )

                    rules // remove containers

                     desugar-container :
                       [Call("container",[], elem1*) | elem2*] -> [elem1*, elem2*]

                     desugar :
                       elem1* -> elem2*
                       where elem2* := <at-suffix(desugar-container)> elem1*

More Related Content

What's hot

UKOUG Tech14 - Using Database In-Memory Column Store with Complex Datatypes
UKOUG Tech14 - Using Database In-Memory Column Store with Complex DatatypesUKOUG Tech14 - Using Database In-Memory Column Store with Complex Datatypes
UKOUG Tech14 - Using Database In-Memory Column Store with Complex DatatypesMarco Gralike
 
How to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational DatabaseHow to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational DatabaseDATAVERSITY
 
OakTable World 2015 - Using XMLType content with the Oracle In-Memory Column...
OakTable World 2015  - Using XMLType content with the Oracle In-Memory Column...OakTable World 2015  - Using XMLType content with the Oracle In-Memory Column...
OakTable World 2015 - Using XMLType content with the Oracle In-Memory Column...Marco Gralike
 
Functional GUIs with F#
Functional GUIs with F#Functional GUIs with F#
Functional GUIs with F#Frank Krueger
 
From SQL to NoSQL: Structured Querying for JSON
From SQL to NoSQL: Structured Querying for JSONFrom SQL to NoSQL: Structured Querying for JSON
From SQL to NoSQL: Structured Querying for JSONKeshav Murthy
 
Introduction to Restkit
Introduction to RestkitIntroduction to Restkit
Introduction to Restkitpetertmarks
 
Hotsos 2013 - Creating Structure in Unstructured Data
Hotsos 2013 - Creating Structure in Unstructured DataHotsos 2013 - Creating Structure in Unstructured Data
Hotsos 2013 - Creating Structure in Unstructured DataMarco Gralike
 
12. session 12 java script objects
12. session 12   java script objects12. session 12   java script objects
12. session 12 java script objectsPhúc Đỗ
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring DataOliver Gierke
 
BGOUG 2012 - XML Index Strategies
BGOUG 2012 - XML Index StrategiesBGOUG 2012 - XML Index Strategies
BGOUG 2012 - XML Index StrategiesMarco Gralike
 
NAVTechDays 2017 Json Meets NAV
NAVTechDays 2017 Json Meets NAVNAVTechDays 2017 Json Meets NAV
NAVTechDays 2017 Json Meets NAVGunnar Gestsson
 
Spring data presentation
Spring data presentationSpring data presentation
Spring data presentationOleksii Usyk
 
领域驱动设计实例讲解
领域驱动设计实例讲解领域驱动设计实例讲解
领域驱动设计实例讲解Jacky Chi
 
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)Stefan Urbanek
 
Oracle business intelligence publisher – developer training
Oracle business intelligence publisher – developer trainingOracle business intelligence publisher – developer training
Oracle business intelligence publisher – developer trainingitprofessionals network
 

What's hot (20)

Full metal mongo
Full metal mongoFull metal mongo
Full metal mongo
 
UKOUG Tech14 - Using Database In-Memory Column Store with Complex Datatypes
UKOUG Tech14 - Using Database In-Memory Column Store with Complex DatatypesUKOUG Tech14 - Using Database In-Memory Column Store with Complex Datatypes
UKOUG Tech14 - Using Database In-Memory Column Store with Complex Datatypes
 
How to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational DatabaseHow to Handle NoSQL with a Relational Database
How to Handle NoSQL with a Relational Database
 
OakTable World 2015 - Using XMLType content with the Oracle In-Memory Column...
OakTable World 2015  - Using XMLType content with the Oracle In-Memory Column...OakTable World 2015  - Using XMLType content with the Oracle In-Memory Column...
OakTable World 2015 - Using XMLType content with the Oracle In-Memory Column...
 
Functional GUIs with F#
Functional GUIs with F#Functional GUIs with F#
Functional GUIs with F#
 
From SQL to NoSQL: Structured Querying for JSON
From SQL to NoSQL: Structured Querying for JSONFrom SQL to NoSQL: Structured Querying for JSON
From SQL to NoSQL: Structured Querying for JSON
 
Introduction to Restkit
Introduction to RestkitIntroduction to Restkit
Introduction to Restkit
 
Java script
Java scriptJava script
Java script
 
JSON
JSONJSON
JSON
 
Hotsos 2013 - Creating Structure in Unstructured Data
Hotsos 2013 - Creating Structure in Unstructured DataHotsos 2013 - Creating Structure in Unstructured Data
Hotsos 2013 - Creating Structure in Unstructured Data
 
qooxdoo Form Management
qooxdoo Form Managementqooxdoo Form Management
qooxdoo Form Management
 
12. session 12 java script objects
12. session 12   java script objects12. session 12   java script objects
12. session 12 java script objects
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring Data
 
BGOUG 2012 - XML Index Strategies
BGOUG 2012 - XML Index StrategiesBGOUG 2012 - XML Index Strategies
BGOUG 2012 - XML Index Strategies
 
NAVTechDays 2017 Json Meets NAV
NAVTechDays 2017 Json Meets NAVNAVTechDays 2017 Json Meets NAV
NAVTechDays 2017 Json Meets NAV
 
Spring data presentation
Spring data presentationSpring data presentation
Spring data presentation
 
领域驱动设计实例讲解
领域驱动设计实例讲解领域驱动设计实例讲解
领域驱动设计实例讲解
 
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
Cubes - Lightweight Python OLAP (EuroPython 2012 talk)
 
AngularJS
AngularJSAngularJS
AngularJS
 
Oracle business intelligence publisher – developer training
Oracle business intelligence publisher – developer trainingOracle business intelligence publisher – developer training
Oracle business intelligence publisher – developer training
 

Viewers also liked

Model-Driven Software Development - Context-Sensitive Transformation
Model-Driven Software Development - Context-Sensitive TransformationModel-Driven Software Development - Context-Sensitive Transformation
Model-Driven Software Development - Context-Sensitive TransformationEelco Visser
 
TI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific LanguagesTI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific LanguagesEelco Visser
 
Model-Driven Software Development - Web Abstractions 1
Model-Driven Software Development - Web Abstractions 1Model-Driven Software Development - Web Abstractions 1
Model-Driven Software Development - Web Abstractions 1Eelco Visser
 
Model-Driven Software Development - Web Abstractions 2
Model-Driven Software Development - Web Abstractions 2Model-Driven Software Development - Web Abstractions 2
Model-Driven Software Development - Web Abstractions 2Eelco Visser
 
Composing Domain-Specific Languages
Composing Domain-Specific LanguagesComposing Domain-Specific Languages
Composing Domain-Specific LanguagesEelco Visser
 
From Muddling to Modelling
From Muddling to ModellingFrom Muddling to Modelling
From Muddling to ModellingJorn Bettin
 
Domain Analysis & Data Modeling
Domain Analysis & Data ModelingDomain Analysis & Data Modeling
Domain Analysis & Data ModelingEelco Visser
 
Software languages
Software languagesSoftware languages
Software languagesEelco Visser
 
Programming languages
Programming languagesProgramming languages
Programming languagesEelco Visser
 

Viewers also liked (14)

Code Generation
Code GenerationCode Generation
Code Generation
 
Model-Driven Software Development - Context-Sensitive Transformation
Model-Driven Software Development - Context-Sensitive TransformationModel-Driven Software Development - Context-Sensitive Transformation
Model-Driven Software Development - Context-Sensitive Transformation
 
TI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific LanguagesTI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific Languages
 
Model-Driven Software Development - Web Abstractions 1
Model-Driven Software Development - Web Abstractions 1Model-Driven Software Development - Web Abstractions 1
Model-Driven Software Development - Web Abstractions 1
 
Type analysis
Type analysisType analysis
Type analysis
 
Model-Driven Software Development - Web Abstractions 2
Model-Driven Software Development - Web Abstractions 2Model-Driven Software Development - Web Abstractions 2
Model-Driven Software Development - Web Abstractions 2
 
Composing Domain-Specific Languages
Composing Domain-Specific LanguagesComposing Domain-Specific Languages
Composing Domain-Specific Languages
 
Static Analysis
Static AnalysisStatic Analysis
Static Analysis
 
Dataflow Analysis
Dataflow AnalysisDataflow Analysis
Dataflow Analysis
 
From Muddling to Modelling
From Muddling to ModellingFrom Muddling to Modelling
From Muddling to Modelling
 
Domain Analysis & Data Modeling
Domain Analysis & Data ModelingDomain Analysis & Data Modeling
Domain Analysis & Data Modeling
 
Dynamic Semantics
Dynamic SemanticsDynamic Semantics
Dynamic Semantics
 
Software languages
Software languagesSoftware languages
Software languages
 
Programming languages
Programming languagesProgramming languages
Programming languages
 

Similar to Building DSLs with the Spoofax Language Workbench

Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)lennartkats
 
SF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDBSF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDBPeter Hamilton
 
"Technical Challenges behind Visual IDE for React Components" Tetiana Mandziuk
"Technical Challenges behind Visual IDE for React Components" Tetiana Mandziuk"Technical Challenges behind Visual IDE for React Components" Tetiana Mandziuk
"Technical Challenges behind Visual IDE for React Components" Tetiana MandziukFwdays
 
The openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query LanguageThe openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query LanguageNeo4j
 
Mongo db勉強会20110730
Mongo db勉強会20110730Mongo db勉強会20110730
Mongo db勉強会20110730Akihiro Okuno
 
CS101- Introduction to Computing- Lecture 29
CS101- Introduction to Computing- Lecture 29CS101- Introduction to Computing- Lecture 29
CS101- Introduction to Computing- Lecture 29Bilal Ahmed
 
Visual Studio 2010 and .NET 4.0 Overview
Visual Studio 2010 and .NET 4.0 OverviewVisual Studio 2010 and .NET 4.0 Overview
Visual Studio 2010 and .NET 4.0 Overviewbwullems
 
Separation of Concerns in Web User Interfaces
Separation of Concerns in Web User InterfacesSeparation of Concerns in Web User Interfaces
Separation of Concerns in Web User Interfacesjippeh
 
NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020Thodoris Bais
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1Paras Mendiratta
 
SQL Saturday 28 - .NET Fundamentals
SQL Saturday 28 - .NET FundamentalsSQL Saturday 28 - .NET Fundamentals
SQL Saturday 28 - .NET Fundamentalsmikehuguet
 
Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Andrii Lashchenko
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDCMike Dirolf
 
Software Language Design & Engineering
Software Language Design & EngineeringSoftware Language Design & Engineering
Software Language Design & EngineeringEelco Visser
 
Introduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in RIntroduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in RPaul Richards
 
MSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for Developers
MSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for DevelopersMSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for Developers
MSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for DevelopersDave Bost
 

Similar to Building DSLs with the Spoofax Language Workbench (20)

Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
Domain-Specific Languages for Composable Editor Plugins (LDTA 2009)
 
SF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDBSF Elixir Meetup - RethinkDB
SF Elixir Meetup - RethinkDB
 
.Net 3.5
.Net 3.5.Net 3.5
.Net 3.5
 
"Technical Challenges behind Visual IDE for React Components" Tetiana Mandziuk
"Technical Challenges behind Visual IDE for React Components" Tetiana Mandziuk"Technical Challenges behind Visual IDE for React Components" Tetiana Mandziuk
"Technical Challenges behind Visual IDE for React Components" Tetiana Mandziuk
 
The openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query LanguageThe openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query Language
 
Mongo db勉強会20110730
Mongo db勉強会20110730Mongo db勉強会20110730
Mongo db勉強会20110730
 
CS101- Introduction to Computing- Lecture 29
CS101- Introduction to Computing- Lecture 29CS101- Introduction to Computing- Lecture 29
CS101- Introduction to Computing- Lecture 29
 
Visual Studio 2010 and .NET 4.0 Overview
Visual Studio 2010 and .NET 4.0 OverviewVisual Studio 2010 and .NET 4.0 Overview
Visual Studio 2010 and .NET 4.0 Overview
 
Separation of Concerns in Web User Interfaces
Separation of Concerns in Web User InterfacesSeparation of Concerns in Web User Interfaces
Separation of Concerns in Web User Interfaces
 
NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1
 
SQL Saturday 28 - .NET Fundamentals
SQL Saturday 28 - .NET FundamentalsSQL Saturday 28 - .NET Fundamentals
SQL Saturday 28 - .NET Fundamentals
 
Angular Schematics
Angular SchematicsAngular Schematics
Angular Schematics
 
Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.Spray Json and MongoDB Queries: Insights and Simple Tricks.
Spray Json and MongoDB Queries: Insights and Simple Tricks.
 
Couchbas for dummies
Couchbas for dummiesCouchbas for dummies
Couchbas for dummies
 
WEB DEVELOPMENT
WEB DEVELOPMENTWEB DEVELOPMENT
WEB DEVELOPMENT
 
MongoDB at ZPUGDC
MongoDB at ZPUGDCMongoDB at ZPUGDC
MongoDB at ZPUGDC
 
Software Language Design & Engineering
Software Language Design & EngineeringSoftware Language Design & Engineering
Software Language Design & Engineering
 
Introduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in RIntroduction to Shiny for building web apps in R
Introduction to Shiny for building web apps in R
 
MSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for Developers
MSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for DevelopersMSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for Developers
MSDN Presents: Visual Studio 2010, .NET 4, SharePoint 2010 for Developers
 

More from Eelco Visser

CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingEelco Visser
 
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesEelco Visser
 
CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingEelco Visser
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionEelco Visser
 
CS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionCS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionEelco Visser
 
A Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesA Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesEelco Visser
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with StatixEelco Visser
 
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionCompiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionEelco Visser
 
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Eelco Visser
 
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementCompiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementEelco Visser
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersEelco Visser
 
Compiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationCompiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationEelco Visser
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesEelco Visser
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksCompiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksEelco Visser
 
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisCompiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisEelco Visser
 
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionCompiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionEelco Visser
 
Compiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsCompiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsEelco Visser
 
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingCompiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingEelco Visser
 
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisCompiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisEelco Visser
 
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingCompiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingEelco Visser
 

More from Eelco Visser (20)

CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
 
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic ServicesCS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 4 | Syntactic Services
 
CS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | ParsingCS4200 2019 | Lecture 3 | Parsing
CS4200 2019 | Lecture 3 | Parsing
 
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definitionCS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 | Lecture 2 | syntax-definition
 
CS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: IntroductionCS4200 2019 Lecture 1: Introduction
CS4200 2019 Lecture 1: Introduction
 
A Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation RulesA Direct Semantics of Declarative Disambiguation Rules
A Direct Semantics of Declarative Disambiguation Rules
 
Declarative Type System Specification with Statix
Declarative Type System Specification with StatixDeclarative Type System Specification with Statix
Declarative Type System Specification with Statix
 
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler ConstructionCompiler Construction | Lecture 17 | Beyond Compiler Construction
Compiler Construction | Lecture 17 | Beyond Compiler Construction
 
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
 
Compiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory ManagementCompiler Construction | Lecture 15 | Memory Management
Compiler Construction | Lecture 15 | Memory Management
 
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | InterpretersCompiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 14 | Interpreters
 
Compiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code GenerationCompiler Construction | Lecture 13 | Code Generation
Compiler Construction | Lecture 13 | Code Generation
 
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual MachinesCompiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 12 | Virtual Machines
 
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone FrameworksCompiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 11 | Monotone Frameworks
 
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow AnalysisCompiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 10 | Data-Flow Analysis
 
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint ResolutionCompiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 9 | Constraint Resolution
 
Compiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type ConstraintsCompiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 8 | Type Constraints
 
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type CheckingCompiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 7 | Type Checking
 
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static AnalysisCompiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 6 | Introduction to Static Analysis
 
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term RewritingCompiler Construction | Lecture 5 | Transformation by Term Rewriting
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
 

Recently uploaded

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Recently uploaded (20)

Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 

Building DSLs with the Spoofax Language Workbench

  • 1. Building DSLs with The Spoofax Language Workbench Eelco Visser Delft University of Technology http://eelcovisser.org Joint work with Lennart Kats, Karl-Trygve Kalleberg, Maartje de Jonge, and many others
  • 2. The Meta-Languages Wars Internal DSLs vs External DSLs Textual vs Graphical Partial vs Complete Code Generation Project-Specific vs Multi-Project DSLs Code Generation vs Interpretation Dynamically vs Statically Typed
  • 3. The Meta-Languages Wars Internal DSLs vs External DSLs Textual vs Graphical Partial vs Complete Code Generation Project-Specific vs Multi-Project DSLs Code Generation vs Interpretation Dynamically vs Statically Typed
  • 4. WebDSL http://webdsl.org separation of concerns & linguistic integration Eelco Visser. WebDSL: A Case Study in Domain-Specific Language Engineering. GTTSE 2007: 291-373
  • 6. publication records correct & extend
  • 8. bibliographies tagging reputation system access control rules user groups conference calendar community engineering etc.
  • 9. 18,000 lines of WebDSL code 138 (generated) tables in mysql
  • 10. Concerns in web applications - Data model - User interface templates - Actions - Access control rules - Data validation WebDSL - Linguistic integration - Cross concern, static consistency checking
  • 11. WebLib: a model of researchr
  • 12. Data Model entity Publication { key :: String (id) title :: String (name,searchable) authors -> List<Author> journal :: String (searchable) volume :: Int issue :: Int year :: Int (searchable) month :: String (searchable) firstpage :: Int lastpage :: Int cites -> Set<Publication> citedBy -> Set<Publication> (inverse=Publication.cites) } entity Author { key :: String (id) name :: String publications -> Set<Publication> (inverse=Publication.authors) created :: DateTime modified :: DateTime }
  • 14. Full Text Search define page search() { var query : String action show() { var pubs : List<Publication> := searchPublication(query); if(pubs.length > 0) { replace(results, results(query,pubs)); } else { replace(results, noresults()); entity Publication { title :: String (name,searchable) } journal :: String (searchable) } year :: Int (searchable) main{ month :: String (searchable) section{ ... } header{"Search"} form{ input(query)[onkeyup:=show()] } placeholder results{} } } }
  • 15. Page & Template Definitions define page root() { main{ section{ header{"Welcome to WebLib: Your Digital Library"} aboutWeblib() recent() tips() } } } define aboutWeblib() { par{ "WebLib is a digital library ..." } }
  • 16. XML Embedding define no-span main() { <div class="page-wrap"> top() <div class="body"> messages() elements() </div> <div class="clear"></div> </div> footer() }
  • 17. Page Navigation define tips() { section{ header{"What Can You Do Here?"} list{ listitem{ navigate(newauthor()){ "Add an author" } } listitem{ navigate(newpublication()){ "Add a publication" } } listitem{ navigate(search()){ "Search" } } } } } define page search() { ... }
  • 18. HQL Embedding extend entity Person { publications -> List<Publication> := select p from Publication as p, Author as a where (a.person = ~this) and (p = a.publication) }
  • 19. Forms & Data Binding define page editpublication(pub : Publication) { main{ section{ header{"Edit Publication '" output(pub.title) "'"} form{ group{ label("Key:" ){ input(pub.key) } label("Title:" ){ input(pub.title) } label("Authors:"){ input(pub.authors) } ... } submit action{ pub.modified := now(); return publication(pub); } { "Save" } } } } }
  • 20. Access Control Danny M. Groenewegen, Eelco Visser. Declarative Access Control for WebDSL: Combining Language Integration and Separation of Concerns. ICWE 2008: 175-188
  • 21. Access Control Rules define showReview(review : Review) { action delete() { ... } section{ ... navigate(editReview(review)){"[Edit]"} submitlink delete() {"[X]"} } }
  • 22. Access Control Rules define showReview(review : Review) { action delete() { ... } section{ ... navigate(editReview(review)){"[Edit]"} submitlink delete() {"[X]"} } } access control rules principal is User with credentials username, password predicate isReviewer(review : Review) { review.reviewer == securityContext.principal } rule template showReview(review : Review, pubLink : Bool) { review.public || isReviewer(review) rule action delete() { loggedIn() && isReviewer(review) } } rule page editReview(review : Review) { loggedIn() && isReviewer(review) }
  • 23. Data Validation Danny M. Groenewegen, Eelco Visser. Integration of Data Validation and User Interface Concerns in a DSL for Web Applications. SLE 2009: 164-173
  • 24. Data Validation: Form Input Validation label("Acronym (without year)"){ input(acronym){ validate(!isEmptyString(acronym), "Provide acronym") validate(!(/[ ]/.find(acronym)), "Acronym should not contain spaces") validate(!(/[0-9][0-9][0-9][0-9]/.find(acronym)), "Acronym should not contain year") } }
  • 25. Data Validation: Data Invariants entity Publication { key :: String (id, index(25), validate(isUniquePublication(this), "that key is already in use"), validate(isValidKeyForURL(key), "Key should consist of letters, digits, : and -")) ... }
  • 26. Data Validation: Assertions extend entity Person { invitation -> Invitation (inverse=Invitation.invitee) function invite(email : Email, invitation : WikiText) : Invitation { validate(findUser(email) == null && findInvitationByEmail(email).length == 0, "That email address is already in use."); ... } }
  • 27. Concerns in web applications - Data model - User interface templates - Actions - Access control rules - Data validation WebDSL - Linguistic integration - Cross concern, static consistency checking
  • 29. parse check Model AST Errors desugar Traditional Compiler core Architecture generate Code
  • 30. Compiler Ingredients Syntax definition ★ concrete syntax ★ abstract syntax Static semantics ★ error checking ★ name resolution ★ type analysis Model-to-model transformation ★ express constructs in core language Code generation ★ translate core language models to implementation
  • 32. Editor Services for Modern IDEs Syntactic Editor Services ★ syntax checking ★ bracket matching ★ syntax highlighting ★ code folding ★ outline view Semantic Editor Services ★ error checking ★ reference resolving ★ hover help ★ code completion ★ refactoring
  • 33. parse Editor AST feedback core Integrated Development Environment Code
  • 34. Architectural Requirements for IDEs Editor services are based on AST ★ services analyze structure, not text of source Error recovery ★ continue services in presence of syntactic errors Incremental processing ★ effort of applying analysis, transformation, generation should be proportional to change in source Separate compilation (analysis, transformation) ★ keep track of dependencies
  • 35. Holy Grail of Software Language Definition Automatically derive efficient, scalable, incremental compiler + usable IDE from high-level, declarative language definition
  • 37. The Spoofax/IMP Language Workbench Syntax definition: SDF ★ declarative, modular syntax definition Transformation, analysis, generation: Stratego ★ rewrite rules, strategies, dynamic rules Editor services ★ domain-specific languages for configuration Based on IMP framework by IBM Research
  • 39. Syntax Definition Pretty-Print Parse Table Signature Table Parse Transform Pretty-Print @Entity entity User { class User { name :: String String _user; pw :: Secret public User } getUser() { def output(u : syntax definition is basis of language definition return _user; User) { }
  • 41. Structure of Sentences composed from
  • 42. Context-Free Grammar sort regular expression symbol Definition grammar production Property* {Stat “;”}* “entity”
  • 43. Lexical Syntax regular expression character class characters in lexical syntax not separated by layout
  • 44. Syntax of Data Models
  • 46. Lexical Syntax: Identifiers & Literals follow restriction: symbol may not reserved words be followed by character from this class: BlogEntry is one ID
  • 47. Lexical Syntax: Strings escape complement escape escape
  • 48. Lexical Syntax: Whitespace LAYOUT? is inserted between symbols in CF productions normalize
  • 50. Parsing & Abstract Syntax building structured representation of sentence
  • 51. Linking Concrete & Abstract Syntax
  • 52. Terms to Represent Abstract Syntax Entity(“Blog”, [Property(“name”,SimpleType(“String”)), Property(“author”, SimpleType(“User”))] )
  • 54. Signatures defining the structure of abstract syntax terms
  • 55. Syntax Definition Pretty-Print Parse Table Signature Table Parse Transform Pretty-Print @Entity entity User { class User { name :: String String _user; pw :: Secret public User } getUser() { def output(u : syntax definition is basis of language definition return _user; User) { }
  • 56. Signatures declare arguments and types of constructors signature is generated from grammar
  • 58. Arithmetic Expressions note: this style produces good abstract syntax Plus(Times(Var(“x”),Int(2)),Var(“z”))
  • 59.
  • 65. Embedding HQL module expressions imports Common imports HQL exports context-free syntax SelectStatement -> Exp define page index() { list{ for(p : Post in select p from Post as p order by (p.title)) { listitem{ output(p) } } } } ForElem("p", SimpleType("Post") , QueryRule( SelectFrom( Some(Select(None(), [AliasedExpression(Path(["p"]), None())])) , FromClause([FromRangeJoin(FromClass(Path(["Post"]), Some(AsAlias(Alias("p" ) , Some(OrderByClause([OrderElement(Paren([Path(["p", "title"])]), None())])) ) , [CallElems("listitem", [CallArgs("output", [Var("p")])])] )
  • 67. Editor Services Syntax highlighting ★ token coloring Code folding ★ folding & unfolding code fragments Outline view ★ table of contents Syntax properties ★ bracket matching, indentation Syntax completion ★ match on syntactic triggers & replace with template
  • 68. Editor Services Composition module nwl.main imports nwl-Builders nwl-Colorer nwl-Folding nwl-Outliner nwl-References nwl-Syntax nwl-Completions language General properties name : nwl id : nwl extends : Root description : "Spoofax/IMP-generated editor for the nwl language" url : http://strategoxt.org extensions : nwl table : include/nwl.tbl start symbols : Start
  • 69. Syntax Definition Default Syntax Default Default Highlighting Code Folding Outline View Custom Syntax Custom Custom + Highlighting + Code Folding + Outline View Editor
  • 70. Code Folding module nwl-Folding.generated folding Default folding Start.Module Definition.Entity Property.Property Definition.TemplateDef Element.CallArgs PageRef.PageRef Element.Action module nwl-Folding imports nwl-Folding.generated folding Element.CallElems Element.Call Element.ForElem Element.ForAllElem
  • 71. Outline View module nwl-Outliner.generated outliner Default outliner Start.Module Definition.Entity Property.Property Definition.TemplateDef Element.CallArgs Exp.MethodCall Element.CallElems Element.Call Element.ForElem Element.ForAllElem PageRef.PageRef Element.Action Statement.For Statement.While Statement.If Element.Submit Element.XmlElem
  • 72. module nwl-Colorer.generated colorer Default, token-based highlighting Default Syntax Highlighting keyword : 127 0 85 bold identifier : default string : blue number : darkgreen var : 255 0 100 italic operator : 0 0 128 layout : 100 100 0 italic colorer System colors darkred = 128 0 0 red = 255 0 0 darkgreen = 0 128 0 green = 0 255 0 darkblue = 0 0 128 blue = 0 0 255 cyan = 0 255 255 magenta = 255 0 255 yellow = 255 255 0 white = 255 255 255 black = 0 0 0 gray = 128 128 128 grey = gray orange = 255 165 0 pink = 255 105 180 brown = 139 69 19 default = _
  • 73. Custom Syntax Highlighting module nwl-Colorer imports nwl-Colorer.generated colorer Element : darkgreen
  • 74. Syntax Properties module nwl-Syntax.generated language Syntax properties (static defaults) // Comment constructs: line comment : "//" block comment : "/*" * "*/" // Fences (used for matching, // inserting, indenting brackets): fences : [ ] ( ) { } // Automatic indent hints // (indent after these tokens): indent after : "=" ":" // Regular expression for identifiers: identifier lexical : "[A-Za-z0-9_]+"
  • 76. Parse Error Recovery also for composite languages
  • 78. Builders: Analysis & Transformation Services module nwl-Builders builders provider: include/nwl.ctree observer: editor-analyze builder : "Generate Java code" = generate-java (openeditor) (realtime) builder : "Show ATerm (selection)" = generate-aterm (openeditor) (realtime) (meta) builder : "Normalize (selection)" = show-normalized (openeditor) (realtime) (meta) builder : "Normalize Pretty (selection)" = show-normalized-pp (openeditor) (realtime) (meta)
  • 80. Term Rewriting Term rewrite rules ★ transform term to term ★ pattern matching ★ variable binding ★ substitution Rewriting strategy ★ algorithm for applying rewrite rules
  • 81. Term Rewrite Rule left-hand side pattern label/name desugar : Property(x, t) -> Property(x, t, []) variable right-hand side pattern
  • 82. Rewrite Strategy generic strategy strategy definition desugar-all = innermost(desugar) strategy instantiation apply transformation s exhaustively to all sub- innermost(s) terms of subject term in bottom-up order
  • 83. Constant Folding y := a + (3 * 5 + 2); Assign( Var("y") , Plus( Var("a") , Plus(Times(IntLit("3"), IntLit("5")), IntLit("2")) parse ) ) Assign( Var("y") , BinOp(Var("a"), "+", IntLit("17")) desugar + eval ) y := (a + 17); pretty-print
  • 84. Constant Folding Rules strategies eval-all = innermost(desugar + eval) rules eval : BinOp(IntLit(x), "+", IntLit(y)) -> IntLit(<addS>(x, y)) eval : BinOp(IntLit(x), "-", IntLit(y)) -> IntLit(<subtS>(x, y)) eval : BinOp(IntLit(x), "*", IntLit(y)) -> IntLit(<mulS>(x, y)) eval : BinOp(IntLit(x), "/", IntLit(y)) -> IntLit(<divS>(x, y))
  • 85. Conditional Rewrite Rules bound in condition eval : BinOp(IntLit(x), "+", IntLit(y)) -> IntLit(z) condition where z := <addS>(x, y) match apply transformation eval : BinOp(IntLit(x), "+", IntLit(y)) -> IntLit(<addS>(x, y))
  • 86. Code Generation by Model Transformation
  • 87. Rewriting with Concrete Object Syntax elem-to-java-servlet : tc@elem|[ x(e)[passign*]{elem*} ]| -> <wrap-input-render-java-code> bstm* |[ String x_temp = ident+"~inputident"+uniqueid; ~*<render-error-messages-with-error-template(|java:expr|[ x_temp ]|, <ErrorTemplateInput>)> bstm*|[ bstm_call* ]| ]| where <is-input-template> tc with inputident := <get-inputnumber> tc ; x_temp := <newname> "temp" ; bstm_call* := <control-flow-tcall-helper(|"render",expr|[ x_temp ]|)> tc Stratego + embedded Java
  • 89. Consistency Checking Syntax definition ★ what are well-formed sentences? Static analysis ★ not all ‘well-formedness’ properties are context-free ★ consistency of compositions ★ consistency of expressions wrt declarations Error reporting ★ indicate errors in editor ★ use sensible error message
  • 90.
  • 91.
  • 92. Consistency Checking: Ingredients Editor Interface ★ collecting and displaying errors, warnings Error checking ★ checking static constraints and reporting errors Type analysis ★ computing types of expressions Name resolution ★ disambiguation of names Reference resolving ★ linking identifiers to declarations
  • 93. Consistency Checking: Generic Approach Rename ★ make identifiers unique Map ★ map identifiers to declarations Project ★ compute properties of declarations, expressions Check ★ check constraints
  • 94. Editor Interface module nwl-Builders imports nwl-Builders.generated builders provider: include/nwl.ctree observer: editor-analyze editor/nwl-Builders.esv trans/static-analysis.str module static-analysis imports include/nwl imports entities imports utils rules // static analysis editor-analyze: (ast, path, fullpath) -> (errors, warnings, notes) with ...
  • 95. Editor Interface editor-analyze: (ast, path, fullpath) -> (errors, warnings, notes) with errors := <collect-all(check, conc)> ast; warnings := <collect-all(constraint-warning, conc)> ast; notes := <collect-all(constraint-note, conc)> ast
  • 96. Error Checking Rules check : context -> (target, error) where assumption where require(constraint) require(s) = not(s) – Context: identifying points in the code to check – Assumptions: only report an error if certain assumptions hold (validating the context and avoiding spurious errors) – Constraints: checking for constraints at the context – Formulating an error message – Attribution of the error to a particular character range in the source text (usually, only part of the context
  • 97. Error Checking: Binary Operators check : e@BinOp(e1, op, e2) -> (e, $[operator [op] not defined for [<pp>t1] and [<pp>t2]]) where t1 := <type-of> e1 where t2 := <type-of> e2 where require(<type-of> e)
  • 98. Pretty-Printing with String Interpolation pp : Entity(x, prop*) -> $[entity [x] { [<map(pp)>prop*] }] pp : Property(x,t) -> $[[x] : [<pp>t] ] pp : SimpleType(x) -> x pp : SetType(t) -> $[Set<[<pp> t]>] pp : [] -> $[] pp : [t] -> <pp>t pp : [t1,t2|ts] -> $[[<pp>t1],[<pp>[t2|ts]]]
  • 99. Type Analysis type-of : e -> t compute type of expression
  • 100. Type Analysis: Literals type-of : StringLit(x) -> SimpleType("String") type-of : IntLit(x) -> SimpleType("Int")
  • 101. Type Analysis: Binary Operators type-of : BinOp(e1, op, e2) -> t where t := <function-type>(op, [<type-of>e1, <type-of>e2]) function-type : ("+", [SimpleType("String"), SimpleType("String")]) -> SimpleType("String") function-type : ("+", [SimpleType("Int"), SimpleType("Int")]) -> SimpleType("Int") function-type : ("-", [SimpleType("Int"), SimpleType("Int")]) -> SimpleType("Int")
  • 102. Type Analysis: What is Type of Variable? define page root(x : Int) { action exptest() { for(y : Int in {1,2,x}) { x := x + y; } } type-of : } Var(x) -> t where t := ??? Assign( Var("x") , BinOp(Var("x"), "+", Var("y")) ) type of variable not part of variable use
  • 103. Variables: Map declare-all = alltd(declare) declare : Param(x, t) -> Param(x, t) with rules( TypeOf : x -> t ) type-of : Var(x) -> t where t := <TypeOf> x
  • 104. Scope define page root(x : Int) { action exptest() { for(x : Int in {1,2,x}) { print(x); } } } multiple occurrences of same identifier corresponding to different declarations
  • 105. Variables: Map + Rename rename-all = alltd(rename) rename : Param(x, t) -> Param(y, t) with y := <rename-var>(x, t) unique annotation rename-var : (x, t) -> y with y := x{<new>}; map variable to type rules( TypeOf : y -> t RenameId : x -> y ) rename occurrences rename : Var(x) -> Var(y) where y := <RenameId> x type-of : Var(x) -> t where t := <TypeOf> x
  • 106. Term Annotations t{t1,...,tn} add additional information to term without affecting signature
  • 107. Variables: Check check : e@Var(x) -> (e, $[Variable '[x]' not declared]) where require(<type-of>e)
  • 108. Variable Binding Constructs rename : For(x, t, e1, stat1*) -> For(y, t, e2, stat2*) with e2 := <rename-all> e1 with {| RenameId : y := <rename-var>(x, t) ; stat2* := <rename-all> stat1* |} For defines local variable x in body stat1*’
  • 109. Editor Interface with Analysis editor-analyze: (ast, path, fullpath) -> (errors, warnings, notes) with ast2 := <analyze> ast; errors := <collect-all(check, conc)> ast2; warnings := <collect-all(constraint-warning, conc)> ast2; notes := <collect-all(constraint-note, conc)> ast2 analyze = rename-all
  • 110. Rename, Map, Project, Check Rename ★ make local variables unique Map ★ variables to their type Project ★ compute type of expressions Check ★ check constraints using types
  • 112. Reference Resolution Aiding program navigation ★ Hover-click on identifier to jump to declaration Reuse name resolution infrastructure
  • 113. Reference Resolution module nwl-References imports nwl-References.generated references reference _ : editor-resolve editor-resolve: (source, position, ast, path, fullpath) -> target where target := <compute-target> source
  • 114. From Use to Declaration editor-resolve: (SimpleType(type), position, ast, path, fullpath) -> target where Entity(target,_) := <declaration-of> type editor-resolve: (ref@PageRef(x,e*), position, ast, path, fullpath) -> target where TemplateDef(_,target,_,_) := <declaration-of> ref
  • 116. Experience Bootstrapped ★ SDF, Stratego, ATerm, PP ★ Editor service language Spoofax ★ WebDSL ★ Mobl: mobile web applications ★ Acoda: migration of data models ★ Aster: attribute grammars ★ PIL: platform independent language ★ Student languages SDF+Stratego ★ Java, AspectJ, XML, PHP, SQL, Jimple, Octave, Dot, ...
  • 117. Future Work (in progress) Higher-level definition of scope & type system ★ cover scope systems of real languages Refactoring ★ layout preservation, generic refactoring strategies Systematic language design ★ how do we decide that a language design is good? Interaction design ★ higher-level specifications of interaction Combining textual and visual Textual IDE in the browser
  • 118. - the end - Lennart C. L. Kats, Eelco Visser. The Spoofax Language Workbench. Rules for Declarative Specification of Languages and IDEs. OOPSLA 2010 http://spoofax.org http://webdsl.org http://mobl.org
  • 120. define page blog(b : Blog) { Template Inlining header{output(b.name)} list{ for(p : Post in b.posts) { listitem{ outputPost(p) } } } } define outputPost(pst : Post) { navigate post(pst) { output(pst.name) } } define list() { <ul> elements </ul> } define listitem() { <li> elements </li> } define header() { <h1> elements </h1> } define page blog ( b : Blog ) { <h1> output(b.name) </h1> <ul> for ( p : Post in b.posts ) { <li> navigate post(p) { output(p.name) } </li> } </ul> }
  • 121. Context-sensitive Transformation Local-to-local ★ replace term by another term Local-to-global ★ local term influence terms in other parts of model Global-to-local ★ global information influences transformation of local terms
  • 122. define page blog(b : Blog) { header{output(b.name)} list{ for(p : Post in b.posts) { listitem{ outputPost(p) } } } Inlining is Global-to-Local } define outputPost(pst : Post) { navigate post(pst) { output(pst.name) } } define list() { <ul> elements </ul> } define listitem() { <li> elements </li> } define header() { <h1> elements </h1> } define page blog ( b : Blog ) { <h1> output(b.name) </h1> <ul> for ( p : Post in b.posts ) { <li> navigate post(p) { output(p.name) } </li> } </ul> }
  • 123. Inlining as Rewrite Problem outputPost(p) -> navigate post(p) { output(p.name) } where define outputPost(pst : Post) { navigate post(pst) { output(pst.name) } } (this is not a valid Stratego rewrite rule)
  • 124. Rewrite Rules are Context-free desugar : Property(x, t) -> Property(x, t, [])
  • 125. Simplification: Parameterless Templates define page blog(b : Blog) { ... footer() } define footer() { navigate url(http://webdsl.org) { “WebDSL” } } define page blog ( b : Blog ) { ... container() { navigate url(http://webdsl.org) { “WebDSL” } } }
  • 126. Rewrite in Context Inline : [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1* local traversal bound in context container needed to replace single call with multiple elements
  • 128. transformation is partial* function from terms to terms * transformation may fail to apply to a term
  • 129. Defining Transformations: Rules & Strategies Rewrite rules are basic transformations ★ transform term matching lhs to instantiation of rhs ★ evaluate condition (where clause) Strategies combine rules into complex transformations ★ select rules to apply ★ select algorithm to apply rules Strategy combinators ★ composition of custom transformations
  • 130. Strategy Combinators id ★ Identity fail ★ failure s1 ; s2 ★ sequential composition s1 <+ s2 ★ choice
  • 131. Variables {x, y : s} ★ term variable scope ?t ★ match term pattern t !t ★ build term pattern t t1 := t2 ★ match term t2 to term (pattern) t1 <s> t ★ apply strategy s to term t
  • 132. Rewrite Rules l : t1 -> t2 where s ★ named, scoped rewrite rule ★ all variables in t1, t2, s are in scope of the rule (t1 -> t2 where s) ★ unscoped rewrite rule ★ variables are in scope of enclosing scope
  • 133. Rewrite in Context Inline : [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1* bound in context
  • 134. Inline : [def@TemplateDef(f,[],elem*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem*)))> def1* f elem* [ TemplateDef( "footer" , [] , [Navigate(PageRef("webdsl", []), [String("WebDSL")])] ) , TemplateDef( "blog" , [Param("b", SimpleType("Blog"))] , [Call("footer")] ) ] Call(f) def1*
  • 135. Strategy Definitions f(x,y|a,b) = s ★ x, y are strategy parameters ★ a, b are term parameters ★ s uses all parameters f(x) = s f = s ★ term parameters are optional ★ all parameters are optional Examples ★ try(s) = s <+ id ★ repeat(s) = try(s; repeat(s))
  • 136. Rules with Parameters Transform all elements of a list map(s) : [] -> [] map(s) : [x|xs] -> [<s>x | <map(s)> xs] Invert order of elements of a list inverse(|ys) : [] -> ys inverse(|ys) : [x|xs] -> <inverse(|[x|ys])> xs Pair elements of two lists zip(s) : ([],[]) -> [] zip(s) : ([x|xs],[y|ys]) -> [<s>(x,y) | <zip(s)>(xs,ys)]
  • 137. Traversal Combinators all(s) ★ apply s to all direct sub-terms (children) one(s) ★ apply s to exactly one sub-term some(s) ★ apply s to at least one sub-term
  • 138. Traversal Strategies topdown(s) = s; all(topdown(s)) ★ apply s to all sub-terms in top-down order bottomup(s) = all(bottomup(s)); s ★ apply s to all sub-terms in bottom-up order oncetd(s) = s <+ one(oncetd(s)) ★ apply s to one sub-term alltd(s) = s <+ all(alltd(s)) ★ apply s to frontier
  • 139. Rewrite in Context: Local Traversal Inline : [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1* local traversal
  • 141. Rewrite in Context: Not Optimal Inline : [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1* requires def before use local traversal for each declaration
  • 142. Dynamic Rewrite Rules Inline : [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1* declare-inline : TemplateDef(f,[],elem1*) -> TemplateDef(f,[],elem1*) where rules( InlineTemplate : Call(f) -> Call("container", elem1*) ) inline = alltd(declare-inline); topdown(try(InlineTemplate)) separate traversal from rule definition (binding closures)
  • 143. Inlining as Rewrite Problem (Revisited) outputPost(p) -> navigate post(p) { output(p.name) } where define outputPost(pst : Post) { navigate post(pst) { output(pst.name) } } (informal) declare-inline : TemplateDef(f,[],elem1*) -> TemplateDef(f,[],elem1*) where rules( InlineTemplate : Call(f) -> Call("container", elem1*) ) (formal; but not yet complete)
  • 144. define page blog(b : Blog) { Template Parameter header{output(b.name)} list{ for(p : Post in b.posts) { listitem{ outputPost(p) } } } } define outputPost(pst : Post) { navigate post(pst) { output(pst.name) } } define list() { <ul> elements </ul> } define listitem() { <li> elements </li> } define header() { <h1> elements </h1> } define page blog ( b : Blog ) { <h1> output(b.name) </h1> <ul> for ( p : Post in b.posts ) { <li> navigate post(p) { output(p.name) } </li> } </ul> }
  • 145. Inlining Templates with Parameters declare-inline : def@TemplateDef(mod*,f,param*,elem1*) -> def where rules( InlineTemplate : Call(f, e*, []) -> Call("container", [], elem3*) where elem3* := <substitute> (param*, e*, elem1*) ) substitute : (param*, e*, elem1*) -> elem2* where {| Subst : <zip(bind-arg)> (param*, e*) ; elem2* := <alltd(Subst)> elem1* |} bind-arg : (Param(x, t), e) -> (Param(x, t), e) where rules( Subst : Var(x) -> e )
  • 146. Element Parameters define list() { <ul> elements </ul> } declare-inline : def@TemplateDef(mod*,f,param*,elem1*) -> def where rules( InlineTemplate : Call(f, e*, elem2*) -> Call("container", [], elem3*) where {| Subst : rules( Subst : Elements() -> Call("container",[],elem2*) ) ; elem3* := <substitute> (param*, e*, elem1*) |} )
  • 147. Removing Intermediate Structures rules // remove containers desugar-container : [Call("container",[], elem1*) | elem2*] -> [elem1*, elem2*] desugar : elem1* -> elem2* where elem2* := <at-suffix(desugar-container)> elem1* container needed to replace single call with multiple elements
  • 148. Inlining Strategy module template-inlining imports libstratego-lib imports include/nwl imports desugar strategies inline-all = desugar-all; alltd(declare-inline); innermost(desugar <+ InlineTemplate) rules declare-inline : ...
  • 149. module template-inlining imports libstratego-lib imports include/nwl imports desugar strategies inline-all = desugar-all; alltd(declare-inline); innermost(desugar <+ InlineTemplate) rules declare-inline : TemplateDef(mod*,f,param*,elem1*) -> TemplateDef(mod*,f,param*,elem1*) where rules( InlineTemplate : Call(f, e*, elem2*) -> Call("container", [], elem3*) Template Inlining where {| Subst : rules( Subst : Elements() -> Call("container", [], elem2*) ) ; elem3* := <substitute> (param*, e*, elem1*) Transformation ) |} substitute : (param*, e*, elem1*) -> elem2* where {| Subst : <zip(bind-arg)> (param*, e*) ; elem2* := <alltd(Subst)> elem1* |} bind-arg : (Param(x, t), e) -> (Param(x, t), e) where rules( Subst : Var(x) -> e ) rules // remove containers desugar-container : [Call("container",[], elem1*) | elem2*] -> [elem1*, elem2*] desugar : elem1* -> elem2* where elem2* := <at-suffix(desugar-container)> elem1*