SlideShare una empresa de Scribd logo
1 de 75
Descargar para leer sin conexión
Context-Sensitive Transformation
                         Lecture 8



                                               Course IN4308
     Eelco Visser
                                    Master Computer Science
http://eelcovisser.org          Delft University of Technology
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) {
                                                                              }
Coming up
Lecture 8: Context-sensitive transformation
   ★ design 2
   ★ transformation with dynamic rewrite rules

Lecture 9: Static analysis & error checking
   ★ name resolution, reference resolution
   ★ type analysis

Lecture 10: Code generation
   ★ string templates, code generation by model transformation
   ★ concrete object syntax

Lecture 11: Code generation strategies
   ★ customization of generated code
Outline


Design 2
   ★ designing a domain-specific language

Context-sensitive transformation
   ★ global-to-local, local-to-global

Rewriting strategies
   ★ controlling the application of rules

Dynamic rewrite rules
   ★ context-sensitive transformation with rewrite rules
Design 2
Build your own DSL
Design 2: Purpose


Design a domain-specific language
Domain analysis
   ★ find abstractions in an existing programming domain

Language design
   ★ define a notation and translational semantics

Language implementation
   ★ build IDE and code generator

Understand tradeoffs in language design
Design 2: Ingredients


Syntax definition
   ★ elegant and efficient notation for a domain

Model transformation
   ★ reduce rich surface syntax to core language

Static analysis
   ★ find errors during editing

Code generation
   ★ generate complete implementation from models
Design 2: Considerations

Type system
   ★ do you catch errors at compile-time (in the IDE)?

Customization
   ★ can application developers work around lack of coverage?

Native interface
   ★ how are models integrated with environment?

Modularity
   ★ can models be broken down into smaller components?

Incremental language processing
Design 2: Inductive (bottom-up) design



Finding abstractions
Identify coding patterns
   ★ are there standard patterns in programs in this domain

Identify commonality
   ★ code generation templates

Identify variability
   ★ language constructs
Design 2: Examples

Improve existing language
-   Software building DSL generating ANT

-   XML transformation DSL generating XSLT

