Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Appendix H: Lexical Reference

The chapters teach constructs. This appendix covers the smaller rules underneath them – how names, literals, and comments are actually written – and in particular the two forms the chapters use without stopping to explain: root-qualified names and quoted names.

Names

An ordinary name is an identifier: CoffeeMachine, grindSize, waterTank. The book’s convention, and a common one, is UpperCamelCase for definitions and lowerCamelCase for usages and attributes. Nothing in the language enforces that, but a reader scanning a model relies on it.

Qualified and root-qualified names

<Package>::<Member>
$::<Package>::<Member>
part grinder : CoffeeMachineDomain::Definitions::Grinder;

A qualified name walks down from a visible namespace. Reach for one when a bare name would be ambiguous across packages.

Prefixing $:: makes it a root-qualified name: lookup starts at the model root rather than the enclosing scope. It is the escape hatch for the case where a local name shadows the one you meant.

Quoted names, for names that are not identifiers

<'<short-name>'> '<long name>'
requirement def <'REQ-TEMP-01'> 'Extraction Temperature' {
    doc /* Water temperature shall remain within operating range. */
}

Read it as: this requirement’s short name is REQ-TEMP-01 and its name is Extraction Temperature.

A name in single quotes is an unrestricted name, and it may contain characters an identifier cannot – spaces, hyphens, punctuation. Angle brackets declare a short name, which is why requirement identifiers like REQ-TEMP-01 are written <'REQ-TEMP-01'>: the hyphens would otherwise be read as subtraction. To put a quote inside such a name, escape it: 'REQ\'TEMP-02'.

This is the form Chapter 10 and Chapter 11 use for requirement identifiers.

Use quoted names where they earn their keep – requirements and cases that carry an external identifier or a human-readable title – and plain identifiers everywhere else.

Literals

attribute grindSize   : Real    = 0.4;
attribute enabled     : Boolean = true;
attribute label       : String  = "Main Grinder";
  • Booleans are true and false.
  • Strings are double-quoted.
  • Reals may lead with a dot – .5 is valid – and may use scientific notation: 1e3, 9.8e-2.
  • null is the null literal. () is an equivalent spelling of the same empty value, which is worth recognising when you meet it in library sources.
  • * is the infinity literal. It is what makes [0..*] mean “any number of” in a multiplicity, and it is the same token as multiplication – position tells them apart.

Comments, and why doc is different

part def Brewer {
    doc /* Heats and pressurizes water for extraction. */

    //* A note to whoever is editing this file next.
    attribute waterTemp : Real = 93.0;
}

doc creates a documentation element in the model. It survives into the model itself, so tools can show it on hover, carry it into a generated document, and export it through the API.

//* notes do not. Per the specification’s own grammar they are hidden tokens, discarded during parsing in the same way whitespace is. They never become part of the model.

So the choice is not stylistic. If the sentence explains what an element is, it belongs in doc, where a reviewer who never opens the source file will still see it. If it is a message to the next person editing the file, //* is right.

The most common mistake here is writing model meaning into a note and then wondering why it does not appear anywhere in the tooling.

Marking the language of documentation

part def Brewer {
    doc locale "en-GB" /* Heats and pressurises water for extraction. */
}

A doc may carry a locale – a string naming the natural language the documentation is written in. It is optional, and worth setting on a model whose documentation is translated or whose readership is mixed, because it lets a tool pick the right text rather than guessing. Comments take the same modifier.

Embedding another language

The specification also provides a way to carry a fragment of some other language inside a model element:

[rep <name>] language "<language-name>" /* <the fragment> */

This is a textual representation (SysML §8.2.2.4.3). The intent is that a constraint expressed in OCL, a formula in MathML, or a snippet of source can travel with the element it belongs to, tagged with what language it is in, so a tool that understands that language can pick it up and one that does not can leave it alone.

Not available in sysml-rs. The parser does not accept this form. Worse, a rep line without the string is absorbed as a pair of ordinary names rather than reported as an error, so it fails quietly. The construct is in the specification and in the grammar; it is simply not implemented here, and this book does not use it.