-
Notifications
You must be signed in to change notification settings - Fork 0
Names
Unlike program code, models should express the components and behavior of your system as clearly as possible to mere humans. The grammar supports a more natural language friendly way of naming state model elements like transitions, events and states with rules that would horrify most programmers. Within some limits, of course as we do need to ensure the models are unambiguous and executable, unlike natural language.
Our state modeling grammar threads that needle, so before diving in, you may want to review the precise naming rules.
Almost everything you write in an xsm file — a domain, a class, an event, a state, a parameter, a type — is
a name. Here's the grammar:
// Elements
name = word (delim word)* r'\?'? // A name is a sequence of one or more words separated by delimiters with optional ?
word = r"[A-Za-z][A-Za-z0-9']*" // Word beginning with an alpha character allowing apostrophe for contractions
delim = r'[ _]' // Delimiter used inside of names
INDENT = " " // Need INDENT for clarity and to signal unstructured lines of text
block_end = "--" EOL* // Signifies end of a block (within section)
rnum = r'O?R[1-9][0-9]*' // Relationship number
A word starts with a letter and continues with letters, digits and apostrophes. So Door, R2, Level2
and driver's are all words. A word may not start with a digit or contain a hyphen.
This means that you can have a state named: Is it there yet?
Or you can name an event: Can't close the door
As you can see in the grammar, a question mark may only appear at the end of a name.
Caveat: The above grammar is only for structural model elements and not the action language used inside
a state's activity section. The Scrall action language uses a
different parser and grammar that employs many punctuation characters as operators and other computational
elements. Don't worry, the naming rules aren't that different, but punctuation characters
like ' and ? are not available for naming within an activity.
Words within a name are joined by a single space or a single underscore. That's what makes
Can't close door one event name rather than three words, and it's why multi-word names read so naturally
in this language.
Note, however:
-
One delimiter only.
Cannot close doorwith two spaces is not a name. -
Spaces and underscores are not equivalent.
Are we there?andAre_we_there?both parse, but they are different names. So choose your naming style and stick with it.
A name may end in a single ?, which is useful for states that ask something:
state Are we already there?
The ? is part of the name. Any transition targeting that state has to include it.
The grammar doesn't enforce all aspects of this style, but I have adopted a consistent style for naming model elements.
- Class and domain names get initial caps on each significant word —
Accessible Shaft Level. - Waiting states are all caps and transient states are mixed case.
- Keywords are all lowercase and unindented:
metadata,domain,class,relationship,events,initial transitions,state,activity,transitions.
The INDENT token is exactly four spaces. It's what marks metadata items, event declarations, transitions
and Activities body lines, and it's how the grammar distinguishes structure from the
unstructured action language text inside an activity. Tabs will not do, and neither will two or six spaces
at the structural level — though within an activity body you may indent as deeply as you like past the
first four.
The -- token, always unindented, closes the Events block, the Initial transitions section and
each individual state block. It's the one piece of punctuation doing real structural work in this language.
Note that it closes a block, not every section within one. The events block holds two sections
(interaction events and completion events) and a state block holds three (transitions, ignore and
can't happen), but each block still ends with exactly one --.
// Whitespace and comments
EOL = SP* COMMENT? '\n' // end of line: Comments, blank lines, whitespace we can omit from the parser result
COMMENT = '//' r'.*' // Comment slashes don't work if included in the regular expression for some reason
SP = " "
A comment starts with // and runs to the end of the line. Blank lines are fine between sections. Both are
discarded by the parser and never appear in the result — with the exception of comments inside an
activity body (see Activities), which are just part of the raw action language text and get passed straight
through.
Copyright 2023-2026 © Leon Starr under MIT Open Source License