Abstract from existing framework/library
-   DSL for Vaadin (http://vaadin.com)

-   Javascript widget DSL generating JQuery or Dojo

-   Game DSL generating Ogre C++

AndroidDSL
-   Generate Java for Android applications

-   Android & Nexus One phones available for experiments
JavaSwul
import javax.swing.*;
import java.awt.*;

public class Test3 {
  public static void main(String[] ps) {
                                                   import javax.swing.*;
    JFrame frame = frame {                         import java.awt.*;
       title = "Welcome!"                          public class Test3
       content = panel of border layout {          {
                                                     public static void main(String[] ps)
         center = label { text = "Hello World" }     {
                                                       JButton jButton_1;
         south = panel of grid layout {                JButton jButton_0;
                                                       JPanel jPanel_1;
           row = {                                     JLabel jLabel_0;
             button { text = "cancel" }                JPanel jPanel_0;
                                                       JFrame jFrame_0;
             button { text = "ok"}                     jFrame_0 = new JFrame();
                                                       jFrame_0.setTitle("Welcome!");
           }                                           jPanel_0 = new JPanel();
         }                                             BorderLayout borderLayout_0 = new BorderLayout();
                                                       jPanel_0.setLayout(borderLayout_0);
       }                                               jFrame_0.setContentPane(jPanel_0);
                                                       JFrame frame = jFrame_0;
    };                                                 jLabel_0 = new JLabel();
                                                       jLabel_0.setText("Hello World");
    frame.pack();                                      jPanel_0.add(jLabel_0, BorderLayout.CENTER);
    frame.setVisible(true);                            jPanel_1 = new JPanel();
                                                       GridLayout gridLayout_0 = new GridLayout(1, 2);
  }                                                    jButton_0 = new JButton();
                                                       jButton_0.setText("cancel");
}                                                      jButton_1 = new JButton();
                                                       jButton_1.setText("ok");
                                                       jPanel_1.setLayout(gridLayout_0);
                                                       jPanel_1.add(jButton_0);
                                                       jPanel_1.add(jButton_1);
                                                       jPanel_0.add(jPanel_1, BorderLayout.SOUTH);
                                                       frame.pack();
                                                       frame.setVisible(true);
                                                     }
                                                   }
private String[] initAddressList() {
             contactList.setContainerDataSource(addressBookData);


Vaadin
             contactList.setVisibleColumns(visibleCols);
             contactList.setSelectable(true);
             contactList.setImmediate(true);
             contactList.addListener(new Property.ValueChangeListener() {
                 public void valueChange(ValueChangeEvent event) {
                     Object id = contactList.getValue();
                     contactEditor.setItemDataSource(id == null ? null : contactList
                             .getItem(id));
                     contactRemovalButton.setVisible(id != null);
                 }
             });
             return visibleCols;
         }

         private void initFilteringControls() {
             for (final String pn : visibleCols) {
                 final TextField sf = new TextField();
                 bottomLeftCorner.addComponent(sf);
                 sf.setWidth("100%");
                 sf.setInputPrompt(pn);
                 sf.setImmediate(true);
                 bottomLeftCorner.setExpandRatio(sf, 1);
                 sf.addListener(new Property.ValueChangeListener() {
                     public void valueChange(ValueChangeEvent event) {
                         addressBookData.removeContainerFilters(pn);
                         if (sf.toString().length() > 0 && !pn.equals(sf.toString())) {
                             addressBookData.addContainerFilter(pn, sf.toString(),
                                      true, false);
                         }
                         getMainWindow().showNotification(
                                 "" + addressBookData.size() + " matches found");
                     }
                 });
             }
         }

         private static IndexedContainer createDummyData() {

             String[] fnames = { "Peter", "Alice", "Joshua", "Mike", "Olivia",
                     "Nina", "Alex", "Rita", "Dan", "Umberto", "Henrik", "Rene",
                     "Lisa", "Marge" };
             String[] lnames = { "Smith", "Gordon", "Simpson", "Brown", "Clavel",
                     "Simons", "Verne", "Scott", "Allison", "Gates", "Rowling",
                     "Barks", "Ross", "Schneider", "Tate" };
Design 2: Advice

Choosing a domain
-   choose a domain that you know or are interested to learn

Agile software development
-   identify iterations

-   minimize risks

-   create working version in first week and evolve

Proposal
-   don’t get stuck on it

-   choose a domain and go
Model Transformation
Compilation by Normalization
Types of Model Transformation

Reduction to sub-language
   ★ Normalization
   ★ Desugaring
   ★ Optimization
   ★ Aspect weaving
   ★ Instrumentation
   ★ Refactoring

Translation to another language
   ★ Conversion
   ★ Migration
   ★ Compilation
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 - 17);


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


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


                                                  y := (a + 25);
                                   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))
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*
Free Variable Capture
Free Variable Capture in Template Inlining
define page blogfront(b : Blog) {
  header{output(b.name)}
  list{
    for(p : Post in b.posts) {
      listitem{
        postInline(p) { par{ "Posted by " outputUser(p.author) } }
      }
    }
  }
}
define postInline(pst : Post) {
  header{output(pst.title)}
  output(pst.text)
  for(p : Tag in pst.tags) {
    elements
  }
}
Free Variable Capture in Template Inlining
define page blogfront(b : Blog) {
  header{output(b.name)}
  list{
    for(p : Post in b.posts) {
      listitem{
        postInline(p) { par{ "Posted by " outputUser(p.author) } }
                   define page blogfront(b : Blog) {
      }
                     <h1> output(b.name) </h1>
    }
                     <ul>
  }
                       for(p : Post in b.posts) {
}
                          <li>
define postInline(pst : Post) {
                            <h1>output(p.title)</h1>
  header{output(pst.title)}
                            output(p.text)
  output(pst.text)
                            for ( p : Tag in p.tags ) {
  for(p : Tag in pst.tags) {
                               <p>
    elements
                                 "Posted by "
  }
                                 navigate user(p.author) { output(p.author.name) }
}
                               </p>
                            }
                          </li>
                       }
                     </ul>
                   }
Free Variable Capture in Template Inlining


define page blogfront(b : Blog) {
  for(p : Post in b.posts) {
    postInline(p) { "Posted by " outputUser(p.author) }
  }
}
define postInline(pst : Post) {
  for(p : Tag in pst.tags) { output(p.name) elements }
}




                    define page blogfront(b : Blog) {
                      for(p : Post in b.posts) {
                        for(p : Tag in p.tags) {
                          output(p.name)
                          "Posted by "
                          navigate user(p.author) { output(p.author.name) }
                        }
                      }
                    }
Avoiding Free Variable Capture

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

substitute =
  alltd(Subst <+ rename-bound)

rename-bound :
  ForElem(x, t, e1, elem1*) -> ForElem(y, t, e2, elem2*)
  where {| Subst
         : y := <newname> x
         ; e2 := <substitute> e1
         ; rules( Subst : Var(x) -> Var(y) )
         ; elem2* := <substitute> elem1*
         |}



             rename bound variables
Free Variable Capture in Template Inlining


define page blogfront(b : Blog) {
  for(p : Post in b.posts) {
    postInline(p) { "Posted by " outputUser(p.author) }
  }
}
define postInline(pst : Post) {
  for(p : Tag in pst.tags) { output(p.name) elements }
}




                    define page blogfront(b : Blog) {
                      for(p : Post in b.posts) {
                        for(p3 : Tag in p.tags) {
                          output(p3.name)
                          "Posted by "
                          navigate user(p.author) { output(p.author.name) }
                        }
                      }
                    }
Aspect Weaving
Aspect Weaving



Aspect definition
   ★ modular definition of cross cutting concerns

Aspect weaving
   ★ apply aspects to base program

Applications
   ★ instrumentation for logging, tracing, debugging, profiling
   ★ access control, data validation, entity extension
Access Control Rules
define page post(p : Post) {
  header{output(p.title)}
  output(p.text)
  par{ "Posted by " outputUser(p.author) }
  navigate editpost(p) { "Edit" }
}

