@startuml
[*] --> read

read: The entry point
read ---> [*]: guard:eof-object?
read --> skip_global_comment: guard:semicolon?
read --> read_section_title: guard:left-square-bracket?
read --> read_property_key: guard:letter? -> action:store
read -> read

read_property_key: Read a property key.
read_property_key ---> [*]: guard:eof-object? -> action:syntax-error
read_property_key ---> [*]: guard:newline? -> action:syntax-error
read_property_key --> trim_property_key: guard:space?
read_property_key --> trim_property_value: guard:equals-sign? -> action:update-stanza
read_property_key -> read_property_key: guard:#t -> action:store

trim_property_key: Skip all trailing spaces after the key.
trim_property_key ---> [*]: guard:eof-object? -> action:syntax-error
trim_property_key --> trim_property_value: guard:equals-sign? -> action:update-stanza
trim_property_key -> trim_property_key

trim_property_value: Trim spaces around a global property value.
trim_property_value ---> [*]: guard:eof-object? -> action:syntax-error
trim_property_value --> read_property_value: guard:letter? -> action:store
trim_property_value -> trim_property_value

read_property_value: Read a global property value.
read_property_value ---> [*]: guard:eof-object? -> action:syntax-error
read_property_value --> read: guard:newline? -> action:append-property
read_property_value -> read_property_value: guard:#t -> action:store

skip_global_comment: Skip a comment that is placed upon all the sections
skip_global_comment --> read: guard:newline?
skip_global_comment -> skip_global_comment

read_section_title: Read and store a section title
read_section_title --> [*]: guard:eof-object?
read_section_title --> read_section_content: guard:right-square-bracket? -> action:start-section
read_section_title --> read_section_title: guard:#t -> action:store

read_section_content: Read properties written in a section.
read_section_content ---> [*]: guard:eof-object?
read_section_content --> skip_comment: guard:semicolon?
read_section_content --> read_section_property_key: guard:letter? -> action:store
read_section_content --> read_section_title: guard:left-square-bracket?
read_section_content -> read_section_content

skip_comment: Skip a comment inside a section.
skip_comment --> [*]: guard:eof-object?
skip_comment --> read_section_content: guard:newline?
skip_comment -> skip_comment

read_section_property_key: Read a section property key.
read_section_property_key ---> [*]: guard:eof-object? -> action:syntax-error
read_section_property_key ---> [*]: guard:newline? -> action:syntax-error
read_section_property_key --> trim_section_property_key: guard:space?
read_section_property_key --> trim_section_property_value: guard:equals-sign? -> action:update-stanza
read_section_property_key -> read_section_property_key: guard:#t -> action:store

trim_section_property_key: Skip all trailing spaces after the key.
trim_section_property_key ---> [*]: guard:eof-object? -> action:syntax-error
trim_section_property_key ---> [*]: guard:letter? -> action:syntax-error
trim_section_property_key --> trim_section_property_value: guard:equals-sign? -> action:update-stanza
trim_section_property_key -> trim_section_property_key

trim_section_property_value: Trim all the spaces before the section property value.
trim_section_property_value ---> [*]: guard:eof-object? -> action:syntax-error
trim_section_property_value --> trim_section_property_value: guard:space?
trim_section_property_value --> read_section_property_value: guard:newline?
trim_section_property_value --> read_section_property_value: guard:#t -> action:store

read_section_property_value: Read the section property value.
read_section_property_value ---> [*]: guard:eof-object?
read_section_property_value --> read_section_content: guard:newline? -> action:append-property
read_section_property_value -> read_section_property_value: guard:#t -> action:store
@enduml