Domain-Specific Languages with
Sven Efftinge
copyright 2008 by itemis AG
Kiel, Germany
Jan Peter
Dennis
“... won’t talk
about
model-driven
stuff”
You’re lucky!
No UML!
No MDA!
No meta meta
meta meta ...
Hands-on a
concrete example
taken from Martin Fowler’s upcoming
Book on DSLs
You’re working for a company
specialized on systems for
secret compartments
Your customer:
Mrs. H
she likes secrets
To open the secret compartment, she has to
To open the secret compartment, she has to
close the door,
To open the secret compartment, she has to
close the door,
open the second draw in
her chest,
To open the secret compartment, she has to
close the door,
open the second draw in
her chest,
turn her bedside light on.
events
doorClosed
drawOpened
lightOn
doorOpened
panelClosed
end
resetEvents
doorOpened
end
commands
unlockPanel
lockPanel
lockDoor
unlockDoor
end
state idle
actions {unlockDoor lockPanel}
doorClosed => active
end
state active
drawOpened => waitingForLight
lightOn => waitingForDraw
end
state waitingForLight
lightOn => unlockedPanel
end
state waitingForDraw
drawOpened => unlockedPanel
end
state unlockedPanel
actions {unlockPanel lockDoor}
panelClosed => idle
end
External DSL Internal DSL
events event :doorClosed
doorClosed event :drawOpened
drawOpened
event :lightOn
lightOn
doorOpened event :doorOpened
panelClosed event :panelClosed
end
command :unlockPanel
resetEvents command :lockPanel
doorOpened
end command :lockDoor
command :unlockDoor
commands
unlockPanel resetEvents :doorOpened
lockPanel
lockDoor
unlockDoor
state :idle do
end actions :unlockDoor, :lockPanel
transitions :doorClosed => :active
state idle end
actions {unlockDoor lockPanel}
doorClosed => active
state :active do
end
transitions :drawOpened => :waitingForLight,
state active :lightOn => :waitingForDraw
drawOpened => waitingForLight end
lightOn => waitingForDraw
end state :waitingForLight do
state waitingForLight transitions :lightOn => :unlockedPanel
lightOn => unlockedPanel end
end
state :waitingForDraw do
state waitingForDraw transitions :drawOpened => :unlockedPanel
drawOpened => unlockedPanel
end
end
state unlockedPanel state :unlockedPanel do
actions {unlockPanel lockDoor} actions :unlockPanel, :lockDoor
panelClosed => idle transitions :panelClosed => :idle
end
end
External DSL Internal DSL
events event :doorClosed
doorClosed event :drawOpened
drawOpened event :lightOn
lightOn
doorOpened event :doorOpened
panelClosed event :panelClosed
end
command :unlockPanel
resetEvents command :lockPanel
doorOpened
end command :lockDoor
command :unlockDoor
commands
unlockPanel resetEvents :doorOpened
lockPanel
lockDoor
unlockDoor
state :idle do
end actions :unlockDoor, :lockPanel
transitions :doorClosed => :active
state idle end
actions {unlockDoor lockPanel}
doorClosed => active
state :active do
end
transitions :drawOpened => :waitingForLight,
state active :lightOn => :waitingForDraw
drawOpened => waitingForLight end
lightOn => waitingForDraw
end state :waitingForLight do
state waitingForLight transitions :lightOn => :unlockedPanel
lightOn => unlockedPanel end
end
state :waitingForDraw do
state waitingForDraw transitions :drawOpened => :unlockedPanel
drawOpened => unlockedPanel
end end
state unlockedPanel state :unlockedPanel do
actions {unlockPanel lockDoor} actions :unlockPanel, :lockDoor
panelClosed => idle transitions :panelClosed => :idle
end
end
On top of external DSLs
no compromises
On top of external DSLs
no compromises
domain-specific static analysis
On top of external DSLs
no compromises
domain-specific static analysis
graphical views
On top of external DSLs
no compromises
domain-specific static analysis
graphical views
closed scope
Statemachine :
'events'
(events+=Event)+
'end'
'resetEvents' followed by at least one
(resetEvents+=[Event])+
'end' definition of Event
'commands'
(commands+=Command)+
'end'
(states+=State)+;
Event :
name=ID;
which is defined here and
Command :
name=ID;
consists of just one
identifier (ID)
State :
'state' name=ID
('actions' '{' (actions+=[Command])+ '}')?
(transitions+=Transition)*
'end';
Transition :
event=[Event] '=>' state=[State];
Statemachine :
'events'
(events+=Event)+
'end'
'resetEvents'
(resetEvents+=[Event])+
'end'
'commands'
(commands+=Command)+
'end'
(states+=State)+; this is a cross reference,
Event : referencing Events
name=ID;
declared in the previous
Command :
name=ID; section.
State :
'state' name=ID
('actions' '{' (actions+=[Command])+ '}')?
(transitions+=Transition)*
'end';
Transition :
event=[Event] '=>' state=[State];
Statemachine :
'events'
(events+=Event)+
'end'
'resetEvents'
(resetEvents+=[Event])+
'end'
'commands'
(commands+=Command)+
'end'
(states+=State)+;
Event :
name=ID;
commands are very
Command :
similar to events
name=ID;
State :
'state' name=ID
('actions' '{' (actions+=[Command])+ '}')?
(transitions+=Transition)*
'end';
Transition :
event=[Event] '=>' state=[State];
Statemachine :
'events'
(events+=Event)+
'end'
'resetEvents'
(resetEvents+=[Event])+
'end'
'commands'
(commands+=Command)+
'end'
(states+=State)+;
Event : States have a name (ID)
name=ID;
Command :
name=ID;
State :
'state' name=ID
('actions' '{' (actions+=[Command])+ '}')?
(transitions+=Transition)*
'end';
Transition :
event=[Event] '=>' state=[State];
Statemachine :
'events'
(events+=Event)+
'end'
'resetEvents'
(resetEvents+=[Event])+
'end'
'commands'
(commands+=Command)+
'end'
(states+=State)+;
Event : States have a name (ID)
name=ID;
Command :
name=ID;
optional action block
State :
'state' name=ID
('actions' '{' (actions+=[Command])+ '}')?
(transitions+=Transition)*
'end';
Transition :
event=[Event] '=>' state=[State];
Statemachine :
'events'
(events+=Event)+
'end'
'resetEvents'
(resetEvents+=[Event])+
'end'
'commands'
(commands+=Command)+
'end'
(states+=State)+;
Event : States have a name (ID)
name=ID;
Command :
name=ID;
optional action block
State :
'state' name=ID
('actions' '{' (actions+=[Command])+ '}')?
(transitions+=Transition)*
'end';
Transition :
any number of Transitions
event=[Event] '=>' state=[State];
This was the example DSL
implemented in
So what do we get from such a
description?
Antlr based Parser
Antlr based Parser
Eclipse based Editor
Antlr based Parser
Eclipse based Editor
Statemachine
commands * events
* resetStates * states
Command State Event
name:String * name:String name:String
actions
state
event
EMF based Semantic Model
*
Transition
Demo
oaw.itemis.com
Thank you very much!
the eclipse distro can be downloaded from
http://oaw.itemis.com
0 comments
Post a comment