rule page editpost(pst : Post) {
  principal == pst.blog.author
}

define page editpost(p : Post) {
  action save() {
    return post(p);
  }
  header{output(p.title)}
  form{
    input(p.url)
    input(p.title)
    input(p.text)
    submit save() { "Save" }
  }
}
Access Control Weaving
define page post(p : Post) {
  header{output(p.title)}
  output(p.text)
  par{ "Posted by " outputUser(p.author) }
  navigate editpost(p) { "Edit" }
}

rule page editpost(pst : Post) {
  principal == pst.blog.author
}

define page editpost(p : Post) {
  action save() {
    return post(p);
  }
  header{output(p.title)}
  form{
    input(p.url)
    input(p.title)
    input(p.text)
    submit save() { "Save" }
  }
}
Access Control Weaving: Protect Page
define page post(p : Post) {
  header{output(p.title)}
  output(p.text)
  par{ "Posted by " outputUser(p.author) }
  navigate editpost(p) { "Edit" }
}
                                     define page editpost(p : Post) {
                                       init {
rule page editpost(pst : Post) {
                                         if(!(principal == pst.blog.author)) {
  principal == pst.blog.author
                                           return accessdenied() ;
}
                                         }
                                       }
define page editpost(p : Post) {
                                       action save() { return post(p) ; }
  action save() {
                                       header{output(p.title)}
    return post(p);
                                       form{
  }
                                         input(p.url)
  header{output(p.title)}
                                         input(p.title)
  form{
                                         input(p.text)
    input(p.url)
                                         submit save ( ) { "Save" }
    input(p.title)
                                       }
    input(p.text)
                                     }
    submit save() { "Save" }
  }
}
Access Control Weaving: Protect Link
define page post(p : Post) {
  header{output(p.title)}
  output(p.text)
  par{ "Posted by " outputUser(p.author) }
  navigate editpost(p) { "Edit" }
}
                                      define page editpost(p : Post) {
                                         init {
rule page editpost(pst : Post) {
                                           if(!(principal == pst.blog.author)) {
  principal == pst.blog.author
                                             return accessdenied() ;
}
                                           }
                                         }
define page editpost(p : Post) {
                                         action save() { return post(p) ; }
  action save() {
                                         header{output(p.title)}
    return post(p);
                                  define page post ( p : Post ) {
                                         form{
  }
                                       header{output(p.title)}
                                           input(p.url)
  header{output(p.title)}
                                       output(p.text)
                                           input(p.title)
  form{
                                       par{"Posted by "outputUser(p.author)}
                                           input(p.text)
    input(p.url)
                                       if(principal == ( ) { "Save" } {
                                           submit save p.blog.author)
    input(p.title)
                                         }navigate editpost(p) { "Edit" }
    input(p.text)
                                      }}
    submit save() { "Save" }
                                    }
  }
}
Access Control Weaving: Strategy




weave-ac-rules =
	 alltd(declare-ac-rule);
	 bottomup(try(ProtectPage <+ ProtectNavigate))
Access Control Weaving: Protect Navigate




declare-ac-rule :
	 r@Rule([Page()], f, param1*, e) -> r
	 where rules(
	    ProtectNavigate :
	      elem@Navigate(PageRef(f, e*), elem*) -> If(e2,Block([elem]),Block([]))
	      where e2 := <substitute-args> (param1*, e*, e)
	 )
Access Control Weaving: Protect Page


declare-ac-rule :
	 r@Rule([Page()], f, param1*, e) -> r
	 where rules(
     ProtectNavigate : ...

	       ProtectPage :
	         TemplateDef([Page()], f, param2*, elem*) ->
	         TemplateDef([Page()], f, param2*,
	           [Init([
               If(Not(e),
                  Block([ReturnPage(PageRef("accessdenied", []))]),
                  Block([]))]),
	            elem*])
	         where e2 := <substitute-args> (param1*, <map(param-to-exp)> param2*, e)
	   )

param-to-exp :
  Param(x, t) -> Var(x)
Access Control Weaving: Complete*
    weave-ac-rules =
    	   alltd(declare-ac-rule);
    	   bottomup(try(ProtectPage <+ ProtectNavigate))
    	
    declare-ac-rule :
    	   r@Rule([Page()], f, param1*, e) -> r
    	   where rules(
    	     ProtectPage :
    	       TemplateDef([Page()], f, param2*, elem1*) ->
    	       TemplateDef([Page()], f, param2*,
    	         [Init([
                If(Not(e),
                   Block([ReturnPage(PageRef("accessdenied", []))]),
                   Block([]))]),
    	          elem1*])
    	       where e2 := <substitute-args> (param1*, <map(param-to-exp)> param2*, e)
    	
    	     ProtectNavigate :
    	       elem@Navigate(PageRef(f, e*), elem*) -> If(e2,Block([elem]),Block([]))
    	       where e2 := <substitute-args> (param1*, e*, e)
    	   )
    	
    param-to-exp :
      Param(x, t) -> Var(x)




* complete specification for this limited example; WebDSL AC is more complex
Extend Entity

