jazoon 2010 - building dsls with eclipse

Post on 15-Jan-2015

2.556 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

In this presentation, I show how to build an Xtext based DSL for iPhone and Android aplications.

TRANSCRIPT

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(“you@gmail.com”).from(“me@gmail.com”).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...

http://www.eclipse.org/Xtext/

@xtext

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

top related