17. To open the secret compartment, she has to
close the door,
18. To open the secret compartment, she has to
close the door,
open the second draw in
her chest,
19. To open the secret compartment, she has to
close the door,
open the second draw in
her chest,
turn her bedside light on.
20. 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
21. 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
22. 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
32. 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];
33. 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];
34. 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];
35. 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];
36. 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];
37. 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];
38. This was the example DSL
implemented in
So what do we get from such a
description?
42. 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