module blog

entity Post {
  url    : String (id)
  title : String (name)
  text   : WikiText
  blog   : Blog (inverse:posts)
  author : User
                  module tags
  blog   : Blog
}
                  entity Tag {
                    key    : String (id)
                    title : String (name)
                    text   : WikiText
                    posts : Set<Post>
                  }

                 extend entity Post {
                   tags : Set<Tag> (inverse:posts)
                 }

                modular extensibility => more cohesion (?)
Extend Entity                           module woven

                                            entity Post {
                                              url    : String (id)
                                              title : String (name)
module blog                                   text   : WikiText
                                              blog   : Blog (inverse:posts)
entity Post {                                 author : User
  url    : String (id)                        blog   : Blog
  title : String (name)                       tags : Set<Tag> (inverse:posts)
  text   : WikiText                         }
  blog   : Blog (inverse:posts)
  author : User                             entity Tag   {
                  module tags
  blog   : Blog                               key    :   String (id)
}                                             title :    String (name)
                  entity Tag {
                                              text   :   WikiText
                    key    : String (id)
                                              posts :    Set<Post>
                    title : String (name)
                                            }
                    text   : WikiText
                    posts : Set<Post>
                  }

                 extend entity Post {
                   tags : Set<Tag> (inverse:posts)
                 }

                modular extensibility => more cohesion (?)
Other Model
Transformations
Other Applications of Model Transformation

Refactoring
   ★ behaviour preserving transformation to improve design
   ★ e.g. extract/inline function/template/entity

Difference detection
   ★ detect differences between two models

Migration
   ★ update model to conform to new meta-model

Optimization
   ★ derive more efficient version
   ★ e.g. query prefetching
Schedule
Case 3
  ★ Syntax definition & term rewriting
  ★ Deadline:

Design 2
  ★ Make a proposal (can be submitted separately)
  ★ Deadline:

Lab this week
  ★ Install Spoofax
  ★ Make Case 3

Next
  ★ Lecture 9: static analysis

Más contenido relacionado

La actualidad más candente

Fee managment system
Fee managment systemFee managment system
Fee managment systemfairy9912
 
Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesKaniska Mandal
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql JOYITAKUNDU1
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbroncymbron
 
Linked In Presentation
Linked In PresentationLinked In Presentation
Linked In Presentationapweir12
 
C# Basics Quick Reference Sheet
C# Basics Quick Reference SheetC# Basics Quick Reference Sheet
C# Basics Quick Reference SheetFrescatiStory
 
ECOOP01 AOOSDM Poster.ppt
ECOOP01 AOOSDM Poster.pptECOOP01 AOOSDM Poster.ppt
ECOOP01 AOOSDM Poster.pptPtidej Team
 
2 introduction toentitybeans
2 introduction toentitybeans2 introduction toentitybeans
2 introduction toentitybeansashishkirpan
 
Wait queue
Wait queueWait queue
Wait queueRoy Lee
 
Advance Java Programming (CM5I) 1.AWT
Advance Java Programming (CM5I) 1.AWTAdvance Java Programming (CM5I) 1.AWT
Advance Java Programming (CM5I) 1.AWTPayal Dungarwal
 
Software Language Design & Engineering
Software Language Design & EngineeringSoftware Language Design & Engineering
Software Language Design & EngineeringEelco Visser
 

La actualidad más candente (20)

Fee managment system
Fee managment systemFee managment system
Fee managment system
 
Converting Db Schema Into Uml Classes
Converting Db Schema Into Uml ClassesConverting Db Schema Into Uml Classes
Converting Db Schema Into Uml Classes
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 
Oop bai10
Oop bai10Oop bai10
Oop bai10
 
Java File
Java FileJava File
Java File
 
Tdd.eng.ver
Tdd.eng.verTdd.eng.ver
Tdd.eng.ver
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbron
 
Linked In Presentation
Linked In PresentationLinked In Presentation
Linked In Presentation
 
C# Basics Quick Reference Sheet
C# Basics Quick Reference SheetC# Basics Quick Reference Sheet
C# Basics Quick Reference Sheet
 
Writing Good Tests
Writing Good TestsWriting Good Tests
Writing Good Tests
 
ECOOP01 AOOSDM Poster.ppt
ECOOP01 AOOSDM Poster.pptECOOP01 AOOSDM Poster.ppt
ECOOP01 AOOSDM Poster.ppt
 
gtk2-perl
gtk2-perlgtk2-perl
gtk2-perl
 
Elementary Sort
Elementary SortElementary Sort
Elementary Sort
 
2 introduction toentitybeans
2 introduction toentitybeans2 introduction toentitybeans
2 introduction toentitybeans
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Java: GUI
Java: GUIJava: GUI
Java: GUI
 
Wait queue
Wait queueWait queue
Wait queue
 
Advance Java Programming (CM5I) 1.AWT
Advance Java Programming (CM5I) 1.AWTAdvance Java Programming (CM5I) 1.AWT
Advance Java Programming (CM5I) 1.AWT
 
Software Language Design & Engineering
Software Language Design & EngineeringSoftware Language Design & Engineering
Software Language Design & Engineering
 
