Domain-specific languages
with




Dr. Jan Köhnlein

itemis AG
Who‘s that guy?
Jan Köhnlein
• Software Architect, Consultant,
  Coach at itemis




                               Jan Köhnlein
• Software Architect, Consultant,
  Coach at itemis
• Several years of experience
  in the modeling world




            ...
• Software Architect, Consultant,
  Coach at itemis
• Several years of experience
  in the modeling world
• Committer to s...
itemis short facts

    Spezialist für modellbasierte Entwicklungsverfahren
    Gründung im Jahr 2003
    Niederlassung...
What is a
Domain Specific
Language (DSL)?
A domain-specific language (DSL)
     is a formal, processable language
targeting at a specific viewpoint or aspect
        ...
A domain-specific language (DSL)
        is a formal, processable language
   targeting at a specific viewpoint or aspect
  ...
Boring! Don‘t
you have any
 examples?
Rd2-c2
Rd2-c2
“ Queen to c7.
              Check.”




  “ Rd2-c2 ,
rook at d2 moves to c2.”
Using JPA
@Entity
public class Customer implements Serializable {
  private Long id;
  private String name;
  private Address addres...
@Entity
public class Customer implements Serializable {
  private Long id;
  private String name;
  private Address addres...
Testing

Testing a Parser
Expr

2+3*7/8
                 Op +



Parser    Number 2            Op /


                     Op *        Number 8


  ...
public class ParserTests extends TestCase {

