Potherca
7/27/2016 - 8:29 PM

Jison Grammar for PlantUML State Diagram

Jison Grammar for PlantUML State Diagram

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.

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
/* 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
            });
    }
;

Introduction

The idea is to create a Jison definition that represents the PlantUML State Diagram syntax.

This is currently a work in progress.

The attached Jison file can be tried and debugged in the online tools provided on the Jison site.