GUI programming
GUI programmingGUI programming
GUI programming
 

Destacado

Building DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language WorkbenchBuilding DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language WorkbenchEelco 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
 
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 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
 

Destacado (14)

Building DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language WorkbenchBuilding DSLs with the Spoofax Language Workbench
Building DSLs with the Spoofax Language Workbench
 
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
 
Code Generation
Code GenerationCode Generation
Code Generation
 
TI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific LanguagesTI1220 Lecture 14: Domain-Specific Languages
TI1220 Lecture 14: Domain-Specific Languages
 
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 a Context-Sensitive Transformation

20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docx
20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docx20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docx
20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docxAliHaiderCheema2
 
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdfimport java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdfvenkt12345
 
import javaawt import javaxswing import javaxswing.pdf
import javaawt import javaxswing import javaxswing.pdfimport javaawt import javaxswing import javaxswing.pdf
import javaawt import javaxswing import javaxswing.pdfADITIEYEWEAR
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo Ali Parmaksiz
 
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Anton Arhipov
 
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdfpackage net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdfsudhirchourasia86
 
AJP Practical Questions with Solution.docx
AJP Practical Questions with Solution.docxAJP Practical Questions with Solution.docx
AJP Practical Questions with Solution.docxRenuDeshmukh5
 
Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020Jerry Liao
 
Vaadin today and tomorrow
Vaadin today and tomorrowVaadin today and tomorrow
Vaadin today and tomorrowJoonas Lehtinen
 
Creating a Facebook Clone - Part V.pdf
Creating a Facebook Clone - Part V.pdfCreating a Facebook Clone - Part V.pdf
Creating a Facebook Clone - Part V.pdfShaiAlmog1
 
Ejemplo radio
Ejemplo radioEjemplo radio
Ejemplo radiolupe ga
 
jrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeusjrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeusTakeshi AKIMA
 

Similar a Context-Sensitive Transformation (20)

20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docx
20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docx20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docx
20-Arid-850 Ali Haider Cheema BSSE(5A) Evening MPL Assignement 08.docx
 
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdfimport java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
import java.awt.Color;import java.awt.Insets;import java.awt.Con.pdf
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Draw2D
Draw2DDraw2D
Draw2D
 
import javaawt import javaxswing import javaxswing.pdf
import javaawt import javaxswing import javaxswing.pdfimport javaawt import javaxswing import javaxswing.pdf
import javaawt import javaxswing import javaxswing.pdf
 
culadora cientifica en java
culadora cientifica en javaculadora cientifica en java
culadora cientifica en java
 
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo A GWT Application with MVP Pattern Deploying to CloudFoundry using  Spring Roo
A GWT Application with MVP Pattern Deploying to CloudFoundry using Spring Roo
 
Vaadin 7
Vaadin 7Vaadin 7
Vaadin 7
 
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012
 
Prog iv
Prog ivProg iv
Prog iv
 
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdfpackage net.codejava.swing.mail;import java.awt.Font;import java.pdf
package net.codejava.swing.mail;import java.awt.Font;import java.pdf
 
AJP Practical Questions with Solution.docx
AJP Practical Questions with Solution.docxAJP Practical Questions with Solution.docx
AJP Practical Questions with Solution.docx
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Stay with React.js in 2020
Stay with React.js in 2020Stay with React.js in 2020
Stay with React.js in 2020
 
Vaadin today and tomorrow
Vaadin today and tomorrowVaadin today and tomorrow
Vaadin today and tomorrow
 
Creating a Facebook Clone - Part V.pdf
Creating a Facebook Clone - Part V.pdfCreating a Facebook Clone - Part V.pdf
Creating a Facebook Clone - Part V.pdf
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Ejemplo radio
Ejemplo radioEjemplo radio
Ejemplo radio
 
Chap1 1.4
Chap1 1.4Chap1 1.4
Chap1 1.4
 
jrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeusjrubykaigi2010-lt-rubeus
jrubykaigi2010-lt-rubeus
 

Más de 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
 

Más de 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
 

