Publicité
Publicité

Contenu connexe

Publicité
Publicité

Domänenspezifische Sprachen mit Xtext

  1. Domain-specific languages with Dr. Jan Köhnlein itemis AG
  2. Who‘s that guy?
  3. Jan Köhnlein
  4. • Software Architect, Consultant, Coach at itemis Jan Köhnlein
  5. • Software Architect, Consultant, Coach at itemis • Several years of experience in the modeling world Jan Köhnlein
  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. 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. What is a Domain Specific Language (DSL)?
  9. A domain-specific language (DSL) is a formal, processable language targeting at a specific viewpoint or aspect of a system.
  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. Boring! Don‘t you have any examples?
  12. Rd2-c2
  13. Rd2-c2
  14. “ Queen to c7. Check.” “ Rd2-c2 , rook at d2 moves to c2.”
  15. Using JPA
  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. @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. Testing Testing a Parser
  19. Expr 2+3*7/8 Op + Parser Number 2 Op / Op * Number 8 Number 3 Number 7
  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. 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. 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. What can I achieve with DSLs?
  24. Abstraction
  25. GPL vs DSL
  26. GPL vs DSL
  27. GPL vs DSL
  28. Why isn‘t everybody using DSLs?
  29. Complicated Expensive
  30. licensed by http://www.wordle.net/
  31. G ra m m ar
  32. Reference ar Model m m ra G
  33. Reference ar Model m m ra G
  34. Reference ar Model m m ra G Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor
  35. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor
  36. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Model Model Model
  37. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Model Model Model
  38. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor AST Model Model Model
  39. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor AST Model Model Model
  40. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Interpreter AST Model Model Code Model Generator
  41. Runtime Superclass Subclass Class ecore meta model LL(*) Parser editor Interpreter AST Model Model Code Model Generator
  42. Showtime
  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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Isn‘t text a little bit old- fashioned?
  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. } 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. } 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. } 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. } 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. } 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. } 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. } 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. } 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. } 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. } 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. How about customization?
  78. Convention over Configuration
  79. http://www.wordle.net/
  80. Configured with Google Guice class MyDslRuntimeModule extends DefaultRuntimeModule { Class<? extends ServiceInterface> bindService() { return MyServiceImplementation.class; } }
  81. Bird’s Eye View
  82. Extensible Language Generator • Generates a lot of Java code • Composed of fragments • Customizable • Add your own fragments!
  83. Does Xtext integrate with other technologies?
  84. Integration with EMF
  85. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component
  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. Integration with EMF eclipse Any EMF-based modeling Code Generator GMF Editor P R O J E C T Component <<abstract>> XMIResource Resource
  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. 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. 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. 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. 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. 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. converging editors (Xtext and GMF) koehnlein.blogspot.com
  95. converging editors (Xtext and GMF) koehnlein.blogspot.com
  96. Questions? find out more at http://www.xtext.org
  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

Notes de l'éditeur

  1. Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex GMFTools, oAW
  2. Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex GMFTools, oAW
  3. Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex GMFTools, oAW
  4. Eclipse Modeling: Xtext, Xpand, MWE, EMFIndex GMFTools, oAW
  5. st&amp;#xFC;ckweise durchgehen
  6. st&amp;#xFC;ckweise durchgehen
  7. kompakt, kontextbezogen kryptisch...
  8. kompakt, kontextbezogen kryptisch...
  9. kryptisch ist relativ! Bezug auf Konzepte der Dom&amp;#xE4;ne, formal Business-DSL: nicht technisch, f&amp;#xFC;r nicht Techiker geeignet
  10. Java schlecht im Abstrahieren von Struktur, Redundanz Code-Generierung definiert Platform-Mapping (Architekt) Referenz aus anderen DSLs, Wartbarkeit
  11. Java schlecht im Abstrahieren von Struktur, Redundanz Code-Generierung definiert Platform-Mapping (Architekt) Referenz aus anderen DSLs, Wartbarkeit
  12. AST: Abstrakter Syntaxbaum
  13. Java schlecht im Darstellen von B&amp;#xE4;umen lohnt schon bei wenigen Tests, Test schreiben macht Spa&amp;#xDF; Interpreter
  14. Java schlecht im Darstellen von B&amp;#xE4;umen lohnt schon bei wenigen Tests, Test schreiben macht Spa&amp;#xDF; Interpreter
  15. Java schlecht im Darstellen von B&amp;#xE4;umen lohnt schon bei wenigen Tests, Test schreiben macht Spa&amp;#xDF; Interpreter
  16. Raise level of abstraction, Avoids redundancy Separation of concerns, Reuse of domain concepts Higher expressiveness, Ubiquitous language
  17. GPLs k&amp;#xF6;nnen alles Spezielle Aufgaben erfordern spezielle Tools Vorsicht vor wiederverwendbaren von DSLs (Beispiel Feins&amp;#xE4;ge)
  18. GPLs k&amp;#xF6;nnen alles Spezielle Aufgaben erfordern spezielle Tools Vorsicht vor wiederverwendbaren von DSLs (Beispiel Feins&amp;#xE4;ge)
  19. 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
Publicité