h1(#the-statechart-language). The statechart language This chapter describes the statechart elements of the YAKINDU Statechart Tools (YAKINDU SCT) editor. The YAKINDU SCT meta model is the model of finite state machines. It is based on the view of a system that is defined by a finite number of states. The behavior of such a system is based on its active states. These states are determined by the history of the state machine. Very important are the theoretical models for state machines by Mealy and Moore. Mealy state machines associate actions with transitions. Moore machines associate actions with states (_entry_, _exit_). YAKINDU SCT can model both these types. The YAKINDU SCT meta model is designed similar to the UML statechart meta model with the following differences: * YAKINDU SCT statecharts are self-contained with interfaces defined by events and variables. * Core execution semantics are run cycle-driven, not event-driven. ** This allows to process concurrent events. ** Event-driven behavior can be defined on top. * Time is an abstract concept for statecharts. * Time control is delegated to the environment. The model interpreter and different flavors of generated code are following these same core semantics. Please refer to the Wikipedia article "UML state machine":http://en.wikipedia.org/wiki/UML_state_machine for more details. A textual description language is used to declare and describe behaviors in a state machine. It is case sensitive. h2(#statechart). Statechart A statechart or statechart model consists of several components. The most important part is the *state diagram*, comprising "states":#state and "transitions":#transition. They are organized into zero or more "regions":#region. The *definition sections* is a textual statechart component. It contains definitions of namespaces, interfaces, variables, events, operations, etc. Most objects defined in the definition section are _typed_. For example, a variable could be of type _integer_. As another example, the type of an operation is by defined by the number and types of its parameters and its return type, if any. A type system or *domain* specifies which types are available. YAKINDU Statechart Tools has a built-in type system. %(pro-feature)The Professional Edition allows for additional domains to be installed.% h2(#graphical-elements). Graphical elements h3(#region). Region As already mentioned, the YAKINDU statecharts are self-contained. They are organized in regions. Due to this it is possible to organize multiple state machines in different regions and to run them concurrently. !(standard-image)images/docu_parallelRegions.jpg(Parallel regions)! p=. Parallel regions h3(#state). State States are the central elements of a state machine. A state has to be placed inside a region and must have a name that is unique inside this region. During simulation, each state can be active or passive. An active state has actions that are accomplished. Either an action is carried out on entering a state, during active state, or on exit. h3(#transition). Transition A transition is the transfer of one state to another. A transition is diagrammed as a arrow leading from a _source state_ to a _target state_. A transition can also have * an _event trigger_, specifying which event(s) trigger the transition, * a _guard_, specifying which condition(s) must be fulfilled to trigger the transition, * an _effect_, specifying actions like assignments to variables, operations calls etc. that are to take place when this transition is executed. All of these three elements are optional, i. e. a transition may have one or more or them, but it doesn't need to. Events triggers, guard conditions, and effects are specified as a text that is attached to the transition arrow in the diagram. "Figure "Transition syntax overview"":#fig_transition-syntax-overview shows how the syntax of a transition specification is defined. You can refer to this diagram while reading the subsequent sections. p(#fig_transition-syntax-overview). !(standard-image)images/docu_grammar_030_transition-overview.png(Transition syntax overview)! p=. Transition syntax overview h4(#transition-without-specification). Transition without specification In the most simple case we have only the transition's arrow leading from a source state to a target state without any additional specification. In other words, there is no text attached to the transition. However, such an event will never be taken, so better make sure to set up a transition specification. h4(#event-triggers). Event triggers When an "event":#events occurs, it may trigger a transition to "fire". The transition's source state, which is the currently active state, becomes inactive, control is transferred along the transition's arrow to the latter's target state, and that state becomes the newly active state. Events must be declared in the definition section, see section ""Events"":#events. Let's have a look at some sample transition specifications. We are assuming that the transition's source state is active, because otherwise the transition wouldn't fire anyway. | *Transition specification:* | *Condition for the transition to fire:* | | @my_event@ | Event _my_event_ occured. | | @my_event_1, my_event_2@ | At least one the events _my_event_1_ and _my_event_2_ occured. | | @after 3s@ | Three seconds after activating the source state have passed. | | @after 3, my_events@ | Three seconds have passed or event _my_event_ occurred, whatever happens first. | | @after 3, after 2@ | Three seconds have passed or two seconds have passed, whatever happens first. :-) | | @every 3s@ | Three seconds after activating the source state have passed. | | @always@ | Transition fires always. | | @default@ | Transition fires always. | | @else@ | Transition fires always. | | @oncycle@ | Transition fires always. | For more details on the @after@, @every@, @always@, @default@, @else@, and @oncycle@ specifications, please see "section "Reaction triggers"":#reaction-triggers. h4(#entry-and-exit-points). Entry and exit points Unlike transitions as defined by the "UML":https://en.wikipedia.org/wiki/Unified_Modeling_Language, transitions in YAKINDU Statecharts may also denote specific entry or exit points when leaving or entering composite states. This is explained in detail in the sections ""Named entries"":#named-entries and ""Exit"":#exit. h4(#transition-priorities). Transition priorities If a state has several outgoing transitions, these transitions are _prioritized_. The state machine checks the transitions one by one in their defined order and execute the first transition that fulfills all prerequisites for firing. The order of transitions is a property of their source state and can be changed using the statechart editor. h3(#entry). Entry When a state machine starts or when the control flow enters a "region":#region, an _entry_ defines which state is to be activated first. The flow passes through the state machine's or the region's entry and transitions to the target state the entry's transition is pointing to. This state becomes active. An entry has a single outgoing transistion and no incoming ones. Its outgoing transition has neither a trigger nor a guard condition. An entry is depicted as a filled circle, see "figure "Entry, exit, and final state"":#fig_state_entry_exit_final_explained. p(#fig_state_entry_exit_final_explained). !(standard-image)images/docu_state_entry_exit_final_explained.png(Entry, exit, and final state)! p=. Entry, exit, and final state h4(#default-entry). Default entry and initial state An entry without a name is called the _default entry_. It is similar to the UML's _initial state_. However, while the transition from the initial state to an ordinary state may specify a guard, the transition sourced at an entry cannot. A region may have at most one default entry. h4(#named-entries). Named entries The "default entry":#default-entry specifies a single entry point into a region. A region can provide a multitude of additional or alternative entry points, thus implementing different kinds of behavior, depending on which entry point has been taken. If a region comprises multiple entries, these entries must be _named_. An entry's name must be unique within its region. The default entry implicitly has the name @default@. Alternatively, it is possible to explicitly give the name @default@ to the default entry. Semantically both variants are equivalent. Whether an entry has no name or it has the name @default@: in both cases the entry is called _default entry_. An incoming transition specifies a named entry to be used by the entry's _name_. This is done in a so-called _transition property_ of the transition, according to the following format: @# >@ _entry-name_ Named entries have no equivalent in the UML. The sample statechart in "Figure "Entry state"":#fig_state_entry has a composite state named _Handle result_. This composite state has a default entry as well as an entry called _failure_. If state _A_ is active and the _error_ trigger fires, control is transitioned to the _Handle result_ composite state. The notation @error # >failure@ specifies that the _failure_ entry is to be used. p(#fig_state_entry). !(standard-image)images/docu_state_entry.png(Entry state)! p=. Entry state h3(#exit). Exit An _exit_ is a pseudo state that is used to leave and deactivate a composite state. Exits are counterpart to "entries":#entry. They are also known as exit points, exit states, or exit nodes. See "section "Final state"":#final for a different way to terminate a region or state machine. An exit may have multiple incoming transitions and has no outgoing one. An exit state is depicted as an unfilled circle with an X-shaped cross, see "figure "Entry, exit, and final state"":#fig_state_entry_exit_final_explained. Within a region, multiple exits are allowed. Each exit must either have a name that is unique within its region or be the _default exit_. The default exit is either unnamed or has the name @default@, which is semantically equivalent. A region may have at most one default exit. When a composite state reaches an exit in any of its regions, all states in other regions of that composite state, if any, are deactivated immediately. The composite state will be left and be deactivated. It maintains no status information that could be probed from the outside. In other words, reaching an exit in one of a composite state's regions has severe consequences for all the other regions since they are exited and disposed immediately. After that, the containing composite state is also exited. There must be an unguarded transition that catches the exit and leads to another state outside of the composite state. The semantics of exit is different from that of final state; please see "section "Final state"":#final for details. A transition that has a composite state as its source can specify which exits should trigger it. That is, different exits can lead to different behavior on the outside. A transition specifies the exits to react upon as a so-called _property_ which looks like this: @#@ _exit-point-1_@>@ [ _exit-point-2_@>@ ]… Exits have no equivalent in the UML. The sample statechart in "figure "Entries and exits"":#fig_state_entry_exit contains two composite states: * The composite state _Process_ models a process with two passes (states) A and B. If both passes succeed, the composite state is left via the _no_problem_ exit node. However, if an error occurs in either A or B the execution flow proceeds to the _problem_ exit point and leaves the composite state there. * The composite state _Handle result_ is intended to handle the processing result, be it success or failure. It has two entry points _success_ and _failure_. The question is how to connect the exit points of _Process_ to the corresponding entry points of _Handle result_. This is done by two transitions leading from _Process_ to _Handle result_ and appropriate specifications. The transition shown on the left specifies @# no_problem> >success@. This means: If the source composite state is left via the _no_problem_ exit point, enter the target composite state at the _success_ entry point. The specification of the transition on the right is analogous: If the source state is left via the _problem_ exit point, enter the target state at the _failure_ entry point. The order of exit and entry points in a transition specification is irrelevant. Instead, the position of the @>@ character is decisive: * If the @>@ character is to the _right_ of a name, like in @exit_name>@, that name denotes an _exit_. * If the @>@ character is to the _left_ of a name, like in @>entry_name@, that name denotes an _entry_. Alternatively, _Process_ could have been modeled with two different error exit states, say _error_1_ and _error_2_. This would allow to respond differently to different error conditions, while still enabling to catch them both with a single flow. A transition with @# >error_1 >error_2 problem>@ would do so. p(#fig_state_entry_exit). !(standard-image)images/docu_state_entry_exit.png(Entries and exits)! p=. Entries and exits h3(#final). Final state A _final state_ denotes the end of the execution flow of a state machine or region. See "section "Exit"":#exit for a different way to terminate a composite state. A final state is depicted as an unfilled circle with a smaller filled black circle inside, see "figure "Entry, exit, and final state"":#fig_state_entry_exit_final_explained. A final state can have multiple incoming transitions and has no outgoing ones. Within a region, only a single final state is allowed, but each region may have its own final state. When a region reaches its final state, control stops there and waits until all other orthogonal regions, if any, have reached their respective final states, too. The semantics of final states is different from that of exits; please see "section "Exit"":#exit for details. bq.. *Note* Final states are proper states. This is different from the UML, where a final state is a pseudo state, i. e. in the UML, it cannot have any properties normal states can have, except for a name. h3(#choice). Choice A choice is a pseudo state. It can be used to model a conditional path. A choice node divides a transition into multiple parts. Usually the first transition points towards the choice node. One of the choice's outgoing transitions can carry a condition. h3(#synchronization). Synchronization Synchronization is a means to either split a flow into several parallel regions of a substate or to join several parallel flows from orthogonal regions into a single flow. The synchronization state corresponds to the UML's concepts of fork and join. Whether a synchronization state behaves as a fork or as a join depends on its usage. * A synchronization with a single incoming transition and several outgoing ones _forks_ the flow into several regions of the same substate. These regions are executed in parallel, see "section "Orthogonal states"":#orthogonal-states. * A synchronization with several incoming transitions from parallel regions of the same substate and a single outgoing transition _joins_ the incoming flows into a single flow of execution. A synchronization state is shown as a thick horizontal or vertical line, as can be seen in figure "Synchronization state":#fig_state_synchronization. p(#fig_state_synchronization). !(standard-image)images/docu_state_synchronization.png(Synchronization state)! p=. Synchronization state For a synchronization to actually join the incoming transitions and execute the outgoing one, all of the following conditions must be met: * All source states must be active. * All guard conditions that are specified must be fulfilled. * If one or more triggers are defined, at least one trigger must fire at a point in time while the conditions above are met. "Figure "Synchronization state"":#fig_state_synchronization shows a sample statechart containing a forking and a joining synchronization. After having left the @Initialize@ state, the synchronization state forks the execution flow into two regions @r1@ and @r2@. Both are part of the @Process@ composite state and both are executed in parallel. That is, when activating @Process@, the substates @Line A 1@ and @Line B 1@ also become active. When the flows continues and both @Line A 2@ and @Line B 2@ have been reached, the synchronization state on the right-hand side joins the flows and transitions to substates @Cleanup@, making it the active state. However, as long as only one of them is active, the synchronization will wait for the other one to also become active before proceeding to @Process@. The example also demonstrates different lengths and orientations of the synchronization symbol. In the statechart editor, first select the synchronization symbol, the use a handle in one of the symbol's corners to change length or orientation. The handles in the middle of the symbol have no effect. h3(#composite-state). Composite state A composite state is a state comprising one or more state machines. These state machines are also organized in regions within the composite state. Besides the simple composite state YAKINDU SCT knows about two kinds of composite states: orthogonal states and submachine states. Composite states contain other state machine branches. h3(#orthogonal-states). Orthogonal states In the context of state machines orthogonal states are states that are independent of each other. The presumably most famous example is the keyboard example: !(standard-image)images/docu_orthogonalState_example.jpg(Orthogonal states)! p=. Orthogonal states h3(#shallow-history). Shallow history The shallow history state is a pseudo state that is placed inside regions of composite states. It is used to remember the last active state inside a composite state. This makes it possible to jump back to the remembered state instead of starting at the inner initial state again. The following example, showing the answering of a questionaire, explains this: !(standard-image)images/docu_shallowHistory01.jpg(Shallow history [1])! p=. Shallow history [1] Particularly interesting in this statechart are the events @checkProgress@ and @goon@. The event @checkProgress@ jumps back to the @init@ state while assigning the current progress count to the variable @temp@. The event @goon@ jumps to the shallow history state that was placed inside the composite state. !(standard-image)images/docu_shallowHistory02.jpg(Shallow history [2])! p=. Shallow history [2] !(standard-image)images/docu_shallowHistory03.jpg(Shallow history [3])! p=. Shallow history [3] When the @goon@ event is triggered, the most recent active state inside of the composite state @answeringQuestions@ is activated again. h3(#deep-history). Deep history Deep history is similar to shallow history, but more complex. With a deep history the latest state of multiple nested states is remembered. h2(#types). Types The language has a small integrated type system consisting of the following simple types: * integer * real * boolean * string * void h3(#declaring-variables). Declaring variables Variables are typed. A variable is declared specifying its type: bc. var intVar : integer var realVar : real var boolVar : boolean var stringVar : string h3(#declaring-events). Declaring events Events are typed. An event is declared specifying its type: bc. event addInt : integer event addReal : real event checkValidity : boolean event stringEvent : string event voidEvent : void h2(#statements). Statements A statement is one of three kinds: * assignment * event raising * operation call h3(#assignments). Assignments The language has the following assignment operators:
simple assignment@=@
multiply and assign@*=@
divide and assign@/=@
calculate modulo and assign@%=@
add and assign@+=@
subtract and assign@-=@
bitshift left and assign@<<=@
bitshift right and assign@>>=@
bitwise AND and assign@&=@
bitwise XOR and assign@^=@
bitwise OR and assign@|=@
h3(#raising-an-event). Raising an event An event is raised by calling a method whose name consists of the word @raise@, immediately followed by the event name, e. g. @raiseIncoming_call()@. If the event is an interface event, the name of the interface must also be appended. ###. FIXME: Add an example! h3(#calling-an-operation). Calling an operation An operation is called similar to other programming languages with the operation name and passing concrete parameters. The parameters can be expressions. ###. FIXME: Add an example! h2(#expressions). Expressions Expressions in YAKINDU Statechart Tools are similar to expressions in other programming languages. The language provides operators for logical expressions, number arithmetic, bitwise arithmetic, and bit shifting. The type of a logical expression is *boolean*. h3(#LogicalAND). Logical AND bc. expr1 && expr2 h3(#LogicalOR). Logical OR bc. expr1 || expr2 h3(#LogicalNOT). Logical NOT bc. !expr1 h3(#Conditionalexpression). Conditional expression bc. expr1 ? expr2 : expr3 h3(#BitwiseXOR). Bitwise XOR bc. expr1 ^ expr2 h3(#BitwiseOR). Bitwise OR bc. expr1 | expr2 h3(#BitwiseAND). Bitwise AND bc. expr1 & expr2 h3(#LogicalRelationsandShiftOperators). Logical Relations and Shift Operators |<. less than|<. @<@| |<. equal or less than|<. @<=@| |<. greater than|<. @>@| |<. equal or greater than|<. @>=@| |<. equal|<. @==@| |<. not equal|<. @!=@| |<. shift left|<. @<<@| |<. shift right|<. @>>@| h3(#Binaryarithmeticoperators). Binary arithmetic operators |<. plus|<. @+@| |<. minus|<. @-@| |<. multiply|<. @*@| |<. divide|<. @/@| |<. modulo|<. @%@| h3(#Unaryarithmeticoperators). Unary arithmetic operators |<. positive|<. @+@| |<. negative|<. @-@| |<. complement|<. @~@| h2(#scopes). Scopes ==== h3(#Namespace). Namespace The language allows to define unique namespaces which can be used to qualify references to the statechart. bc. namespace trafficlights ==== ==== h3(#interfacescope). Interface scope Declarations in the interface scope are externally visible. They can be shared within the environment. bc. interface NamedInterface: in event event1 out event event3 : integer var variable1 : integer ==== ==== h3(#internal-scope). Internal scope Declarations made in an internal scope are visible to contained states only. bc. internal: var localVariable1: integer event localEvent: integer local event localEvent2 operation localOperation (int1 : integer, int2 : integer): integer localEvent2 / raise NamedInterface.event3 : localOperation(valueof(localEvent) , NamedInterface.variable1) ==== h2(#declarations). Declarations Within scopes, variables, constants, events, variables, operations, and local reactions can be declared. ==== h3(#variables). Variables Variables can have different visibilities. They can be visible for the environment: bc. var variable1: real Variables can be _readonly_ (constants): bc. var readonly pi: real = 3.1415 Variables can be referenced by the environment. bc. var external variable3: integer = 34 ==== ==== h3(#constants). Constants Variables can be immutable. For this special variable the keyword @const@ is used: bc. const variable1: real ==== ==== h3(#events). Events An _event_ is something of importance that happens at a certain point in time in the context of a state machine, for example a user pushes a button, a temperature sensor delivers a value, a period of time has passed, etc. An event is not necessarily something external; the state machine can raise events itself. h4(#incoming-and-outgoing-events). Incoming and outgoing events An event in an interface scope has a direction. It is either ingoing or outgoing: bc. interface NamedInterface: in event event1 out event event2 h4(#events-with-variables). Events with variables An event in the local scope can carry variables: bc. internal: event localEvent1 : integer A local event can have a value assignment: bc. internal: event localEvent1: integer = 25 Read access to the value of an event is possible in the statechart using the @valueof()@ built-in method. Please note that reading an event's value is possible only when the event actually occurs, for example in a guard: bc. localEvent1 [valueof(localEvent1) == 6] An event parameter can be specified when raising an event, as in the following example: bc. raise event1 : 3+3 p. ###. FIXME: Explain how and where an event can be raised! ==== ==== h3(#operations). Operations Operations can have none, one or multiple parameters. A parameter is declared with a name and a type. An operation may have a single return type similar to Java. bc. operation localOperation (xValue : integer, yValue : integer):integer ==== h3(#local-reactions). Local reactions Local reactions describe the internal behavior of a state. So they have internal scope. A local reaction is declared as follows: bc.. LocalReaction: ReactionTrigger '/' ReactionEffect ('#' ReactionProperties)? ReactionTrigger: (Event ("," Event )* (=> '[' Expression ']')?) | '[' Expression ']' ReactionEffect: Statement (';' Statement )* (';')? Statement: Assignment | EventRaising | OperationCall ReactionProperties: (EntryPoint | ExitPoint)* p. Within a local reaction an interface event can be raised: bc. internal: localEvent1 / raise NamedInterface.event3 : localOperation (valueof(localEvent), NamedInterface.variable1); A local reaction can have a priority value. The latter is defined by appending the character @#@ and the numeric priority value to the local reaction's definition. Examples: ###. FIXME: Describe the meaning of priorities! bc. localEvent2 / NamedInterface.variable2 += 3; #1 localEvent3 / NamedInterface.variable4 += 2.0; #2 h2(#reaction-triggers). Reaction triggers Actions are key constructs in state machines to model behavior. YAKINDU SCT knows about the following kinds of actions. ==== h3(#after). after The _after_ trigger specifies a one-shot time event. After the specified time the reaction is triggered. An _after_ trigger can be used in transitions of states as well as in local reactions of states and statecharts. The specified time starts when the state or statechart is entered. bc. after 20 s Synopsis: @after@ _time_ _unit_ The _time_ value is a integer literal or an expression with an integer value. The time _unit_ is one of: * ==== @s@: seconds ==== * ====@ms@: milliseconds ==== * ====@us@: microseconds ==== * ====@ns@: nanoseconds ==== ==== ==== h3(#every). every The _every_ trigger specifies periodic time events. The reaction is triggered recurrently after each passing of the specified period of time. An _every_ trigger can be used in transitions as well as in local reactions of states and statecharts. The specified period of time starts when the state or statechart is entered and repeats periodically. bc. every 200 ms Synopsis: @every@ _time_ _unit_ The _time_ value is a integer literal or an expression with an integer value. The time _unit_ is one of: * @s@: seconds * @ms@: milliseconds * @us@: microseconds * @ns@: nanoseconds ==== ==== h3(#always). always This trigger is always true and enables a reaction to be executed in every run-to-completion step (RTC). The _always_ trigger is equivalent to the _oncycle_ trigger. ==== ==== h3(#oncycle). oncycle This trigger is always true and enables a reaction to be executed in every run-to-completion step (RTC). The _always_ trigger is equivalent to the _oncycle_ trigger. ==== ==== h3(#else). else This trigger is intended to be used for the outgoing transitions of _choice_ pseudo states to make sure that there is always an outgoing transition that can be taken. It can only be be used in transitions and implies the lowest evaluation priority for that transition. The _default_ trigger is equivalent to the _else_ trigger. ==== ==== h3(#default). default This trigger is intended to be used for the outgoing transitions of _choice_ pseudo states to make sure that there is always an outgoing transition that can be taken. It can only be be used in transitions and implies the lowest evaluation priority for that transition. The _default_ trigger is equivalent to the _else_ trigger. ==== ==== h3(#entry-1). entry An _entry_ trigger marks actions that are carried out when entering a state or state machine. ==== ==== h3(#exit-1). exit An _exit_ trigger marks actions that are carried out when exiting a state or state machine. ==== h2(#built-in-functions). Built-in functions ==== h3(#valueofevent). valueof(event) An event can have a value. This function returns the value of the specified event. ###. FIXME: Specify what happens if the event does not have a value. bc. myVar = valueof(myEvent) ==== ==== h3(#as). as Casts a variable. The following example casts a literal from integer to real. bc. myReal = 12 as real ==== ==== h3(#activestate). active(state) Returns _true_ if the specified state is active and _false_ otherwise. bc. myBool = active(StateA) ==== h2(#complete-statechart-language-grammar). Complete statechart language grammar This section presents the complete grammar of the statechart language. If you are in doubt how to write down a transition specification, a variable declaration, or any other syntactical construct of the statechart language, this is your definite reference that clarifies all syntactical questions. The grammar is visualized using "railroad diagrams":https://en.wikipedia.org/wiki/Syntax_diagram. Railroad diagrams are easy to read and comprise all syntactically valid language constructs. Figure ""Railroad diagrams explained"":#fig-railroad-diagrams-explained shows an example: p(#fig-railroad-diagrams-explained). !(standard-image)images/docu_grammar_020_simpleelementreferenceexpression.png(Railroad diagrams explained)! p=. Railroad diagrams explained On the left-hand side you'll find the so-called "_non-terminal symbol_":https://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols (or _non-terminal_ for short) that is being defined by this particular diagram. Here the non-terminal is _SimpleElementReferenceExpression_. To find out what a _SimpleElementReferenceExpression_ is allowed to look like, follow the "railroad track" just like a train would do. At each junction, the train either keeps its direction or changes it by 45 degrees, but it cannot make sharp turns of 90 degrees or more. On its way, the train passes several "stations". Each station represents a language element that is valid at this point. In our example, the first station is a rectangle with a grey background. The grey background denotes a non-terminal, and the word inside the rectangle is the non-terminal's name, here: _ID_. You will have to look up this particular non-terminal's railroad diagram to learn more about it. However, for simplicity and because their meanings are more or less obvious a few non-terminals are not refined further. Examples are _STRING_, _INT_, _BOOL_, or _ID_. In a _SimpleElementReferenceExpression_, a valid ID – a name – is always the first element, e. g. @init42@. If the train turns right at the junction, it moves directly to the railroad diagram's exit. That means just an _ID_ like @init42@ is a valid _SimpleElementReferenceExpression_. Please note that when the train reaches the junction right before the exit, it cannot turn left, because trains don't move that way. That is, the train is unable to travel to the @(@ station from this direction. The train can reach the @)@ from the opposite direction only. After having left the initial _ID_ station, the train can move to the left at the junction and then run a stretch touching only the @(@ and @)@ stations, in that order. These rectangles have a white background color, denoting a "_terminal symbol_":https://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols or _terminal_ for short. A terminal stands for itself; write it down as it is. Following that rule, @init42()@ is a valid _SimpleElementReferenceExpression_. One or more _Expressions_ inside the paranthesis, separated by the @,@ terminal, are also valid. Example: @init42(foo, bar + 27)@. bq.. *Please note:* The railroad diagrams themselves are generated from a textual grammar representation established and maintained with "Xtext":https://eclipse.org/Xtext/. If you suspect the diagrams shown here are lagging behind the actual implementation, look for files with the @.xtext@ extension in the YAKINDU Statechart Tools source code distribution! bq.. *Please also note:* Not each and every construction that is syntactically allowed does make sense semantically. The statechart editor will flag such constructions as errors. h3(#statechart-grammar). Statechart grammar Figure ""Statechart grammar"":#fig-statechart-grammar shows the statechart grammar. It makes use of the "expressions grammar":#expressions-grammar. p(#fig-statechart-grammar). !(standard-image)images/docu_grammar_010_stext.png(Statechart grammar)! p=. Statechart grammar h3(#expressions-grammar). Expressions grammar Figure ""Expressions grammar"":#fig-expressions-grammar shows the expressions grammar. It is used by the "statechart grammar":#statechart-grammar. p(#fig-expressions-grammar). !(standard-image)images/docu_grammar_010_expressions.png(Expressions grammar)! p=. Expressions grammar