Context-Sensitive Transformation

  • 1. Context-Sensitive Transformation Lecture 8 Course IN4308 Eelco Visser Master Computer Science http://eelcovisser.org Delft University of Technology
  • 2. 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) { }
  • 3. Coming up Lecture 8: Context-sensitive transformation ★ design 2 ★ transformation with dynamic rewrite rules Lecture 9: Static analysis & error checking ★ name resolution, reference resolution ★ type analysis Lecture 10: Code generation ★ string templates, code generation by model transformation ★ concrete object syntax Lecture 11: Code generation strategies ★ customization of generated code
  • 4. Outline Design 2 ★ designing a domain-specific language Context-sensitive transformation ★ global-to-local, local-to-global Rewriting strategies ★ controlling the application of rules Dynamic rewrite rules ★ context-sensitive transformation with rewrite rules
  • 6. Design 2: Purpose Design a domain-specific language Domain analysis ★ find abstractions in an existing programming domain Language design ★ define a notation and translational semantics Language implementation ★ build IDE and code generator Understand tradeoffs in language design
  • 7. Design 2: Ingredients Syntax definition ★ elegant and efficient notation for a domain Model transformation ★ reduce rich surface syntax to core language Static analysis ★ find errors during editing Code generation ★ generate complete implementation from models
  • 8. Design 2: Considerations Type system ★ do you catch errors at compile-time (in the IDE)? Customization ★ can application developers work around lack of coverage? Native interface ★ how are models integrated with environment? Modularity ★ can models be broken down into smaller components? Incremental language processing
  • 9. Design 2: Inductive (bottom-up) design Finding abstractions Identify coding patterns ★ are there standard patterns in programs in this domain Identify commonality ★ code generation templates Identify variability ★ language constructs
  • 10. Design 2: Examples Improve existing language - Software building DSL generating ANT - XML transformation DSL generating XSLT Abstract from existing framework/library - DSL for Vaadin (http://vaadin.com) - Javascript widget DSL generating JQuery or Dojo - Game DSL generating Ogre C++ AndroidDSL - Generate Java for Android applications - Android & Nexus One phones available for experiments
  • 11. JavaSwul import javax.swing.*; import java.awt.*; public class Test3 { public static void main(String[] ps) { import javax.swing.*; JFrame frame = frame { import java.awt.*; title = "Welcome!" public class Test3 content = panel of border layout { { public static void main(String[] ps) center = label { text = "Hello World" } { JButton jButton_1; south = panel of grid layout { JButton jButton_0; JPanel jPanel_1; row = { JLabel jLabel_0; button { text = "cancel" } JPanel jPanel_0; JFrame jFrame_0; button { text = "ok"} jFrame_0 = new JFrame(); jFrame_0.setTitle("Welcome!"); } jPanel_0 = new JPanel(); } BorderLayout borderLayout_0 = new BorderLayout(); jPanel_0.setLayout(borderLayout_0); } jFrame_0.setContentPane(jPanel_0); JFrame frame = jFrame_0; }; jLabel_0 = new JLabel(); jLabel_0.setText("Hello World"); frame.pack(); jPanel_0.add(jLabel_0, BorderLayout.CENTER); frame.setVisible(true); jPanel_1 = new JPanel(); GridLayout gridLayout_0 = new GridLayout(1, 2); } jButton_0 = new JButton(); jButton_0.setText("cancel"); } jButton_1 = new JButton(); jButton_1.setText("ok"); jPanel_1.setLayout(gridLayout_0); jPanel_1.add(jButton_0); jPanel_1.add(jButton_1); jPanel_0.add(jPanel_1, BorderLayout.SOUTH); frame.pack(); frame.setVisible(true); } }
  • 12. private String[] initAddressList() { contactList.setContainerDataSource(addressBookData); Vaadin contactList.setVisibleColumns(visibleCols); contactList.setSelectable(true); contactList.setImmediate(true); contactList.addListener(new Property.ValueChangeListener() { public void valueChange(ValueChangeEvent event) { Object id = contactList.getValue(); contactEditor.setItemDataSource(id == null ? null : contactList .getItem(id)); contactRemovalButton.setVisible(id != null); } }); return visibleCols; } private void initFilteringControls() { for (final String pn : visibleCols) { final TextField sf = new TextField(); bottomLeftCorner.addComponent(sf); sf.setWidth("100%"); sf.setInputPrompt(pn); sf.setImmediate(true); bottomLeftCorner.setExpandRatio(sf, 1); sf.addListener(new Property.ValueChangeListener() { public void valueChange(ValueChangeEvent event) { addressBookData.removeContainerFilters(pn); if (sf.toString().length() > 0 && !pn.equals(sf.toString())) { addressBookData.addContainerFilter(pn, sf.toString(), true, false); } getMainWindow().showNotification( "" + addressBookData.size() + " matches found"); } }); } } private static IndexedContainer createDummyData() { String[] fnames = { "Peter", "Alice", "Joshua", "Mike", "Olivia", "Nina", "Alex", "Rita", "Dan", "Umberto", "Henrik", "Rene", "Lisa", "Marge" }; String[] lnames = { "Smith", "Gordon", "Simpson", "Brown", "Clavel", "Simons", "Verne", "Scott", "Allison", "Gates", "Rowling", "Barks", "Ross", "Schneider", "Tate" };
  • 13. Design 2: Advice Choosing a domain - choose a domain that you know or are interested to learn Agile software development - identify iterations - minimize risks - create working version in first week and evolve Proposal - don’t get stuck on it - choose a domain and go
  • 16. Types of Model Transformation Reduction to sub-language ★ Normalization ★ Desugaring ★ Optimization ★ Aspect weaving ★ Instrumentation ★ Refactoring Translation to another language ★ Conversion ★ Migration ★ Compilation
  • 18. Term Rewriting Term rewrite rules ★ transform term to term ★ pattern matching ★ variable binding ★ substitution Rewriting strategy ★ algorithm for applying rewrite rules
  • 19. Term Rewrite Rule left-hand side pattern label/name desugar : Property(x, t) -> Property(x, t, []) variable right-hand side pattern
  • 20. 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
  • 21. Constant Folding y := a + (3 * 5 - 17); Assign( Var("y") , Plus( Var("a") , Minus(Times(IntLit("3"), IntLit("5")), IntLit("17")) parse ) ) Assign( Var("y") , BinOp(Var("a"), "+", IntLit("25")) desugar + eval ) y := (a + 25); pretty-print
  • 22. 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))
  • 23. 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))
  • 25. 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> }
  • 26. 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
  • 27. 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> }
  • 28. 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)
  • 29. Rewrite Rules are Context-free desugar : Property(x, t) -> Property(x, t, [])
  • 30. 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” } } }
  • 31. 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
  • 33. transformation is partial* function from terms to terms * transformation may fail to apply to a term
  • 34. 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
  • 35. Strategy Combinators id ★ Identity fail ★ failure s1 ; s2 ★ sequential composition s1 <+ s2 ★ choice
  • 36. 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
  • 37. 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
  • 38. Rewrite in Context Inline : [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1* bound in context
  • 39. 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*
  • 40. 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))
  • 41. 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)]
  • 42. 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
  • 43. 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
  • 44. Rewrite in Context: Local Traversal Inline : [def@TemplateDef(f,[],elem1*) | def1*] -> [def | def2*] where def2* := <alltd((Call(f) -> Call("container", elem1*)))> def1* local traversal
  • 46. 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
  • 47. 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)
  • 48. 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)
  • 49. 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> }
  • 50. 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 )
  • 51. 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*) |} )
  • 52. 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
  • 53. 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 : ...
  • 54. 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*
  • 56. Free Variable Capture in Template Inlining define page blogfront(b : Blog) { header{output(b.name)} list{ for(p : Post in b.posts) { listitem{ postInline(p) { par{ "Posted by " outputUser(p.author) } } } } } } define postInline(pst : Post) { header{output(pst.title)} output(pst.text) for(p : Tag in pst.tags) { elements } }
  • 57. Free Variable Capture in Template Inlining define page blogfront(b : Blog) { header{output(b.name)} list{ for(p : Post in b.posts) { listitem{ postInline(p) { par{ "Posted by " outputUser(p.author) } } define page blogfront(b : Blog) { } <h1> output(b.name) </h1> } <ul> } for(p : Post in b.posts) { } <li> define postInline(pst : Post) { <h1>output(p.title)</h1> header{output(pst.title)} output(p.text) output(pst.text) for ( p : Tag in p.tags ) { for(p : Tag in pst.tags) { <p> elements "Posted by " } navigate user(p.author) { output(p.author.name) } } </p> } </li> } </ul> }
  • 58. Free Variable Capture in Template Inlining define page blogfront(b : Blog) { for(p : Post in b.posts) { postInline(p) { "Posted by " outputUser(p.author) } } } define postInline(pst : Post) { for(p : Tag in pst.tags) { output(p.name) elements } } define page blogfront(b : Blog) { for(p : Post in b.posts) { for(p : Tag in p.tags) { output(p.name) "Posted by " navigate user(p.author) { output(p.author.name) } } } }
  • 59. Avoiding Free Variable Capture substitute-args : (param*, e*, elem1*) -> elem2* where {| Subst : <zip(bind-arg)> (param*, e*) ; elem2* := <substitute> elem1* |} substitute = alltd(Subst <+ rename-bound) rename-bound : ForElem(x, t, e1, elem1*) -> ForElem(y, t, e2, elem2*) where {| Subst : y := <newname> x ; e2 := <substitute> e1 ; rules( Subst : Var(x) -> Var(y) ) ; elem2* := <substitute> elem1* |} rename bound variables
  • 60. Free Variable Capture in Template Inlining define page blogfront(b : Blog) { for(p : Post in b.posts) { postInline(p) { "Posted by " outputUser(p.author) } } } define postInline(pst : Post) { for(p : Tag in pst.tags) { output(p.name) elements } } define page blogfront(b : Blog) { for(p : Post in b.posts) { for(p3 : Tag in p.tags) { output(p3.name) "Posted by " navigate user(p.author) { output(p.author.name) } } } }
  • 62. Aspect Weaving Aspect definition ★ modular definition of cross cutting concerns Aspect weaving ★ apply aspects to base program Applications ★ instrumentation for logging, tracing, debugging, profiling ★ access control, data validation, entity extension
  • 63. Access Control Rules define page post(p : Post) { header{output(p.title)} output(p.text) par{ "Posted by " outputUser(p.author) } navigate editpost(p) { "Edit" } } rule page editpost(pst : Post) { principal == pst.blog.author } define page editpost(p : Post) { action save() { return post(p); } header{output(p.title)} form{ input(p.url) input(p.title) input(p.text) submit save() { "Save" } } }
  • 64. Access Control Weaving define page post(p : Post) { header{output(p.title)} output(p.text) par{ "Posted by " outputUser(p.author) } navigate editpost(p) { "Edit" } } rule page editpost(pst : Post) { principal == pst.blog.author } define page editpost(p : Post) { action save() { return post(p); } header{output(p.title)} form{ input(p.url) input(p.title) input(p.text) submit save() { "Save" } } }
  • 65. Access Control Weaving: Protect Page define page post(p : Post) { header{output(p.title)} output(p.text) par{ "Posted by " outputUser(p.author) } navigate editpost(p) { "Edit" } } define page editpost(p : Post) { init { rule page editpost(pst : Post) { if(!(principal == pst.blog.author)) { principal == pst.blog.author return accessdenied() ; } } } define page editpost(p : Post) { action save() { return post(p) ; } action save() { header{output(p.title)} return post(p); form{ } input(p.url) header{output(p.title)} input(p.title) form{ input(p.text) input(p.url) submit save ( ) { "Save" } input(p.title) } input(p.text) } submit save() { "Save" } } }
  • 66. Access Control Weaving: Protect Link define page post(p : Post) { header{output(p.title)} output(p.text) par{ "Posted by " outputUser(p.author) } navigate editpost(p) { "Edit" } } define page editpost(p : Post) { init { rule page editpost(pst : Post) { if(!(principal == pst.blog.author)) { principal == pst.blog.author return accessdenied() ; } } } define page editpost(p : Post) { action save() { return post(p) ; } action save() { header{output(p.title)} return post(p); define page post ( p : Post ) { form{ } header{output(p.title)} input(p.url) header{output(p.title)} output(p.text) input(p.title) form{ par{"Posted by "outputUser(p.author)} input(p.text) input(p.url) if(principal == ( ) { "Save" } { submit save p.blog.author) input(p.title) }navigate editpost(p) { "Edit" } input(p.text) }} submit save() { "Save" } } } }
  • 67. Access Control Weaving: Strategy weave-ac-rules = alltd(declare-ac-rule); bottomup(try(ProtectPage <+ ProtectNavigate))
  • 68. Access Control Weaving: Protect Navigate declare-ac-rule : r@Rule([Page()], f, param1*, e) -> r where rules( ProtectNavigate : elem@Navigate(PageRef(f, e*), elem*) -> If(e2,Block([elem]),Block([])) where e2 := <substitute-args> (param1*, e*, e) )
  • 69. Access Control Weaving: Protect Page declare-ac-rule : r@Rule([Page()], f, param1*, e) -> r where rules( ProtectNavigate : ... ProtectPage : TemplateDef([Page()], f, param2*, elem*) -> TemplateDef([Page()], f, param2*, [Init([ If(Not(e), Block([ReturnPage(PageRef("accessdenied", []))]), Block([]))]), elem*]) where e2 := <substitute-args> (param1*, <map(param-to-exp)> param2*, e) ) param-to-exp : Param(x, t) -> Var(x)
  • 70. Access Control Weaving: Complete* weave-ac-rules = alltd(declare-ac-rule); bottomup(try(ProtectPage <+ ProtectNavigate)) declare-ac-rule : r@Rule([Page()], f, param1*, e) -> r where rules( ProtectPage : TemplateDef([Page()], f, param2*, elem1*) -> TemplateDef([Page()], f, param2*, [Init([ If(Not(e), Block([ReturnPage(PageRef("accessdenied", []))]), Block([]))]), elem1*]) where e2 := <substitute-args> (param1*, <map(param-to-exp)> param2*, e) ProtectNavigate : elem@Navigate(PageRef(f, e*), elem*) -> If(e2,Block([elem]),Block([])) where e2 := <substitute-args> (param1*, e*, e) ) param-to-exp : Param(x, t) -> Var(x) * complete specification for this limited example; WebDSL AC is more complex
  • 71. Extend Entity module blog entity Post { url : String (id) title : String (name) text : WikiText blog : Blog (inverse:posts) author : User module tags blog : Blog } entity Tag { key : String (id) title : String (name) text : WikiText posts : Set<Post> } extend entity Post { tags : Set<Tag> (inverse:posts) } modular extensibility => more cohesion (?)
  • 72. Extend Entity module woven entity Post { url : String (id) title : String (name) module blog text : WikiText blog : Blog (inverse:posts) entity Post { author : User url : String (id) blog : Blog title : String (name) tags : Set<Tag> (inverse:posts) text : WikiText } blog : Blog (inverse:posts) author : User entity Tag { module tags blog : Blog key : String (id) } title : String (name) entity Tag { text : WikiText key : String (id) posts : Set<Post> title : String (name) } text : WikiText posts : Set<Post> } extend entity Post { tags : Set<Tag> (inverse:posts) } modular extensibility => more cohesion (?)
  • 74. Other Applications of Model Transformation Refactoring ★ behaviour preserving transformation to improve design ★ e.g. extract/inline function/template/entity Difference detection ★ detect differences between two models Migration ★ update model to conform to new meta-model Optimization ★ derive more efficient version ★ e.g. query prefetching
  • 75. Schedule Case 3 ★ Syntax definition & term rewriting ★ Deadline: Design 2 ★ Make a proposal (can be submitted separately) ★ Deadline: Lab this week ★ Install Spoofax ★ Make Case 3 Next ★ Lecture 9: static analysis