Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Model-Driven Software Development - Pretty-Printing, Editor Services, Term Rewriting

1,946 views

Published on

Model-Driven Software Development, Pretty-Printing, Editor Services, Term Rewriting

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Model-Driven Software Development - Pretty-Printing, Editor Services, Term Rewriting

  1. 1. Pretty-Printing Editor Services Term Rewriting Lecture 7 Course IN4308 Eelco Visser Master Computer Science http://eelcovisser.org Delft University of Technology
  2. 2. Outline Pretty-printing ★ from abstract syntax to concrete syntax Editor services ★ defining the behavior of editors Term rewriting ★ transforming abstract syntax
  3. 3. Pretty-Printing
  4. 4. Pretty-Printing: Abstract to Concrete Syntax While( BinOp(Var("x"), "<", IntLit("3")) , Block( [Assign( Var("x") , BinOp(Var("x"), "+", IntLit("1")) )] ) ) while ( (x < 3) ) { x := (x + 1) ; }
  5. 5. 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) { }
  6. 6. Syntax of Statements module statements exports sorts Statement context-free syntax Exp ":=" Exp ";" -> Statement {cons("Assign")} Exp ";" -> Statement {cons("ExpStat")} "return" PageRef ";" -> Statement {cons("ReturnPage")} "{" Statement* "}" -> Block {cons("Block")} Block -> Statement sorts VarDecl context-free syntax "var" ID ":" Type -> VarDecl {cons("VarDecl")} "var" ID ":" Type ":=" Exp -> VarDecl {cons("VarDeclInit")} VarDecl ";" -> Statement {cons("Stat")} "var" -> ID {reject} context-free syntax "for" "(" ID ":" Type "in" Exp ")" Block -> Statement {cons("For")} "while" "(" Exp ")" Block -> Statement {cons("While")} "if" "(" Exp ")" Block "else" Block -> Statement {cons("If")}
  7. 7. Pretty-Print Table context-free syntax Exp ":=" Exp ";" -> Statement {cons("Assign")} "{" Statement* "}" -> Block {cons("Block")} Block -> Statement "while" "(" Exp ")" Block -> Statement {cons("While")} [ ... Assign -- H[ _1 KW[":="] _2 KW[";"] ], Block -- V[ V is=2[ KW["{"] _1] KW["}"]], Block.1:iter-star -- _1, While -- V[ H[KW["while"] KW["("] _1 KW[")"]] _2], ... ] mapping constructors to text
  8. 8. Formatting with Box Expressions context-free syntax Exp ":=" Exp ";" -> Statement {cons("Assign")} "{" Statement* "}" -> Block {cons("Block")} Block -> Statement "while" "(" Exp ")" Block -> Statement {cons("While")} [ ... Assign -- H[ _1 KW[":="] _2 KW[";"] ], Block -- V[ V is=2[ KW["{"] _1] KW["}"]], Block.1:iter-star -- _1, While -- V[ H[KW["while"] KW["("] _1 KW[")"]] _2], ... ]
  9. 9. Pretty-Printing: Term to Box to Text While( BinOp(Var("x"), "<", IntLit("3")) , Block( [Assign( Var("x") , BinOp(Var("x"), "+", IntLit("1")) )] ) ) V[H[KW["while"] KW["("] ... KW[")"]] V[V is=2[KW["{"] ... ] KW["}"]] while ( (x < 3) ) ] { x := (x + 1) ; }
  10. 10. Generated Pretty-Print Table [ ... Assign -- _1 KW[":="] _2 KW[";"], ExpStat -- _1 KW[";"], ReturnPage -- KW["return"] _1 KW[";"], Block -- KW["{"] _1] KW["}"], Block.1:iter-star -- _1, VarDecl -- KW["var"] _1 KW[":"] _2, VarDeclInit -- KW["var"] _1 KW[":"] _2 KW[":="] _3, Stat -- _1 KW[";"], For -- KW["for"] KW["("] _1 KW[":"] _2 KW["in"] _3 KW[")"] _4, While -- KW["while"] KW["("] _1 KW[")"] _2], If -- KW["if"] KW["("] _1 KW[")"] _2 KW["else"] _3, ... ]
  11. 11. Pretty-Print Table with Box Markup [ ... Assign -- H[_1 KW[":="] _2 KW[";"]], ExpStat -- H hs=0[_1 KW[";"]], ReturnPage -- H hs=0 [KW["return"] _1 KW[";"]], Block -- V [V is=2 [KW["{"] _1] KW["}"]], Block.1:iter-star -- _1, VarDecl -- H [KW["var"] _1 KW[":"] _2], VarDeclInit -- H [KW["var"] _1 KW[":"] _2 KW[":="] _3], Stat -- H hs=0 [_1 KW[";"]], For -- V[H[KW["for"] KW["("] _1 KW[":"] _2 KW["in"] _3 KW[")"]] _4], While -- V[H[KW["while"] KW["("] _1 KW[")"]] _2], If -- V [ V is=2[ H[KW["if"] KW["("] _1 KW[")"]] _2] V is=2[ KW["else"] _3]], ... ]
  12. 12. Presentational Editor Services
  13. 13. 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
  14. 14. 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
  15. 15. Syntax Definition Default Syntax Default Default Highlighting Code Folding Outline View Custom Syntax Custom Custom + Highlighting + Code Folding + Outline View Editor
  16. 16. 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
  17. 17. 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
  18. 18. 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 = _
  19. 19. Custom Syntax Highlighting module nwl-Colorer imports nwl-Colorer.generated colorer Element : darkgreen
  20. 20. 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_]+"
  21. 21. Builders Semantic Editor Services
  22. 22. 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)
  23. 23. Term Rewriting
  24. 24. Term Rewriting Term rewrite rules ★ transform term to term ★ pattern matching ★ variable binding ★ substitution Rewriting strategy ★ algorithm for applying rewrite rules
  25. 25. Grammar to Signature context-free syntax "entity" ID "{" Property* "}" -> Definition {cons("Entity")} ID ":" Type -> Property {cons("Property")} ID ":" Type "(" {Annotation ","}* ")" -> Property {cons("Property")} module nwl signature constructors Entity : ID * List(Property) -> Definition Property : ID * Type * List(Annotation) -> Property Property : ID * Type -> Property
  26. 26. Desugaring: Syntactic Normalization Entity("Blog" , [ Property("url", SimpleType("String"), [Id()]) , Property("name", SimpleType("String"), [Name()]) , Property("posts", SetType(SimpleType("Post"))) , Property("author", SimpleType("User")) ] ) Entity("Blog" , [ Property("url", SimpleType("String"), [Id()]) , Property("name", SimpleType("String"), [Name()]) , Property("posts", SetType(SimpleType("Post")), []) , Property("author", SimpleType("User"), []) ] )
  27. 27. Term Rewriting in Stratego import signature module desugar imports include/nwl rewrite rule rules desugar : Property(x, t) -> Property(x, t, []) strategies desugar-all = innermost(desugar) strategy
  28. 28. Term Rewrite Rule left-hand side pattern label/name desugar : Property(x, t) -> Property(x, t, []) variable right-hand side pattern
  29. 29. Rewrite Rule Application Property("author", SimpleType("User")) pattern variable matching binding desugar : Property(x, t) -> Property(x, t, []) pattern substitution instantiation Property("author", SimpleType("User"), [])
  30. 30. 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
  31. 31. More Syntactic Normalizations rules desugar : CallArgs(x, e*) -> Call(x, e*, []) desugar : CallElems(x, elem*) -> Call(x, [], elem*) desugar : Call(x) -> Call(x, [], []) desugar : Property(x, t) -> Property(x, t, [])
  32. 32. Generic Representation for Binary Operators signature constructors BinOp : Exp * Op * Exp -> Exp rules desugar : Lt(e1, e2) -> BinOp(e1, "<", e2) desugar : Plus(e1, e2) -> BinOp(e1, "+", e2) desugar : Times(e1, e2) -> BinOp(e1, "*", e2) desugar : UnaryMinus(e) -> BinOp(IntLit("0"), "-", e)
  33. 33. x := a + b * 3 / c; Assign( Var("x") , Plus( Var("a") , Div(Times(Var("b"), IntLit("3")), Var("c")) parse ) ) Assign( Var("x") , BinOp( Var("a") , "+" , BinOp( BinOp(Var("b"), "+", IntLit("3")) desugar , "/" , Var("c") ) ) )
  34. 34. Applying Transformation in Editor
  35. 35. Binding Transformation to Editor Service editor interface behavior module nwl-Builders builders builder : "Desugar (selection)" = show-desugared (openeditor) (realtime) (meta) Stratego interface standard calling convention for builders rules show-desugared : (selected, position, ast, path, project-path) -> (filename, result-string) with filename := <guarantee-extension(|"aterm")> path; result-string := <desugar-all; pp-aterm-box; box2text-string(|120)> selected transformation
  36. 36. 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
  37. 37. 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))
  38. 38. 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))
  39. 39. For to While action foo() { for(p : Post in b.posts) { p.title := "foo"; } action foo ( ) { } var i : Int := 0; var c : Set<Post> := b.posts; var l : Int := c.length(); while (i < l) { var p : Post := c[i]; p.title := "foo" ; i := i + 1; } } specification (by example)
  40. 40. For to While: Transformation Schema for(x : t in e) b var i : Int := 0; var c : Set<t> := e; var l : Int := c.length(); while (i < l) { var x : t := c[i]; b i := i + 1; } abstraction of example
  41. 41. For to While: Rewrite Rule normalize : For(x, t, e, b) -> Block([ Stat(VarDeclInit(i, SimpleType("Int"), IntLit("0"))), Stat(VarDeclInit(c, SimpleType(t), e)), Stat(VarDeclInit(l, SimpleType("Int"), MethodCall(Var(c), "length", []))), While(BinOp(Var(i), "<", Var(l)), Block([ Stat(VarDeclInit(x, t, IndexAccess(Var(c), Var(i)))), b, Assign(Var(i), BinOp(Var(i), "+", IntLit("1"))) ])) ]) where i := <newname> "i"; c := <newname> "c"; l := <newname> "l"
  42. 42. For to While: Result action foo() { specification by example for(p : Post in b.posts) { p.title := "foo"; action foo ( ) { } var i : Int := 0; } var c : Set<Post> := b.posts; var l : Int := c.length(); action foo ( ) { while (i < l) { { var p : Post := c[i]; var i0 : Int := 0; p.title := "foo" ; var c0 : Set<Post> := b.posts; i := i + 1; var l0 : Int := c0.length(); } while ( (i0 < l0) ) } { var p : Post := c0[i0]; p.title := "foo" ; i0 := (i0 + 1) ; } } } result
  43. 43. Normalization Strategy strategies normalize-all = innermost(desugar + normalize) rules normalize : For(x, t, e, b) -> Block([ Stat(VarDecl(... ]) normalize : [Block(stat1*) | stat2*] -> <conc> (stat1*, stat2*) (is that a correct transformation?)
  44. 44. For to While: Final Result action foo() { specification by example for(p : Post in b.posts) { p.title := "foo"; action foo ( ) { } var i : Int := 0; } var c : Set<Post> := b.posts; var l : Int := c.length(); while (i < l) { action foo ( ) { var p : Post := c[i]; var i0 : Int := 0; p.title := "foo" ; var c0 : Set<Post> := b.posts; i := i + 1; var l0 : Int := c0.length(); } while ( (i0 < l0) ) } { var p : Post := c0[i0]; p.title := "foo" ; i0 := (i0 + 1) ; } } result
  45. 45. Normalization Strategy strategies normalize-all = innermost(desugar + normalize) rules normalize : For(x, t, e, b) -> Block([ Stat(VarDecl(... ]) normalize : Block([Block(stat*)]) -> Block(stat*)
  46. 46. Schedule Lab this week ★ Design 1: deadline is April 1 ★ Design 2: what DSL will you design? Cases ★ Case 2: web abstractions ★ Deadline Case 2: April 8 ★ Case 3: Next ★ Lecture 8: code generation

×