model-driven software development - pretty-printing, editor services, term rewriting

46
Pretty-Printing Editor Services Term Rewriting Course IN4308 Master Computer Science Delft University of Technology Eelco Visser http://eelcovisser.org Lecture 7

Upload: eelco-visser

Post on 10-May-2015

1.680 views

Category:

Technology


2 download

DESCRIPTION

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

TRANSCRIPT

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

Pretty-PrintingEditor ServicesTerm Rewriting

Course IN4308Master Computer Science

Delft University of Technology

Eelco Visserhttp://eelcovisser.org

Lecture 7

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

Outline

Pretty-printing

★ from abstract syntax to concrete syntax

Editor services

★ defining the behavior of editors

Term rewriting

★ transforming abstract syntax

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

Pretty-Printing

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

While( BinOp(Var("x"), "<", IntLit("3")), Block( [Assign( Var("x") , BinOp(Var("x"), "+", IntLit("1")) )] ))

while ( (x < 3) ){ x := (x + 1) ;}

Pretty-Printing: Abstract to Concrete Syntax

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

Syntax Definition

Parse Table Signature Pretty-Print Table

TransformParse Pretty-Print

entity User { name :: String pw :: Secret}def output(u : User) {

@Entityclass User { String _user; public User getUser() { return _user; }syntax definition is basis of language definition

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

Syntax of Statements

module statementsexports 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")}

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

Pretty-Print Table

mapping constructors to text

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], ...]

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

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], ...]

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

While( BinOp(Var("x"), "<", IntLit("3")), Block( [Assign( Var("x") , BinOp(Var("x"), "+", IntLit("1")) )] ))

while ( (x < 3) ){ x := (x + 1) ;}

Pretty-Printing: Term to Box to Text

V[H[KW["while"] KW["("] ... KW[")"]] V[V is=2[KW["{"] ... ] KW["}"]]]

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

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, ...]

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

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]], ...]

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

Presentational

Editor Services

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

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

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

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

Editor Services Composition

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

Syntax Definition

Default Syntax Highlighting

Default Code Folding

DefaultOutline View

Editor

Custom Syntax Highlighting

CustomCode Folding

CustomOutline View+ + +

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

module nwl-Foldingimports nwl-Folding.generatedfolding Element.CallElems Element.Call Element.ForElem Element.ForAllElem

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

Code Folding

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

Outline View

module nwl-Outliner.generatedoutliner 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

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

module nwl-Colorer.generated colorer Default, token-based 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 = _

Default Syntax Highlighting

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

Custom Syntax Highlighting

module nwl-Colorerimports nwl-Colorer.generatedcolorer Element : darkgreen

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

Syntax Properties

module nwl-Syntax.generatedlanguage 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_]+"

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

BuildersSemantic Editor Services

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

Builders: Analysis & Transformation Services

module nwl-Buildersbuilders 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)

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

Term Rewriting

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

Term Rewriting

Term rewrite rules

★ transform term to term

★ pattern matching

★ variable binding

★ substitution

Rewriting strategy

★ algorithm for applying rewrite rules

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

Grammar to Signature

module nwlsignature constructors Entity : ID * List(Property) -> Definition Property : ID * Type * List(Annotation) -> Property Property : ID * Type -> Property

context-free syntax "entity" ID "{" Property* "}" -> Definition {cons("Entity")} ID ":" Type -> Property {cons("Property")} ID ":" Type "(" {Annotation ","}* ")" -> Property {cons("Property")}

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

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"), []) ])

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

Term Rewriting in Stratego

module desugar

imports include/nwl

rules

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

strategies

desugar-all = innermost(desugar)

import signature

strategy

rewrite rule

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

Term Rewrite Rule

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

label/name

left-hand side pattern

right-hand side patternvariable

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

Rewrite Rule Application

Property("author", SimpleType("User"))

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

pattern matching

variablebinding

Property("author", SimpleType("User"), [])

pattern instantiation substitution

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

Rewrite Strategy

desugar-all = innermost(desugar)

strategy definitiongeneric strategy

strategy instantiation

innermost(s) apply transformation s exhaustively to all sub-terms of subject term in bottom-up order

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

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, [])

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

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)

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

Assign( Var("x"), BinOp( Var("a") , "+" , BinOp( BinOp(Var("b"), "+", IntLit("3")) , "/" , Var("c") ) ))

Assign( Var("x"), Plus( Var("a") , Div(Times(Var("b"), IntLit("3")), Var("c")) ))

x := a + b * 3 / c;

parse

desugar

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

Applying Transformation in Editor

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

Binding Transformation to Editor Service

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

module nwl-Buildersbuilders builder : "Desugar (selection)" = show-desugared (openeditor) (realtime) (meta)

Stratego interface

editor interfacebehavior

transformation

standard calling convention for builders

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

Constant Folding

y := a + (3 * 5 - 17);

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

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

y := (a + 25);

desugar + eval

parse

pretty-print

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

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))

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

Conditional Rewrite Rules

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

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

match apply transformation

bound in condition

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

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)

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

For to While: Transformation Schema

for(x : t in e) bvar 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

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

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"

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

For to While: Result

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; }}

action foo ( ) { { var i0 : Int := 0; var c0 : Set<Post> := b.posts; var l0 : Int := c0.length(); while ( (i0 < l0) ) { var p : Post := c0[i0]; p.title := "foo" ; i0 := (i0 + 1) ; } }}

specification by example

result

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

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?)

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

For to While: Final Result

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; }}

action foo ( ) { var i0 : Int := 0; var c0 : Set<Post> := b.posts; var l0 : Int := c0.length(); while ( (i0 < l0) ) { var p : Post := c0[i0]; p.title := "foo" ; i0 := (i0 + 1) ; }}

specification by example

result

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

Normalization Strategy

strategies normalize-all = innermost(desugar + normalize)

rules normalize : For(x, t, e, b) -> Block([ Stat(VarDecl(... ])

normalize : Block([Block(stat*)]) -> Block(stat*)

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

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