A nest or a single ellipsis is allowed in some expression contexts, and causes ambiguity in others. For example, in a sequence …expr …, the nonterminal expr must be instantiated as an explicit C-language expression, while in an array reference, expr1 [ expr2 ], the nonterminal expr2, because it is delimited by brackets, can be also instantiated as …, representing an arbitrary expression. To distinguish between the various possibilities, we define three nonterminals for expressions: expr does not allow either top-level nests or ellipses, nest_expr allows a nest but not an ellipsis, and dot_expr allows both. The EXPR macro is used to express these variants in a concise way.
expr | ::= | EXPR(expr) |
nest_expr | ::= | EXPR(nest_expr) |
| | NEST(nest_expr, exp_whencode) | |
dot_expr | ::= | EXPR(dot_expr) |
| | NEST(dot_expr, exp_whencode) | |
| | ... [exp_whencode] | |
EXPR(exp) | ::= | exp assign_op exp |
| | exp++ | |
| | exp– | |
| | unary_op exp | |
| | exp bin_op exp | |
| | exp ? dot_expr : exp | |
| | (type) exp | |
| | exp [dot_expr] | |
| | exp . id | |
| | exp -> id | |
| | exp([PARAMSEQ(arg, exp_whencode)]) | |
| | id | |
| | metaidExp | |
| | metaidConst | |
| | const | |
| | (dot_expr) | |
| | OR(exp) | |
arg | ::= | nest_expr |
| | metaidExpList | |
exp_whencode | ::= | when != expr |
assign_op | ::= | = | -= | += | *= | /= | %= |
| | &= | |= | ^= | <<= | >>= | |
bin_op | ::= | * | / | % | + | - |
| | <<| >>| ^ | & | | | |
| | < | > | <= | >= | == | != | && | || | |
unary_op | ::= | ++ | – | & | * | + | - | ! |