Successfully reported this slideshow.

Building DSLs With Eclipse

16

Share

Upcoming SlideShare
Codegeneration With Xtend
Codegeneration With Xtend
Loading in …3
×
1 of 90
1 of 90

More Related Content

Building DSLs With Eclipse

  1. 1. Building DSLs with Eclipse Peter Friese, itemis @peterfriese @xtext (c) 2009 Peter Friese. Distributed under the EDL V1.0 - http://www.eclipse.org/org/documents/edl-v10.php More info: http://www.peterfriese.de / http://www.itemis.com
  2. 2. What is a DSL?
  3. 3. Domain
  4. 4. Language
  5. 5. Suppose...
  6. 6. You’d want to core an apple...
  7. 7. ... for your kids.
  8. 8. ? Right tool for the job?
  9. 9. Your trusty swiss army knife!
  10. 10. Because you can use it for other stuff, too. E.g., opening a bottle of wine.
  11. 11. Suppose...
  12. 12. You’d want to core a few more apples...
  13. 13. ... for an apple cake.
  14. 14. Still the best tool for the job?
  15. 15. Better use this one.
  16. 16. and this one:
  17. 17. BUT avoid the unitasker!
  18. 18. BUT avoid the unitasker!
  19. 19. ... a DSL is ...
  20. 20. A specific tool for a specific job
  21. 21. A specific tool for a specific job
  22. 22. Samples for DSLs
  23. 23. SQL
  24. 24. select name, salary from employees where salary > 2000 order by salary
  25. 25. ANT
  26. 26. <project name="MyProject" default="dist" basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <mkdir dir="${build}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <mkdir dir="${dist}/lib"/> <jar jarfile="${dist}/lib/MyProject.jar" basedir="${build}"/> </target> <target name="clean"> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>
  27. 27. <project name="MyProject" default="dist" basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> <mkdir dir="${build}"/> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <mkdir dir="${dist}/lib"/> <jar jarfile="${dist}/lib/MyProject.jar" basedir="${build}"/> </target> <target name="clean"> <delete dir="${build}"/> <delete dir="${dist}"/> </target> </project>
  28. 28. External or Internal
  29. 29. Internal DSLs
  30. 30. Mailer.mail() .to(“you@gmail.com”) .from(“me@gmail.com”) .subject(“Writing DSLs in Java”) .body(“...”) .send();
  31. 31. Simple
  32. 32. Limited
  33. 33. External DSLs
  34. 34. 1)Create ANTLR grammar 2)Generate lexer / parser 3)Parser will create parse tree 4)Transform parse tree to semantic model 5)Iterate model 6)Pass model element(s) to template
  35. 35. Flexible
  36. 36. Adaptable
  37. 37. Complicated
  38. 38. Why not use a DSL... ... for building DSLs?
  39. 39. Demo 1
  40. 40. @SuppressWarnings("serial") @Entity @Table(name = "CUSTOMER_INFO") public class CustomerInfo implements Serializable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idSeq") @SequenceGenerator(name = "idSeq", sequenceName = "CUST_SEQ", allocationSize = 1) @Column(name = "CUST_ID", nullable = false) private String customerId; public void setCustomerId(String customerId) { this.customerId = customerId; } public String getCustomerId() { return customerId; } @Column(name = "EMAIL", nullable = false, length = 128) private String emailAddress; public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { String oldValue = emailAddress; this.emailAddress = emailAddress; firePropertyChangedEvent("emailAddress", oldValue, this.emailAddress); }
  41. 41. @SuppressWarnings("serial") @Entity @Table(name = "CUSTOMER_INFO") public class CustomerInfo implements Serializable { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idSeq") @SequenceGenerator(name = "idSeq", sequenceName = "CUST_SEQ", allocationSize = 1) @Column(name = "CUST_ID", nullable = false) private String customerId; public void setCustomerId(String customerId) { this.customerId = customerId; } public String getCustomerId() { return customerId; } @Column(name = "EMAIL", nullable = false, length = 128) private String emailAddress; public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { String oldValue = emailAddress; this.emailAddress = emailAddress; firePropertyChangedEvent("emailAddress", oldValue, this.emailAddress); }
  42. 42. entity CustomerInfo (id=CUST_ID, sequenceName=CUST_SEQ) { String emailAddress (notNull, length = 128) }
  43. 43. entity CustomerInfo (id=CUST_ID, sequenceName=CUST_SEQ) { String emailAddress (notNull, length = 128) } Bean DAO (POJO)
  44. 44. Underlying Technology
  45. 45. Model G ra m m ar
  46. 46. ar Model m m ra G Generator
  47. 47. ar Model m m ra G Generator Runtime Superclass Subclass Class LL(*) Parser ECore meta model Editor
  48. 48. ar Model m m ra G Generator Runtime Superclass Subclass Class LL(*) Parser ECore meta model Editor
  49. 49. Grammar (similar to EBNF) grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/example/Entity" Model: (types+=Type)*; Type: TypeDef | Entity; TypeDef: "typedef" name=ID ("mapsto" mappedType=JAVAID)?; JAVAID: name=ID("." ID)*; Entity: "entity" name=ID ("extends" superEntity=[Entity])? "{" (attributes+=Attribute)* "}"; Attribute: type=[Type] (many?="*")? name=ID;
  50. 50. grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  51. 51. grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Rules -> Classes Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  52. 52. grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  53. 53. grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Alternatives -> Hierarchy Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  54. 54. grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  55. 55. grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Assignment -> Feature Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  56. 56. grammar org.xtext.example.Entity with org.eclipse.xtext.common.Terminals Meta model inference generate entity "http://www.xtext.org/example/Entity" entity Model: (types+=Type)*; Model Type: TypeDef | Entity; types TypeDef: * Type "typedef" name=ID name: EString ("mapsto" mappedType=JAVAID)?; superEntity JAVAID: name=ID("." ID)*; TypeDef Entity Entity: mappedType attributes "entity" name=ID Attribute ("extends" superEntity=[Entity])? JAVAID name: EString "{" name: EString many: EBoolean (attributes+=Attribute)* "}"; type Attribute: type=[Type] (many?="*")? name=ID;
  57. 57. Demo 2
  58. 58. Poll "Simple poll" question "What's your name?" name question "How do you feel today?" howareyou () "Fine" fine () "Great" great () "Bad" bad () "Not too bad" not2bad question "What's your favourite food?" food [] "Pizza" pizza [] "Pasta" pasta [] "Sushi" sushi [] "Mexican" mexican
  59. 59. Pimp My Write
  60. 60. Tooltips Scoping Outline Label Provider Validation Hyperlinking / Navigation AST Code Formatting Content Assist Folding Quick Fix Datatype Converter Parser Syntax Highlighting
  61. 61. Tooltips Scoping Outline Hyperlinking / Navigation AST Code Formatting Content Assist Folding Quick Fix Datatype Converter Parser Syntax Highlighting
  62. 62. Tooltips Scoping Outline Label Provider Validation Hyperlinking / Navigation AST Code Formatting Content Assist Folding Quick Fix Datatype Converter Parser Syntax Highlighting
  63. 63. Conclusion
  64. 64. Abstraction
  65. 65. Use a DSL to develop your tools
  66. 66. Support Newsgroup Community Forum Professional Support
  67. 67. Heiko Sven Moritz Peter Dennis Jan Patrick Sebastian Michael Knut Behrens Efftinge Eysholdt Friese Hübner Köhnlein Schönbach Zarnekow Clay Wannheden Individual
  68. 68. Twitter: @xtext http://www.xtext.org

Editor's Notes

  • itemis = IT + Themis
    Themis, goddess of
    justice
    order
    knows the future
  • connect people
    share contact details
    your resume on the web (endorsements, who you know, what you&amp;#x2019;ve done)
  • connect people / friends
    &amp;#x201C;friend&amp;#x201D; someone / &amp;#x201C;write on their wall&amp;#x201D;
    share photos
    fun-oriented
  • connect people
    everybody can have their say
  • Java = GPL
    You can do everything with Java
    But is it a good idea to do everything with Java?
  • concise
    precise
    wouldn&amp;#x2019;t change anything
  • ANT, built on a single transatlantic flight
    using XML to avoid writing own parser
    leverage XML parser
    today, we&amp;#x2019;d do it differently
  • ANT, built on a single transatlantic flight
    using XML to avoid writing own parser
    leverage XML parser
    today, we&amp;#x2019;d do it differently
  • It&amp;#x2019;s relatively easy to write an internal DSL
  • Syntax of host language is the limiting factor for implementing internal DSLs
  • External DSLs are very flexible - you can exactly adjust them to your needs
  • You can choose the syntax of your DSL to your liking
  • However, building external DSLs is complicated
  • Java = GPL
    You can do everything with Java
    But is it a good idea to do everything with Java?
  • Newsgroup
    Foren
    Prof. Support
  • ×