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.

Building DSLs With Eclipse

12,527 views

Published on

This slideshow explains what DSLs are and how to use tools from the Eclipse Modeling Project to create them.

Published in: Technology, Design

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

×