    public void testExampleExpression2() throws IOException {
	   	   EObject...
public class ParserTests extends ParserTestCase {

	   public void testExampleExpression() throws IOException {
	   	 EObj...
public class ParserTests extends ParserTestCase {

	   public void testExampleExpression() throws IOException {
	   	 EObj...
What can I
achieve with
   DSLs?
Abstraction
GPL vs DSL
GPL vs DSL
GPL vs DSL
Why isn‘t
everybody using
     DSLs?
Complicated   Expensive
licensed by http://www.wordle.net/
G
 ra
      m
       m
           ar
Reference




                    ar
 Model




                 m
                m
            ra
            G
Reference




                    ar
 Model




                 m
                m
            ra
            G
Reference




                                  ar
   Model




                               m
                         ...
Runtime
  Superclass




  Subclass     Class




ecore meta model       LL(*) Parser   editor
Runtime
  Superclass




  Subclass     Class




ecore meta model       LL(*) Parser   editor




                       ...
Runtime
  Superclass




  Subclass     Class




ecore meta model       LL(*) Parser   editor




                       ...
Runtime
  Superclass




  Subclass     Class




ecore meta model       LL(*) Parser   editor




                       ...
Runtime
  Superclass




  Subclass     Class




ecore meta model       LL(*) Parser   editor




                       ...
Runtime
   Superclass




   Subclass     Class




ecore meta model        LL(*) Parser   editor




Interpreter         ...
Runtime
   Superclass




   Subclass     Class




ecore meta model        LL(*) Parser   editor




Interpreter         ...
Showtime
Example Model
type String

entity Conference {
  property Name: String
                           n[]
  property Attendees...
Example Model
                                    entity
type String
                                                     ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals

generate entity
  "http://www.xtext.org/webi...
Grammar      grammar org.xtext.webinar.Entity
definition   	   with org.eclipse.xtext.common.Terminals

             gener...
grammar org.xtext.webinar.Entity              Grammar
	   with org.eclipse.xtext.common.Terminals      reuse

generate ent...
grammar org.xtext.webinar.Entity
            	   with org.eclipse.xtext.common.Terminals


Derived     generate entity
   ...
grammar org.xtext.webinar.Entity
         	   with org.eclipse.xtext.common.Terminals

         generate entity
          ...
grammar org.xtext.webinar.Entity
           	   with org.eclipse.xtext.common.Terminals

           generate entity
      ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals

generate entity
  "http://www.xtext.org/webi...
grammar org.xtext.webinar.Entity
                 	   with org.eclipse.xtext.common.Terminals

                 generate e...
grammar org.xtext.webinar.Entity
             	   with org.eclipse.xtext.common.Terminals

             generate entity
  ...
grammar org.xtext.webinar.Entity
             	   with org.eclipse.xtext.common.Terminals

             generate entity
  ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals

generate entity
  "http://www.xtext.org/webi...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals

generate entity
  "http://www.xtext.org/webi...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
grammar org.xtext.webinar.Entity
	   with org.eclipse.xtext.common.Terminals
                                             ...
Isn‘t text a
little bit old-
  fashioned?
}
           	
           	   protected String getErrorMessage() {
           	   	    return errorMessage.toString();
   ...
}
                     	
                     	   protected String getErrorMessage() {
                     	   	    retur...
}
                     	
                     	   protected String getErrorMessage() {
                     	   	    retur...
}
                           	
                           	   protected String getErrorMessage() {
                       ...
}
                           	
                           	   protected String getErrorMessage() {
                       ...
}
                           	
                           	   protected String getErrorMessage() {
                       ...
}
                           	
                           	   protected String getErrorMessage() {
                       ...
}
                             	
                             	   protected String getErrorMessage() {
                   ...
}
                             	
                             	   protected String getErrorMessage() {
                   ...
}
                             	
                             	   protected String getErrorMessage() {
                   ...
}
                             	
                             	   protected String getErrorMessage() {
                   ...
How about
customization?
Convention
over
Configuration
http://www.wordle.net/
Configured with
         Google Guice



class MyDslRuntimeModule extends DefaultRuntimeModule {
   Class<? extends Service...
Bird’s Eye View
Extensible Language
         Generator
• Generates a lot of Java code
• Composed of fragments
 • Customizable
 • Add your ...
Does Xtext
integrate with
     other
 technologies?
Integration with EMF
Integration with EMF
                                              eclipse

                              Any EMF-based   ...
Integration with EMF
                                                eclipse

                                Any EMF-base...
Integration with EMF
                                                eclipse

                                Any EMF-base...
Integration with EMF
                                                eclipse

                                Any EMF-base...
Integration with EMF
                                                eclipse

                                Any EMF-base...
Integration with EMF
                                                 eclipse

                                 Any EMF-ba...
Integration with EMF
                                                 eclipse

                                 Any EMF-ba...
Integration with EMF
                                                  eclipse

                                 Any EMF-b...
Integration with EMF
                                                  eclipse

                                 Any EMF-b...
converging editors (Xtext and GMF)
         koehnlein.blogspot.com
converging editors (Xtext and GMF)
         koehnlein.blogspot.com
Questions?

   find out more at
 http://www.xtext.org
Aktuelle Veranstaltungen


LOP und DSLs - Köln, 15:00
      25. August 2009: Deutsches Zentrum für Luft- und Raumfahrt - F...
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
Domänenspezifische Sprachen mit Xtext
Upcoming SlideShare
Loading in …5
×

Domänenspezifische Sprachen mit Xtext

2,191 views
2,119 views

Published on

Talk at ruhrjug in Essen (Germany)

Published in: Technology
1 Comment
2 Likes
Statistics
Notes
No Downloads
Views
Total views
2,191
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
84
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide
  • Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex
    GMFTools, oAW
  • Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex
    GMFTools, oAW
  • Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex
    GMFTools, oAW
  • Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex
    GMFTools, oAW
  • st&amp;#xFC;ckweise durchgehen
  • st&amp;#xFC;ckweise durchgehen
  • kompakt, kontextbezogen
    kryptisch...
  • kompakt, kontextbezogen
    kryptisch...
  • kryptisch ist relativ!
    Bezug auf Konzepte der Dom&amp;#xE4;ne, formal
    Business-DSL: nicht technisch, f&amp;#xFC;r nicht Techiker geeignet
  • Java schlecht im Abstrahieren von Struktur, Redundanz
    Code-Generierung definiert Platform-Mapping (Architekt)
    Referenz aus anderen DSLs, Wartbarkeit
  • Java schlecht im Abstrahieren von Struktur, Redundanz
    Code-Generierung definiert Platform-Mapping (Architekt)
    Referenz aus anderen DSLs, Wartbarkeit
  • AST: Abstrakter Syntaxbaum
  • Java schlecht im Darstellen von B&amp;#xE4;umen
    lohnt schon bei wenigen Tests, Test schreiben macht Spa&amp;#xDF;
    Interpreter
  • Java schlecht im Darstellen von B&amp;#xE4;umen
    lohnt schon bei wenigen Tests, Test schreiben macht Spa&amp;#xDF;
    Interpreter
  • Java schlecht im Darstellen von B&amp;#xE4;umen
    lohnt schon bei wenigen Tests, Test schreiben macht Spa&amp;#xDF;
    Interpreter
  • Raise level of abstraction, Avoids redundancy
    Separation of concerns, Reuse of domain concepts
    Higher expressiveness, Ubiquitous language
  • GPLs k&amp;#xF6;nnen alles
    Spezielle Aufgaben erfordern spezielle Tools
    Vorsicht vor wiederverwendbaren von DSLs (Beispiel Feins&amp;#xE4;ge)
  • GPLs k&amp;#xF6;nnen alles
    Spezielle Aufgaben erfordern spezielle Tools
    Vorsicht vor wiederverwendbaren von DSLs (Beispiel Feins&amp;#xE4;ge)
  • Die DSL f&amp;#xFC;r DSLs, Eclipse-basiert
    Define textual DSLs easily, Ready-to-use tool-chain, Easy but flexible customizing and tweaking,
    Durable foundation with Java Eclipse EMF, Strong community
  • Domänenspezifische Sprachen mit Xtext

    1. 1. Domain-specific languages with Dr. Jan Köhnlein itemis AG
    2. 2. Who‘s that guy?
    3. 3. Jan Köhnlein
    4. 4. • Software Architect, Consultant, Coach at itemis Jan Köhnlein
    5. 5. • Software Architect, Consultant, Coach at itemis • Several years of experience in the modeling world Jan Köhnlein
    6. 6. • Software Architect, Consultant, Coach at itemis • Several years of experience in the modeling world • Committer to several open- source projects Jan Köhnlein
    7. 7. itemis short facts  Spezialist für modellbasierte Entwicklungsverfahren  Gründung im Jahr 2003  Niederlassungen in Deutschland, Frankreich, Schweiz und Kanada  140 Mitarbeiter  Strategisches Mitglied der Eclipse Foundation  Intensive Verzahnung im Bereich der Forschung  Mitglied von ARTEMISIA  Embedded Software Development  Enterprise Application Development 1
    8. 8. What is a Domain Specific Language (DSL)?
    9. 9. A domain-specific language (DSL) is a formal, processable language targeting at a specific viewpoint or aspect of a system.
    10. 10. A domain-specific language (DSL) is a formal, processable language targeting at a specific viewpoint or aspect of a system. Its semantics, flexibility and notation is designed in order to support working with that viewpoint as good as possible.
    11. 11. Boring! Don‘t you have any examples?
    12. 12. Rd2-c2
    13. 13. Rd2-c2
    14. 14. “ Queen to c7. Check.” “ Rd2-c2 , rook at d2 moves to c2.”
    15. 15. Using JPA
    16. 16. @Entity public class Customer implements Serializable { private Long id; private String name; private Address address; private Collection<Order> orders = new HashSet<Order>(); private Set<PhoneNumber> phones = new HashSet<PhoneNumber>(); public Customer() {} @Id public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } @OneToMany public Collection<Order> getOrders() { return orders; } public void setOrders(Collection<Order> orders) { this.orders = orders; } @ManyToMany public Set<PhoneNumber> getPhones() { return phones; } public void setPhones(Set<PhoneNumber> phones) { this.phones = phones; } }
    17. 17. @Entity public class Customer implements Serializable { private Long id; private String name; private Address address; private Collection<Order> orders = new HashSet<Order>(); private Set<PhoneNumber> phones = new HashSet<PhoneNumber>(); public Customer() {} @Id public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } entity Customer { public void setName(String name) { this.name = name; String name } Address address public Address getAddress() { return address; Order* orders } public void setAddress(Address address) { PhoneNumber** phones this.address = address; } } @OneToMany public Collection<Order> getOrders() { return orders; } public void setOrders(Collection<Order> orders) { this.orders = orders; } @ManyToMany public Set<PhoneNumber> getPhones() { return phones; } public void setPhones(Set<PhoneNumber> phones) { this.phones = phones; } }
    18. 18. Testing Testing a Parser
    19. 19. Expr 2+3*7/8 Op + Parser Number 2 Op / Op * Number 8 Number 3 Number 7
    20. 20. public class ParserTests extends TestCase { public void testExampleExpression2() throws IOException { EObject ast = parse("2+3*7/8"); assertTrue(ast instanceof Expr); EObject ast_0 = child(ast, 0); assertTrue(ast_0 instanceof Op); assertEquals("+", ((Op) ast_0).getOperator()); EObject ast_0_0 = child(ast_0, 0); assertTrue(ast_0_0 instanceof Number); assertEquals(2, ((Number) ast_0_0).getValue()); EObject ast_0_1 = child(ast_0, 1); assertTrue(ast_0_1 instanceof Op); assertEquals("/", ((Op) ast_0_1).getOperator()); EObject ast_0_1_0 = child(ast_0_1, 0); assertTrue(ast_0_1_0 instanceof Op); assertEquals("*", ((Op) ast_0_1_0).getOperator()); EObject ast_0_1_1 = child(ast_0_1, 1); assertTrue(ast_0_1_1 instanceof Number); assertEquals(8, ((Number) ast_0_1_1).getValue()); EObject ast_0_1_0_0 = child(ast_0_1_0, 0); assertTrue(ast_0_1_0_0 instanceof Number); assertEquals(3, ((Number) ast_0_1_0_0).getValue()); EObject ast_0_1_0_1 = child(ast_0_1_0, 1); assertTrue(ast_0_1_0_1 instanceof Number); assertEquals(7, ((Number) ast_0_1_0_1).getValue()); }
    21. 21. public class ParserTests extends ParserTestCase { public void testExampleExpression() throws IOException { EObject ast = parse("2+3*7/8"); assertTrue(ast instanceof Expr); EObject ast_0 = child(ast, 0); assertOperator(ast_0, "+"); EObject ast_0_0 = child(ast_0, 0); assertNumber(ast_0_0, 2); EObject ast_0_1 = child(ast_0, 1); assertOperator(ast_0_1, "/"); EObject ast_0_1_0 = child(ast_0_1, 0); assertOperator(ast_0_1_0, "*"); EObject ast_0_1_1 = child(ast_0_1, 1); assertNumber(ast_0_1_1,8); EObject ast_0_1_0_0 = child(ast_0_1_0, 0); assertNumber(ast_0_1_0_0, 3); EObject ast_0_1_0_1 = child(ast_0_1_0, 1); assertNumber(ast_0_1_0_1, 7); } }
    22. 22. public class ParserTests extends ParserTestCase { public void testExampleExpression() throws IOException { EObject ast = parse("2+3*7/8"); assertTrue(ast instanceof Expr); EObject ast_0 = child(ast, 0); test testExampleExpression assertOperator(ast_0, "+"); "2+3*7/8" EObject ast_0_0 = child(ast_0, 0); Expr { assertNumber(ast_0_0, 2); Op operator="+" { EObject ast_0_1 = child(ast_0, 1); Number value="2" assertOperator(ast_0_1, "/"); Op operator="/" { Op operator="*" { EObject ast_0_1_0 = child(ast_0_1, 0); Number value="3" assertOperator(ast_0_1_0, "*"); Number value="7" EObject ast_0_1_1 = child(ast_0_1, 1); } assertNumber(ast_0_1_1,8); Number value="8" } EObject ast_0_1_0_0 = child(ast_0_1_0, 0); } assertNumber(ast_0_1_0_0, 3); } EObject ast_0_1_0_1 = child(ast_0_1_0, 1); assertNumber(ast_0_1_0_1, 7); } }
    23. 23. What can I achieve with DSLs?
    24. 24. Abstraction
    25. 25. GPL vs DSL
    26. 26. GPL vs DSL
    27. 27. GPL vs DSL
    28. 28. Why isn‘t everybody using DSLs?
    29. 29. Complicated Expensive
    30. 30. licensed by http://www.wordle.net/
    31. 31. G ra m m ar
    32. 32. Reference ar Model m m ra G
    33. 33. Reference ar Model m m ra G
    34. 34. Reference ar Model m m ra G Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor
    35. 35. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor
    36. 36. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Model Model Model
    37. 37. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Model Model Model
    38. 38. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor AST Model Model Model
    39. 39. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor AST Model Model Model
    40. 40. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Interpreter AST Model Model Code Model Generator
    41. 41. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Interpreter AST Model Model Code Model Generator
    42. 42. Showtime
    43. 43. Example Model type String entity Conference { property Name: String n[] property Attendees: Perso er[] property Speakers: Speak } entity Person { property Name: String } rson { entity Speaker extends Pe n[] property Sessions: Sessio } entity Session { property Title: String }
    44. 44. Example Model entity type String Model entity Conference { property Name: String types n[] property Attendees: Perso * er[] property Speakers: Speak Type } name: EString entity Person { property Name: String } SimpleType Entity extends rson { entity Speaker extends Pe n[] property Sessions: Sessio properties * } Property name: EString entity Session { type many: EBoolean property Title: String }
    45. 45. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    46. 46. Grammar grammar org.xtext.webinar.Entity definition with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    47. 47. grammar org.xtext.webinar.Entity Grammar with org.eclipse.xtext.common.Terminals reuse generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    48. 48. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals Derived generate entity "http://www.xtext.org/webinar/Entity" metamodel Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    49. 49. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; Parser SimpleType: rules 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    50. 50. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* Keywords '}'; Keywords Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    51. 51. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: Alternative SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    52. 52. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: Cardinality 'type' name=ID; (zero or more) Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* Cardinality (optional) '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    53. 53. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: Unassigned SimpleType | Entity; rulecall SimpleType: 'type' name=ID; Assigned rulecall Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    54. 54. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; Multivalue assignment SimpleType: 'type' name=ID; Entity: 'entity' name=ID Simple assigment ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?; Boolean assigment
    55. 55. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Cross reference Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    56. 56. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals generate entity "http://www.xtext.org/webinar/Entity" Model: (elements+=Type)*; Type: SimpleType | Entity; SimpleType: 'type' name=ID; Entity: 'entity' name=ID ('extends' extends=[Entity])? '{' properties+=Property* '}'; Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    57. 57. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    58. 58. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    59. 59. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    60. 60. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    61. 61. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    62. 62. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    63. 63. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    64. 64. grammar org.xtext.webinar.Entity with org.eclipse.xtext.common.Terminals entity generate entity "http://www.xtext.org/webinar/Entity" Model Model: types (elements+=Type)*; * Type: Type name: EString SimpleType | Entity; SimpleType: 'type' name=ID; SimpleType Entity Entity: extends 'entity' name=ID ('extends' extends=[Entity])? '{' properties properties+=Property* * '}'; Property name: EString type many: EBoolean Property: 'property' name=ID ':' type=[Type] (many?='[]')?;
    65. 65. Isn‘t text a little bit old- fashioned?
    66. 66. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().g } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    67. 67. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().g } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    68. 68. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    69. 69. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • Suggests non-formalism ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    70. 70. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • Suggests non-formalism ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    71. 71. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • Suggests non-formalism ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    72. 72. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • Suggests non-formalism ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    73. 73. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove(); } } return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    74. 74. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { } } • Easy to evolve i.remove(); return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    75. 75. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r • Editing with mouse } return false; for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { } } • Easy to evolve i.remove(); return relevantChildren; } protected boolean isRelevantChild(EObject container, EObject child) { return true;
    76. 76. } protected String getErrorMessage() { return errorMessage.toString(); } Graphics public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • High-level views public boolean internalIsSameStructure(EObject left, EObject right) { • ++counter; Suggests non-formalism if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + ri • Individual tools return false; } List<EObject> leftChildren = getRelevantChildren(left); • Hard to evolve List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + r • Editing with mouse } return false; for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get errorMessage.append("Children differ " + left + " " + right + return false; } } Text return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) } • Detailed views && left.getEPackage().getNsURI().equals(right.getEPackage().g • Formal protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents( • Well established tools for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { } • Easy to evolve i.remove(); • } } Editing with keyboard return relevantChildren; protected boolean isRelevantChild(EObject container, EObject child) { return true;
    77. 77. How about customization?
    78. 78. Convention over Configuration
    79. 79. http://www.wordle.net/
    80. 80. Configured with Google Guice class MyDslRuntimeModule extends DefaultRuntimeModule { Class<? extends ServiceInterface> bindService() { return MyServiceImplementation.class; } }
    81. 81. Bird’s Eye View
    82. 82. Extensible Language Generator • Generates a lot of Java code • Composed of fragments • Customizable • Add your own fragments!
    83. 83. Does Xtext integrate with other technologies?
    84. 84. Integration with EMF
    85. 85. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component
    86. 86. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMIResource Resource
    87. 87. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMIResource Resource
    88. 88. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource
    89. 89. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource
    90. 90. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource
    91. 91. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource
    92. 92. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource Text
    93. 93. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMI XMIResource Resource XtextResource Text Parser Linker Serializer ValueConverter ScopeProvider Formatter
    94. 94. converging editors (Xtext and GMF) koehnlein.blogspot.com
    95. 95. converging editors (Xtext and GMF) koehnlein.blogspot.com
    96. 96. Questions? find out more at http://www.xtext.org
    97. 97. Aktuelle Veranstaltungen LOP und DSLs - Köln, 15:00 25. August 2009: Deutsches Zentrum für Luft- und Raumfahrt - Falko Riemenschneider, NRWConf. 2009 27-28. August 2009: Wolkenburg 100, 42119 Wuppertal Domänenspezifische Sprachen - Lars Corneliussen 12.15 Uhr - 12.45 Uhr Die 10 Gebote der Architektur - Georg Pietrek 15.20 Uhr - 16.20 Uhr Scrum: Vom Businessneed zum hochwertigen Produktbacklog, Bonn, 18:30 31.August 2009 - Konferenzhotel Bonn - Sebastian Neus / Dr. Martin Wrangel Tagung: Mensch und Computer 2009, Berlin, 09:00 07. September 2009 - Leichtgewichtigkeit als Prinzip – Gestaltung der Webanwendung myPIM durch UCD, FDD und Xtext – Torsten Krohn Praktische Anwendung von EMF Compare, Dortmund 18:30 14. September 2009 - Harenberg City Center - Dr. Lothar Wendehals Alle aktuellen Veranstaltungen und weiterführende Informationen auf: http://www.itemis.de/veranstaltungen

    ×