Grammarware Memes

943 views
789 views

Published on

Slides for mini-tutorial at the International Conference on Sofware Language Engineering (SLE 2012) in Dresden, Germany, September 27, 2012.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
943
On SlideShare
0
From Embeds
0
Number of Embeds
203
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Grammarware Memes

  1. 1. Grammarware Memes Eelco Visser & Guido Wachsmuth
  2. 2. Background
  3. 3. Spoofax Language Workbench
  4. 4. WebDSL Web Programming Language define page post(p: Post, title: String) { init{ p.update(); } title{ output(p.title) } bloglayout(p.blog){ placeholder view { postView(p) } postComments(p) } } define ajax postView(p: Post) { pageHeader2{ output(p.title) } postBodyLayout(p) { postContent(p) postExtendedContent(p) postActions(p) } }
  5. 5. Researchr Bibliography Management System
  6. 6. WebLab Programming Education on the Web
  7. 7. Some Philosophical Considerations
  8. 8. Grammarware vs Modelware? GPCE MODELSOOPSLA ICMT
  9. 9. Grammarware vs Modelware? GPCE MODELS SLEOOPSLA ICMT
  10. 10. Functional vs Object-Oriented vs Logic vs ...
  11. 11. Remember the Programming Language Wars? ICFP OOPSLA
  12. 12. Remember the Programming Language Wars? ICFP GPCE OOPSLA
  13. 13. Scala: Object-Oriented or Functional?‘closure’: a purely functional feature?
  14. 14. X-ware is a Memeplexmemeplex: selection of memes from the meme pool
  15. 15. What is Grammarware?
  16. 16. Grammarware is about (Parsing) Text module users imports library entity User { email : String password : String isAdmin : Bool }
  17. 17. Grammarware is about StructureModule( "users", [ Imports("library") , Entity( "User" , [ Property("email", Type("String")) , Property("password", Type("String")) , Property("isAdmin", Type("Bool")) ] ) ])
  18. 18. Grammarware: Text & Structure
  19. 19. Grammarware is about Transformation
  20. 20. Source to Source Transformation
  21. 21. Source to Source Transformation
  22. 22. Transformation & Analysis name resolution type checking desugaring code generation
  23. 23. Some Memes fromthe Spoofax Memeplex
  24. 24. EnFun: Entities with Functions module blog entity String { function plus(that:String): String } entity Bool { } entity Set<T> { function add(x: T) function remove(x: T) function member(x: T): Bool } entity Blog { posts : Set<Post> function newPost(): Post { var p : Post := Post.new(); posts.add(p); } } entity Post { title : String }
  25. 25. Structure
  26. 26. Signature & Termsconstructors Module : ID * List(Definition) -> Module Imports : ID -> Definition Module( "application" , [Imports("library"), Imports("users"), Imports("frontend")] )
  27. 27. Entities & Propertiesconstructors Entity : ID * List(Property) -> Definition Type : ID -> Type New : Type -> Expconstructors Property : ID * Type -> Property This : Exp PropAccess : Exp * ID -> ExpModule("users", [ Imports("library") , Entity("User" , [ Property("email", Type("String")) , Property("password", Type("String")) , Property("isAdmin", Type("Bool"))])])
  28. 28. Constants & Operators & Variablesconstructors constructors String : STRING -> Exp Geq : Exp * Exp -> Exp Int : INT -> Exp Leq : Exp * Exp -> Exp False : Exp Gt : Exp * Exp -> Exp True : Exp Lt : Exp * Exp -> Exp Eq : Exp * Exp -> Exp Mul : Exp * Exp -> Exp Minus : Exp * Exp -> Exp Plus : Exp * Exp -> Exp Or : Exp * Exp -> Exp And : Exp * Exp -> Exp Not : Exp -> Exp constructors VarDecl : ID * Type -> Stat VarDeclInit : ID * Type * Exp -> Stat Assign : Exp * Exp -> Stat Var : ID -> Exp
  29. 29. Statements & Functionsconstructors Exp : Exp -> Stat Block : List(Stat) -> Stat Seq : List(Stat) -> Stat While : Exp * List(Stat) -> Stat IfElse : Exp * List(Stat) * List(ElseIf) * Option(Else) -> Stat Else : List(Stat) -> Else ElseIf : Exp * List(Stat) -> ElseIfconstructors FunDef : ID * List(Arg) * Type * List(Stat) -> Property FunDecl : ID * List(Arg) * Type -> Property Arg : ID * Type -> Arg Return : Exp -> Stat MethCall : Exp * ID * List(Exp) -> Exp ThisCall : ID * List(Exp) -> Exp
  30. 30. Transformation
  31. 31. Transformation by Strategic Rewriting rules desugar: Plus(e1, e2) -> MethCall(e1, "plus", [e2]) desugar: Or(e1, e2) -> MethCall(e1, "or", [e2]) desugar : VarDeclInit(x, t, e) -> Seq([VarDecl(x, t), Assign(Var(x), e)]) strategies desugar-all = topdown(repeat(desugar))
  32. 32. Return-Lifting Appliedfunction fact(n: Int): Int { function fact(n: Int): Int { var res: Int; if(n == 0) { if(n == 0) { return 1; res := 1; } else { } else { return this * fact(n - 1); res := this * fact(n - 1); } } return res;} }
  33. 33. Return-Lifting Rulesrules lift-return-all = alltd(lift-return; normalize-all) lift-return : FunDef(x, arg*, Some(t), stat1*) -> FunDef(x, arg*, Some(t), Seq([ VarDecl(y, t), Seq(stat2*), Return(Var(y)) ])) where y := <new>; stat2* := <alltd(replace-return(|y))> stat1* replace-return(|y) : Return(e) -> Assign(y, e)
  34. 34. Seq Normalizationstrategies normalize-all = innermost-L(normalize)rules // seq lifting normalize : [Seq(stat1*) | stat2*@[_|_]] -> [Seq([stat1*,stat2*])] normalize : [stat, Seq(stat*)] -> [Seq([stat | stat*])] normalize : Block([Seq(stat1*)]) -> Block(stat1*) normalize : FunDef(x, arg*, t, [Seq(stat*)]) -> FunDef(x, arg*, t, stat*)
  35. 35. Interpretation eval
  36. 36. Small Step Operational Semanticsrules // driver steps = repeat(step) step: State([Frame(fn, this, slots, cont)|f*], heap) -> State(stack, heap) where cont := <eval> cont; stack := <update-stack (|...)> [Frame(..., cont)|f*]; heap := <update-heap(|...)> heap
  37. 37. Small Step Operational Semanticseval(|this, slots, heap): Var(x) -> val where val := <lookup> (x, slots) eval(|this, slots, heap): PropAccess(Ptr(p), prop) -> val where Object(_, props) := <lookup> (p, heap); val := <lookup> (prop, props)
  38. 38. From Text to Structure
  39. 39. Declarative Syntax Definition Entity("User", [ Property("first", Type("String")), Property("last", Type("String")) ])signature constructors Entity : ID * List(Property) -> Definition Type : ID -> Type Property : ID * Type -> Property
  40. 40. Declarative Syntax Definitionentity User { Entity("User", [ first : String Property("first", Type("String")), last : String Property("last", Type("String"))} ])signature constructors Entity : ID * List(Property) -> Definition Type : ID -> Type Property : ID * Type -> Property
  41. 41. Declarative Syntax Definitioncontext-free syntax "entity" ID "{" Property* "}" -> Definition {"Entity"} ID -> Type {"Type"} ID ":" Type -> Property {"Property"}entity User { Entity("User", [ first : String Property("first", Type("String")), last : String Property("last", Type("String"))} ])signature constructors Entity : ID * List(Property) -> Definition Type : ID -> Type Property : ID * Type -> Property
  42. 42. Declarative Syntax Definitioncontext-free syntax "entity" ID "{" Property* "}" -> Definition {"Entity"} ID -> Type {"Type"} ID ":" Type -> Property {"Property"}entity User { Entity("User", [ first : String Property("first", Type("String")), last : String Property("last", Type("String"))} ])signature constructors Entity : ID * List(Property) -> Definition Type : ID -> Type Property : ID * Type -> Property
  43. 43. Context-free Syntaxcontext-free syntax constructors "true" -> Exp {"True"} True : Exp "false" -> Exp {"False"} False : Exp "!" Exp -> Exp {"Not"} Not : Exp -> Exp Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Exp
  44. 44. Lexical Syntaxcontext-free syntax constructors "true" -> Exp {"True"} True : Exp "false" -> Exp {"False"} False : Exp "!" Exp -> Exp {"Not"} Not : Exp -> Exp Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Explexical syntax constructors [a-zA-Z][a-zA-Z0-9]* -> ID : String -> ID "-"? [0-9]+ -> INT : String -> INT [ tnr] -> LAYOUT scannerless generalized (LR) parsing
  45. 45. Ambiguitycontext-free syntax constructors "true" -> Exp {"True"} True : Exp "false" -> Exp {"False"} False : Exp "!" Exp -> Exp {"Not"} Not : Exp -> Exp Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Exp isPublic || isDraft && (author == principal())amb([ And(Or(Var("isPublic"), Var("isDraft")), Eq(Var("author"), ThisCall("principal", []))), Or(Var("isPublic"), And(Var("isDraft"), Eq(Var("author"), ThisCall("principal", []))))])
  46. 46. Disambiguation by Encoding Precedencecontext-free syntax constructors "true" -> Exp {"True"} True : Exp "false" -> Exp {"False"} False : Exp "!" Exp -> Exp {"Not"} Not : Exp -> Exp Exp "&&" Exp -> Exp {"And"} And : Exp * Exp -> Exp Exp "||" Exp -> Exp {"Or"} Or : Exp * Exp -> Expcontext-free syntax "(" Exp ")" -> Exp0 {bracket} "true" -> Exp0 {"True"} "false" -> Exp0 {"False"} Exp0 -> Exp1 "!" Exp0 -> Exp1 {"Not"} Exp1 -> Exp2 Exp1 "&&" Exp2 -> Exp2 {"And"} Exp2 -> Exp3 Exp2 "||" Exp3 -> Exp3 {"Or"}
  47. 47. Declarative Disambiguationcontext-free syntax "true" -> Exp {"True"} "false" -> Exp {"False"} "!" Exp -> Exp {"Not"} Exp "&&" Exp -> Exp {"And", left} Exp "||" Exp -> Exp {"Or", left} "(" Exp ")" -> Exp {bracket}context-free priorities {left: Exp.Not} > {left: Exp.Mul} > {left: Exp.Plus Exp.Minus} > {left: Exp.And} > {non-assoc: Exp.Eq Exp.Lt Exp.Gt Exp.Leq Exp.Geq}isPublic || isDraft && (author == principal()) Or(Var("isPublic"), And(Var("isDraft"), Eq(Var("author"), ThisCall("principal", []))))
  48. 48. Generating Text from Structure
  49. 49. Code Generation by String Concatenation to-java: Property(x, Type(t)) -> <concat-strings>[ "private ", t, " ", x, ";nn", "public ", t, " get_", x, " {n", " return ", x, ";n", "}n", "public void set_", x, " (", t, " ", x, ") {n", " this.", x, " = ", x, ";n", "}" ]
  50. 50. String Interpolation Templates to-java: Property(x, Type(t)) -> $[ private [t] [x]; public [t] get_[x] { return [x]; } public void set_[x] ([t] [x]) { this.[x] = [x]; } ]
  51. 51. Code Generation byModel Transformation
  52. 52. Generating Structured Representationsto-java: Property(x, Type(t)) -> [ Field([Private()], Type(t), Var(x)), Method([Public()], Type(t), $[get_[x]], [], [ Return(Var(x)) ]), Method([Public()], None(), $[set_[x]], [Param(Type(t), x)], [ Assign(FieldAccess(This(), x), Var(x)) ]) ]
  53. 53. Concrete Object Syntax to-java: Property(x, Type(t)) -> |[ private t x; public t get_#x { return x; } public void set_#x (t x) { this.x = x; } ]|
  54. 54. Rewriting with Concrete Object Syntax module desugar imports Enfun strategies desugar-all = topdown(repeat(desugar)) rules desugar: |[ !e ]| -> |[ e.not() ]| desugar: |[ e1 && e2 ]| -> |[ e1.and(e2) ]| desugar: |[ e1 || e2 ]| -> |[ e1.or(e2) ]| desugar: |[ e1 + e2 ]| -> |[ e1.plus(e2) ]| desugar: |[ e1 * e2 ]| -> |[ e1.times(e2) ]| desugar: |[ e1 - e2 ]| -> |[ e1.minus(e2) ]|
  55. 55. Rewriting with Concrete Object Syntaxlift-return-cs : |[ function x(arg*) : t { stat1* } ]| -> |[ function x(arg*): t { var y : t; ( stat2* ) return y; } ]| where y := <new>; stat2* := <alltd(replace-return(|y))> stat1* lift-return : FunDef(x, arg*, Some(t), stat1*) -> FunDef(x, arg*, Some(t), Seq([ VarDecl(y, t), Seq(stat2*), Return(Var(y)) ])) where y := <new>; stat2* := <alltd(replace-return(|y))> stat1*
  56. 56. Pretty-Printing byModel Transformation
  57. 57. Code Formattingmodule users entity String { } entity User { first : String last : String } Module( "demo1" module users , [ Entity("String", None(), None(), []) , Entity( entity String { "User" } , [ Property("first", Type("String")) , Property("last", Type("String")) ] entity User { ) first : String ] ) last : String }
  58. 58. Pretty-Printer Specificationprettyprint-Definition : Entity(x, prop*) -> [ H([SOpt(HS(), "0")] , [ S("entity ") , <pp-one-Z(prettyprint-ID)> x , S(" {") ] ) , <pp-indent(|"2")> [<pp-V-list(prettyprint-Property)> p*] , H([SOpt(HS(), "0")], [S("}")] ) ]
  59. 59. Structure Editors
  60. 60. Discoverability
  61. 61. Editors with Syntactic Completion
  62. 62. Completion Templatescompletions completion template Definition : "entity ID { }" = "entity " <ID:ID> " {nt" (cursor) "n}" (blank) completion template Type : "ID" = <ID:ID> completion template Property : "ID : ID " = <ID:ID> " : " <ID:Type> (blank)
  63. 63. Syntax Templates: Structure + Layout context-free syntax "entity" ID "{" Property* "}" -> Definition {"Entity"} ID -> Type {"Type"} ID ":" Type -> Property {"Property"}templates signature constructors Entity : ID * List(Property) -> Definition Definition.Entity = < Type : ID -> Type Property : ID * Type -> Property entity <ID> { <Property*; separator="n"> completions } completion template Definition : "entity ID { }" = > "entity " <ID:ID> " {nt" (cursor) "n}" (blank) completion template Type : "ID<>" = <ID:ID> "<" <:Type> ">" Type.Type = <<ID>> completion template Property : "ID : ID " = <ID:ID> " : " <ID:Type> (blank) Property.Property = < prettyprint-Definition = <ID> : <Type> ?Entity(x, prop*) ; ![ H( > [SOpt(HS(), "0")] , [ S("entity ") , <pp-one-Z(prettyprint-ID)> x , S(" {") ] ) , <pp-indent(|"2")> [<pp-V-list(prettyprint-Property)> p*] , H([SOpt(HS(), "0")], [S("}")] ) ]
  64. 64. Type Checking
  65. 65. Example: Checking Method Callsmodule renaming entity String { function plus(that:String): String { ... } } entity User { firstName : String lastName : String fullName : String function rename(first: String, last: String) { fullName := first.plus(0); // argument has wrong type fullName := first.plus(); // too few arguments fullName := first.plus(last, last); // too many arguments fullName := first.plus(last); // correct } }
  66. 66. Constraint Checksrules // errors type-error : (e, t) -> (e, $[Type [<pp>t] expected instead of [<pp>t]]) where <type-of> e => t; not(<subtype>(t, t))rules // functions constraint-error: |[ e.x(e*) ]| -> (x, $[Expects [m] arguments, found [n]]) where <lookup-type> x => (t*, t); <length> e* => n; <length> t* => m; not(<eq>(m, n)) constraint-error: |[ e.x(e*) ]| -> <zip; filter(type-error)> (e*, t*) where <lookup-type> x => (t*, t)
  67. 67. Type Analysisrules // constants type-of : |[ true ]| -> TypeBool() type-of : |[ false ]| -> TypeBool() type-of : Int(i) -> TypeInt() type-of : String(x) -> TypeString()
  68. 68. Types of Namesrules // names type-of : Var(x) -> <lookup-type> x type-of : |[ e.x ]| -> t where <lookup-type> x => t type-of : |[ e.x(e*) ]| -> t where <lookup-type> x => (t*, t) type-of : |[ f(e*) ]| -> t where <lookup-type> f => (t*, t)
  69. 69. Analysis: Name Resolution +
  70. 70. Definitions and References definition test type refers to entity [[ module test entity [[String]] { } entity User { first : [[String]] last : String } ]] resolve #2 to #1 reference
  71. 71. From Tree to GraphModule( "test", [ Entity("String", []) , Entity( "User" , [ Property("first", ) , Property("last", ) ] ) ])
  72. 72. Unique NamesModule( "users"{[Module(), "users"]} , [ Entity("String"{[Type(), "String", "users"]}, []) , Entity( "User"{[Type(), "User", "users"]} , [ Property( "first"{[Property(), "first", "User", "users"]} , Type("String"{[Type(), "String", "users"]})) , Property( "last"{[Property(), "last", "User", "users"]} , Type("String"{[Type(), "String", "users"]})) ] ) ] ) + index mapping unique names to values
  73. 73. Spoofax Name Binding Language namespaces Module Type See the full story in SLE talk on Friday rules Entity(c, _) : defines Type c Type(x, _) : refers to Type x Module(m, _) : defines Module m scopes Type Imports(m) : imports Type from Module m abstract from name resolution algorithmics
  74. 74. spoofax.orghttp://spoofax.org

×