Skip to content

Activities

Leon Starr edited this page Aug 4, 2026 · 3 revisions

Shlaer-Mellor defines a single activity per state. That activity consists of zero or more actions.

state LOCKED
activity
    // Tell the cabin that we’re ready to go
    Lock requested.unset
    Doors secure -> /R4/Cabin
transitions
    Unlock > OPENING
--

The grammar is short because most of the work isn't done here:

activity = activity_header body_line* // A block of activity text (not parsed further)
activity_header = "activity" EOL
body_line = '\n' / (INDENT r'.*\n') // An unstructured line of text for capturing action language to be parsed elsewhere

An unindented activity keyword, then any number of body lines. A body line is either completely blank or indented by four spaces, after which anything goes until the end of the line.

The body is not parsed here

That comment on the body_line rule is the important part. The xsm parser deliberately does not interpret the activity body. It collects the lines as raw text and hands them off, because the body is written in an action language — Scrall in my case — with a grammar of its own and its own parser.

This separation is why an xsm file will happily parse even if the action language inside it is nonsense. A typo in Doors secure -> /R4/Cabin won't be caught until a downstream module parses the activity. Don't read a clean xsm parse as a clean state model.

It also means the xsm language doesn't constrain your choice of action language. If you write activities in something other than Scrall, the xsm grammar won't object.

Empty activities

A state whose activity does nothing still needs the keyword:

state OPENING
activity
transitions
    Door opened > OPEN
    Passenger close > CLOSING
--

Wait states frequently have empty activities. That's the whole point of a waiting state: arrive, do nothing, wait for an event. Some modelers drop in a comment rather than leave it bare, which is why you see things like this in the R53 assigner:

state NO TRANSFER
activity
    // Waiting for service request
transitions
    Service requested > Search for new destination
--

Comments in the body are just body text as far as this grammar is concerned.

Indentation

Every non-blank body line must start with the four space INDENT. Beyond those four spaces you can indent as deeply as you like — the action language may well have its own block structure, and the R53 and Door activities do use deeper indentation for continuation and nesting:

state OPEN
activity
    my Bank .= /R4/R2/R1/Bank
    Blocked? delay = my Bank.Block clear time :
        delay = my Bank.Passenger load time
    Time to close -> me @delay

Clone this wiki locally