Skip to content

Instantly share code, notes, and snippets.

@Potherca
Last active December 5, 2016 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Potherca/5502d8fb28af54186aa9f7caa72a96c1 to your computer and use it in GitHub Desktop.
Save Potherca/5502d8fb28af54186aa9f7caa72a96c1 to your computer and use it in GitHub Desktop.
Jison Grammar for PlantUML State Diagram
/* description: PlantUML State Diagram Grammar
*
* The format of the definition is:
*
* FROM --> TO : TRANSITION
*
* Where [*] has special meaning as start/stop
*
* Example:
*
* [*] -> State1
* State1 --> State2 : Succeeded
* State1 --> [*] : Aborted
*
* For full syntax definition see:
*/
/* lexical grammar */
%lex
%%
(\r?\n)+\s* return 'NEWLINE';
[^\S\r\n]+ ; /* whitespace */
[a-zA-Z]+[a-zA-Z]?\b return 'WORD'
":" return 'COLON'
"-->" return 'ARROW'
<<EOF>> return 'EOF'
/lex
%start expressions
%% /* language grammar */
expressions
: content NEWLINE expressions
| content expressions
| EOF {return yy.results || [];}
;
content
: WORD ARROW WORD COLON WORD {
if (!('results' in yy)) {yy.results = [];}
yy.results.push({
"name" : $5,
"from" : $1,
"to" : $3
});
}
;

Simple State

@startuml

[*] --> State1
State1 --> [*]
State1 : this is a string
State1 : this is another string

State1 -> State2
State2 --> [*]

@enduml

Composite state

@startuml
scale 350 width
[*] --> NotShooting

state NotShooting {
  [*] --> Idle
  Idle --> Configuring : EvConfig
  Configuring --> Idle : EvConfig
}

state Configuring {
  [*] --> NewValueSelection
  NewValueSelection --> NewValuePreview : EvNewValue
  NewValuePreview --> NewValueSelection : EvNewValueRejected
  NewValuePreview --> NewValueSelection : EvNewValueSaved
  
  state NewValuePreview {
     State1 -> State2
  }
  
}
@enduml

Long name

@startuml
scale 600 width

[*] -> State1
State1 --> State2 : Succeeded
State1 --> [*] : Aborted
State2 --> State3 : Succeeded
State2 --> [*] : Aborted
state State3 {
  state "Accumulate Enough Data\nLong State Name" as long1
  long1 : Just a test
  [*] --> long1
  long1 --> long1 : New Data
  long1 --> ProcessData : Enough Data
}
State3 --> State3 : Failed
State3 --> [*] : Succeeded / Save Result
State3 --> [*] : Aborted
 
@enduml

Concurrent state

@startuml
[*] --> Active

state Active {
  [*] -> NumLockOff
  NumLockOff --> NumLockOn : EvNumLockPressed
  NumLockOn --> NumLockOff : EvNumLockPressed
  --
  [*] -> CapsLockOff
  CapsLockOff --> CapsLockOn : EvCapsLockPressed
  CapsLockOn --> CapsLockOff : EvCapsLockPressed
  --
  [*] -> ScrollLockOff
  ScrollLockOff --> ScrollLockOn : EvCapsLockPressed
  ScrollLockOn --> ScrollLockOff : EvCapsLockPressed
}

@enduml

Arrow direction

@startuml

[*] -up-> First
First -right-> Second
Second --> Third
Third -left-> Last

@enduml

Notes

@startuml

[*] --> Active
Active --> Inactive

note left of Active : this is a short\nnote

note right of Inactive
  A note can also
  be defined on
  several lines
end note

@enduml


@startuml

[*] --> NotShooting

state "Not Shooting State" as NotShooting {
  state "Idle mode" as Idle
  state "Configuring mode" as Configuring
  [*] --> Idle
  Idle --> Configuring : EvConfig
  Configuring --> Idle : EvConfig
}

note right of NotShooting : This is a note on a composite state

@enduml

Skinparam

@startuml
skinparam backgroundColor LightYellow
skinparam state {
  StartColor MediumBlue
  EndColor Red
  BackgroundColor Peru
  BackgroundColor<<Warning>> Olive
  BorderColor Gray
  FontName Impact
}

[*] --> NotShooting

state "Not Shooting State" as NotShooting {
  state "Idle mode" as Idle <<Warning>>
  state "Configuring mode" as Configuring
  [*] --> Idle
  Idle --> Configuring : EvConfig
  Configuring --> Idle : EvConfig
}

NotShooting --> [*]
@enduml

TODO

  • Create Jison definition that parses a single line
  • Expand the Jison definition to parse all given lines
  • Add more syntax support:
    • Comments - Single or multi-line comments using ' … or /' … '/.
    • Composite state - A composite state can be define using the state keywords and brackets.
    • Long name - The state keyword can be used to add long description for states.
    • Concurrent state - Concurrent state can be defined into a composite state using either -- or || symbol as separator.
    • Arrow direction - It is possible to force arrow's direction using the following syntax: -down-> (default arrow), -right-> or ->, -left->, -up->. The arrow can be shortened by using only the first character or the two first characters of the direction (for example, -d- or -do- instead of -down-).
    • Note - Notes can be defined using note left of, note right of, note top of, note bottom of keywords. Notes can be defined on several lines.
    • Skinparam - The skinparam command can be used to change colors and fonts for the drawing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment