@startuml
title PlantUML <plantuml.com> Reader FSM. This diagram is a part of Guile-SMC <github.com/artyom-poptsov/guile-smc>

' Entry point
[*] -> read_start_tag

' Reading 
read_start_tag --> [*]: guard:eof-object? -> action:unexpected-end-of-file-error
read_start_tag --> read: guard:space? -> action:check-start-tag
read_start_tag --> read: guard:newline? -> action:check-start-tag
read_start_tag -> read_start_tag: guard:#t -> action:store

' Main FSM reading state
read -> [*]: guard:eof-object? -> action:unexpected-end-of-file-error
read --> read_end_tag: guard:at-symbol? -> action:store
read --> read_skip_comment: guard:single-quote?
read --> read_state: guard:left-square-bracket?
read --> read_word: guard:letter? -> action:store
read -> read

' Read 
' TODO: Add end tag check.
read_end_tag: exit-action: action:check-end-tag
read_end_tag --> [*]: guard:eof-object?
read_end_tag --> [*]: guard:newline?
read_end_tag --> [*]: guard:space?
read_end_tag ->  read_end_tag: guard:#t -> action:store

' Skipping comments
read_skip_comment --> [*]: guard:eof-object?
read_skip_comment --> read: guard:newline?
read_skip_comment ->  read_skip_comment

read_word --> [*]: guard:eof-object?
read_word --> read_title: guard:title? -> action:update-stanza
read_word --> search_state_transition: guard:space? -> action:update-stanza
read_word --> read_state_description: guard:colon? -> action:update-stanza
read_word -> read_word: guard:#t -> action:store

read_title --> [*]: guard:eof-object?
read_title --> read: guard:newline? -> action:add-description
read_title -> read_title: guard:#t -> action:store

' Reading state name
read_state --> [*]: guard:eof-object?
read_state --> search_state_transition: guard:right-square-bracket? -> action:update-stanza
read_state --> search_state_transition: guard:space? -> action:update-stanza
read_state --> read_state_description: guard:colon? -> action:update-stanza
read_state -> read_state: guard:#t -> action:store

' Reading state transition
search_state_transition --> [*]: guard:eof-object?
search_state_transition --> read_state_description: guard:colon?
search_state_transition --> read_state_right_arrow: guard:hyphen-minus?
search_state_transition --> read_state_left_arrow: guard:less-than-sign?
search_state_transition ->  search_state_transition

' Reading state description
read_state_description --> [*]: guard:eof-object?
read_state_description --> read: guard:newline? -> action:add-state-description
read_state_description ->  read_state_description

read_state_right_arrow --> [*]: guard:eof-object?
read_state_right_arrow --> search_state_transition_to: guard:space?
read_state_right_arrow -> read_state_right_arrow

search_state_transition_to --> [*]: guard:eof-object?
search_state_transition_to --> read_state_transition_to: guard:letter? -> action:store
search_state_transition_to --> read_state_transition_to: guard:left-square-bracket?
search_state_transition_to -> search_state_transition_to

read_state_transition_to --> [*]: guard:eof-object?
read_state_transition_to --> read_state_transition_to: guard:right-square-bracket?
read_state_transition_to --> search_state_transition_guard: guard:colon? -> action:update-stanza
read_state_transition_to --> read: guard:newline? -> action:add-state-transition
read_state_transition_to -> read_state_transition_to: guard:#t -> action:store

search_state_transition_guard --> [*]: guard:eof-object?
search_state_transition_guard --> read_state_transition_guard: guard:letter? -> action:store
search_state_transition_guard -> search_state_transition_guard

read_state_transition_guard --> [*]: guard:eof-object?
read_state_transition_guard --> search_state_action_arrow: guard:space? -> action:update-stanza
read_state_transition_guard --> read: guard:newline? -> action:add-state-transition
read_state_transition_guard -> read_state_transition_guard: guard:#t -> action:store

search_state_action_arrow --> [*]: guard:eof-object?
search_state_action_arrow --> read: guard:newline?
search_state_action_arrow --> read_state_action_arrow: guard:hyphen-minus?
search_state_action_arrow -> search_state_action_arrow

read_state_action_arrow --> [*]: guard:eof-object? -> action:unexpected-end-of-file-error
read_state_action_arrow --> [*]: guard:newline?
read_state_action_arrow --> search_state_transition_action: guard:more-than-sign?

search_state_transition_action --> [*]: guard:eof-object? -> action:unexpected-end-of-file-error
search_state_transition_action --> read_state_transition_action: guard:letter? -> action:store
search_state_transition_action --> [*]: guard:newline?
search_state_transition_action -> search_state_transition_action

read_state_transition_action --> [*]: guard:eof-object? -> action:unexpected-end-of-file-error
read_state_transition_action --> read: guard:newline? -> action:add-state-transition
read_state_transition_action -> read_state_transition_action: guard:#t -> action:store
@enduml