Jazoon 2010 - Building DSLs with Eclipse
-
Upload
peter-friese -
Category
Technology
-
view
2.556 -
download
2
description
Transcript of Jazoon 2010 - Building DSLs with Eclipse
Building DSLs with EclipsePeter Friese, itemis
@peterfriese@xtext
www.itemis.de
(c) 2009 Peter Friese. Distributed under the EDL V1.0 - http://www.eclipse.org/org/documents/edl-v10.phpMore info: http://www.peterfriese.de / http://www.itemis.com
Think about your job!
Feel like this?
Because
Becauseyou need to write
Becauseyou need to writelots of boring code?
Wrong Level of Abstraction!http://www.flickr.com/photos/rykerstribe/3222969466/
DSLomain
pecific
anguage
DSLA language...
...that lets you express your intention
... that doesn’t get in your way
... that fits your situation
... that’s formal and processable
... that’s simple and easy to learn
... that solves one problem
Some DSLsyou might have
heard of
select name, salaryfrom employees where salary > 2000order by salary
<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>
<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>
Externalor
Internal
Internal DSLs
Mailer.mail().to(“[email protected]”).from(“[email protected]”).subject(“Writing DSLs in Java”).body(“...”).send();
Simple
Limited
External DSLs
1)Create ANTLR grammar2)Generate lexer / parser3)Parser will create parse tree4)Transform parse tree to semantic model
5)Iterate model6)Pass model element(s) to template
Lack of symbolic integration
Writing parsers / generators is complicated
IDE support is inferior / non-existent
Flexible
Adaptable
Complicated
... for building DSLs?
Why not use a DSL...
Superclass
Subclass Class
ECore meta modelLL(*) Parser Editor
Model
Grammar
Generator
Runtime
Superclass
Subclass Class
ECore meta modelLL(*) Parser Editor
Model
Grammar
Generator
Runtime
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;
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;
entity
Model
*
name: EStringType
types
TypeDef Entity
name: EStringJAVAID
superEntity
mappedType
name: EStringmany: EBoolean
Attribute
attributes
type
Meta model inference
Rules -> Classes
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;
entity
Model
*
name: EStringType
types
TypeDef Entity
name: EStringJAVAID
superEntity
mappedType
name: EStringmany: EBoolean
Attribute
attributes
type
Meta model inference
Alternatives -> Hierarchy
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;
entity
Model
*
name: EStringType
types
TypeDef Entity
name: EStringJAVAID
superEntity
mappedType
name: EStringmany: EBoolean
Attribute
attributes
type
Meta model inference
Assignment -> Feature
Let’s build a DSLfor Mobile Apps
Building DSLs
1. Analyze problem domain2. Map concepts of problem domain to language3. (Optional: write interpreter)4. (Optional: write generator)
Analyzing the problem domain
http://www.flickr.com/photos/minifig/3174009125/
Anatomy of an iPhone app
Table view
View title
Table cell
Tab bar
Tab bar button
NameImage
Speaker
TitleLocation
Session
Entity
Data Provider
Mapping concepts
Table view
View title
Table cell
Tab bar
Tab bar button
Entity
Data Provider
tabbarApplication jazoonApp { button { title= "Schedule" icon= "83-calendar.png" view= ScheduleList( AllSessions() ) } button { title= "Speakers" icon= "112-group.png" view= SpeakerList( AllSpeakers() ) } button { title= "Topics" icon= "44-shoebox.png" view= TopicList( AllTopics() ) }}
Mapping concepts
Table view
View title
Table cell
Tab bar
Tab bar button
Entity
Data Provider
entity Speaker { String speakerId String name String bio String organization String country String smallImageURL String largeImageURL Session[] talks}
entity Session { String talkId String title String abstract String ^type String location String startTime String endTime Speaker[] speakers Topic[] topics}
entity Topic { String topicId String themeId String name}
Mapping concepts
Table view
View title
Table cell
Tab bar
Tab bar button
Entity
Data Provider
contentprovider AllSessions returns Session[] fetches XML from "http://jipa.netcetera.ch/talks.xml" selects "feed.entry" contentprovider AllSpeakers returns Speaker[] fetches XML from "http://jipa.netcetera.ch/speakers.xml" selects "feed.entry"
Mapping concepts
Table view
View title
Table cell
Tab bar
Tab bar button
Entity
Data Provider
contentprovider AllSessions returns Session[] fetches XML from "http://query.yahooapis.com/v1/public/yql?q=use%20%22http%3A%2F%2FHeikoBehrens.net%2Fjazoon%2Ftalks.xml%22%20as%20talks%3B%0Aselect%20*%20from%20talks%20where%20omitDetails%3D1&debug=true" selects "query.results.talks.talk"
contentprovider SessionsByTopic(String id) returns Session[] fetches XML from ("http://query.yahooapis.com/v1/public/yql?q=use%20%22http%3A%2F%2FHeikoBehrens.net%2Fjazoon%2Ftalks.xml%22%20as%20s%3B%0Aselect%20*%20from%20s%20where%20topicId%20%3D%20%22"id"%22&diagnostics=true&debug=true&debug=true") selects "query.results.talks.talk"
Mapping concepts
Table view
View title
Table cell
Tab bar
Tab bar button
Entity
Data Provider tableview ScheduleList(Session[] sessions) { title= "Schedule" section { cell Subtitle foreach sessions as session { text= session.title details= session.startTime action= SessionDetails(
SessionById(session.talkId)) } } }
Demo 1
Mapping concepts to code
«Xpand»
Type safe
Produces any kind of text
Can run standalone(ANT / Maven)
Debugger
Profiler
Eclipse-based
Editor Protected regions
Cartridges
Outlets
Polymorphism
Mapping concepts to code
tableview SpeakerList( Speaker[] speakers) { title= "Speakers" section { cell Default foreach speakers as speaker { text= speaker.name image= speaker.smallImageURL action= SpeakerDetails (SpeakerById( speaker.speakerId)) } }}
Mapping concepts to code
«DEFINE viewModule FOR SectionedView»«FILE filenameModule()»#import "«filenameHeader()»"#import "NSObject+Applause.h"«EXPAND imports»
@implementation «className()»
«EXPAND sectionCount»«EXPAND sectionTitleHeader»«EXPAND rowCounts»«EXPAND cellDescriptions»«EXPAND cellSelections»«EXPAND staticData»@end«ENDFILE»«ENDDEFINE»
tableview SpeakerList( Speaker[] speakers) { title= "Speakers" section { cell Default foreach speakers as speaker { text= speaker.name image= speaker.smallImageURL action= SpeakerDetails (SpeakerById( speaker.speakerId)) } }}
Mapping concepts to code
Demo 2
3 things to take home
3 things to take home
Implementing DSLs is easy with Xtext1
Xtext delivers great IDE support2
Symbolic integration is possible3
More Info?Xtext Webinar:
http://live.eclipse.org/node/886
www.xtext.org
Consulting:http://www.itemis.com
@peterfriese | http://peterfriese.de