## 9 Statements

The first rule statement describes the various forms of a statement. The remaining rules implement the constraints that are sensitive to the context in which the statement occurs: single_statement for a context in which only one statement is allowed, and decl_statement for a context in which a declaration, statement, or sequence thereof is allowed.

stmt | ::= | directive
| | | metaidStmt
| | | expr;
| | | if (dot_expr) single_stmt [else single_stmt]
| | | for ([dot_expr]; [dot_expr]; [dot_expr]) single_stmt
| | | while (dot_expr) single_stmt
| | | do single_stmt while (dot_expr);
| | | iter_ident (dot_expr *) single_stmt
| | | switch ([dot_expr]) {case_line * }
| | | return [dot_expr];
| | | { [stmt_seq] }
| | | NEST(decl_stmt +, when)
| | | NEST(expr, when)
| | | break;
| | | continue;
| | | id:
| | | goto id;
| | | {stmt_seq }
directive | ::= | include
| | | #define id [top]
| | | #define id (PARAMSEQ(id, ε)) [top]
| | | #undef id
| | | #pragma id id +
| | | #pragma id ...
single_stmt | ::= | stmt
| | | OR(stmt)
| | | AND(stmt)
decl_stmt | ::= | metaidStmtList
| | | decl_var
| | | stmt
| | | expr
| | | OR(stmt_seq)
| | | AND(stmt_seq)
stmt_seq | ::= | decl_stmt * [DOTSEQ(decl_stmt +, when) decl_stmt *]
| | | decl_stmt * [DOTSEQ(expr, when) decl_stmt *]
case_line | ::= | default : stmt_seq
| | | case dot_expr : stmt_seq
iter_ident | ::= | IteratorId
| | | metaidIterator

OR(gram_o) | ::= | ( gram_o (|gram_o) *)
AND(gram_o) | ::= | ( gram_o (&gram_o) *)
DOTSEQ(gram_d, when_d) | ::= | …[when_d] (gram_d …[when_d]) *
NEST(gram_n, when_n) | ::= | <…[when_n] gram_n (…[when_n] gram_n) * …>
| | | <+…[when_n] gram_n (…[when_n] gram_n) * …+>

OR is a macro that generates a disjunction of patterns. The three tokens (, |, and ) must appear in the leftmost column, to differentiate them from the parentheses and bit-or tokens that can appear within expressions (and cannot appear in the leftmost column). These token may also be preceded by \ when they are used in an other column. These tokens are furthermore different from (, ∣, and ), which are part of the grammar metalanguage.

OR(stmt_seq) and AND(stmt_seq) must have something other than an expression in the first branch. If an expression appears there, they are parsed as their expr counterparts, i.e., all branches must be expressions.

All matching done by a SmPL rule is done intraprocedurally. Thus “…” does not extend from one function to the next one in the same file and it does not extend from one function over a function call into the called function.

#pragma C code can only be matched against when the entire pragma is on one line in the C code. The use of continuation lines, via a backslash, will cause the matching to fail.