| 1 |
/* |
|---|
| 2 |
Crown Copyright (c) 1997, 1998 |
|---|
| 3 |
|
|---|
| 4 |
This TenDRA(r) Computer Program is subject to Copyright |
|---|
| 5 |
owned by the United Kingdom Secretary of State for Defence |
|---|
| 6 |
acting through the Defence Evaluation and Research Agency |
|---|
| 7 |
(DERA). It is made available to Recipients with a |
|---|
| 8 |
royalty-free licence for its use, reproduction, transfer |
|---|
| 9 |
to other parties and amendment for any purpose not excluding |
|---|
| 10 |
product development provided that any such use et cetera |
|---|
| 11 |
shall be deemed to be acceptance of the following conditions:- |
|---|
| 12 |
|
|---|
| 13 |
(1) Its Recipients shall ensure that this Notice is |
|---|
| 14 |
reproduced upon any copies or amended versions of it; |
|---|
| 15 |
|
|---|
| 16 |
(2) Any amended version of it shall be clearly marked to |
|---|
| 17 |
show both the nature of and the organisation responsible |
|---|
| 18 |
for the relevant amendment or amendments; |
|---|
| 19 |
|
|---|
| 20 |
(3) Its onward transfer from a recipient to another |
|---|
| 21 |
party shall be deemed to be that party's acceptance of |
|---|
| 22 |
these conditions; |
|---|
| 23 |
|
|---|
| 24 |
(4) DERA gives no warranty or assurance as to its |
|---|
| 25 |
quality or suitability for any purpose and DERA accepts |
|---|
| 26 |
no liability whatsoever in relation to any use to which |
|---|
| 27 |
it may be put. |
|---|
| 28 |
*/ |
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
/* |
|---|
| 32 |
C SYNTAX |
|---|
| 33 |
|
|---|
| 34 |
This module contains the syntax for the C language. |
|---|
| 35 |
*/ |
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
/* |
|---|
| 39 |
TYPE DECLARATIONS |
|---|
| 40 |
|
|---|
| 41 |
The types BOOL, COUNT and LEX are natural types arising from the |
|---|
| 42 |
parser. The remaining types directly correspond to types within the |
|---|
| 43 |
main program, or composite types formed from them. |
|---|
| 44 |
*/ |
|---|
| 45 |
|
|---|
| 46 |
%types% |
|---|
| 47 |
|
|---|
| 48 |
BOOL ; |
|---|
| 49 |
BTYPE ; |
|---|
| 50 |
CONDITION ; |
|---|
| 51 |
COUNT ; |
|---|
| 52 |
CV ; |
|---|
| 53 |
DECL ; |
|---|
| 54 |
DSPEC ; |
|---|
| 55 |
EXP ; |
|---|
| 56 |
IDENTIFIER ; |
|---|
| 57 |
KEY ; |
|---|
| 58 |
LEX ; |
|---|
| 59 |
LIST-EXP ; |
|---|
| 60 |
NAMESPACE ; |
|---|
| 61 |
NUMBER ; |
|---|
| 62 |
OFFSET ; |
|---|
| 63 |
TYPE ; |
|---|
| 64 |
|
|---|
| 65 |
|
|---|
| 66 |
/* |
|---|
| 67 |
LIST OF TERMINALS |
|---|
| 68 |
|
|---|
| 69 |
This list of terminals corresponds to that given in symbols.h. It can |
|---|
| 70 |
be automatically generated using the routine sid_terminals defined in |
|---|
| 71 |
debug.c (q.v). |
|---|
| 72 |
*/ |
|---|
| 73 |
|
|---|
| 74 |
%terminals% |
|---|
| 75 |
|
|---|
| 76 |
!unknown ; |
|---|
| 77 |
|
|---|
| 78 |
/* Identifiers */ |
|---|
| 79 |
identifier : () -> ( :IDENTIFIER ) ; |
|---|
| 80 |
type-name : () -> ( :IDENTIFIER ) ; |
|---|
| 81 |
!namespace-name : () -> ( :IDENTIFIER ) ; |
|---|
| 82 |
statement-name : () -> ( :IDENTIFIER ) ; |
|---|
| 83 |
!destructor-name : () -> ( :IDENTIFIER ) ; |
|---|
| 84 |
!template-id : () -> ( :IDENTIFIER ) ; |
|---|
| 85 |
!template-type : () -> ( :IDENTIFIER ) ; |
|---|
| 86 |
|
|---|
| 87 |
/* Nested name specifiers */ |
|---|
| 88 |
!nested-name : () -> ( :NAMESPACE ) ; |
|---|
| 89 |
!full-name : () -> ( :NAMESPACE ) ; |
|---|
| 90 |
!nested-name-star : () -> ( :IDENTIFIER ) ; |
|---|
| 91 |
!full-name-star : () -> ( :IDENTIFIER ) ; |
|---|
| 92 |
|
|---|
| 93 |
/* Literals */ |
|---|
| 94 |
!char-lit ; !wchar-lit ; !string-lit ; !wstring-lit ; !integer-lit ; |
|---|
| 95 |
|
|---|
| 96 |
/* Literal expressions */ |
|---|
| 97 |
char-exp : () -> ( :EXP ) ; |
|---|
| 98 |
wchar-exp : () -> ( :EXP ) ; |
|---|
| 99 |
string-exp : () -> ( :EXP ) ; |
|---|
| 100 |
wstring-exp : () -> ( :EXP ) ; |
|---|
| 101 |
integer-exp : () -> ( :EXP ) ; |
|---|
| 102 |
floating-exp : () -> ( :EXP ) ; |
|---|
| 103 |
|
|---|
| 104 |
/* Token applications */ |
|---|
| 105 |
complex-exp : () -> ( :EXP ) ; |
|---|
| 106 |
complex-stmt : () -> ( :EXP ) ; |
|---|
| 107 |
complex-type : () -> ( :TYPE ) ; |
|---|
| 108 |
|
|---|
| 109 |
/* Target-dependent preprocessing directives */ |
|---|
| 110 |
hash-if : () -> ( :EXP ) ; |
|---|
| 111 |
hash-elif : () -> ( :EXP ) ; |
|---|
| 112 |
hash-else ; |
|---|
| 113 |
hash-endif ; |
|---|
| 114 |
hash-pragma ; |
|---|
| 115 |
|
|---|
| 116 |
/* End of file markers */ |
|---|
| 117 |
!newline ; eof ; |
|---|
| 118 |
|
|---|
| 119 |
/* Symbols */ |
|---|
| 120 |
and-1 ; and-eq-1 ; arrow ; assign ; !backslash ; close-brace-1 ; |
|---|
| 121 |
close-round ; close-square-1 ; colon ; comma ; compl-1 ; div ; div-eq ; |
|---|
| 122 |
dot ; ellipsis ; eq ; greater ; greater-eq ; !hash-1 ; !hash-hash-1 ; |
|---|
| 123 |
less ; less-eq ; logical-and-1 ; logical-or-1 ; lshift ; lshift-eq ; |
|---|
| 124 |
minus ; minus-eq ; minus-minus ; not-1 ; not-eq-1 ; open-brace-1 ; |
|---|
| 125 |
open-round ; open-square-1 ; or-1 ; or-eq-1 ; plus ; plus-eq ; plus-plus ; |
|---|
| 126 |
question ; rem ; rem-eq ; rshift ; rshift-eq ; semicolon ; star ; |
|---|
| 127 |
star-eq ; xor-1 ; xor-eq-1 ; !arrow-star ; !colon-colon ; !dot-star ; |
|---|
| 128 |
abs ; max ; min ; |
|---|
| 129 |
|
|---|
| 130 |
/* Digraphs */ |
|---|
| 131 |
!close-brace-2 ; !close-square-2 ; !hash-2 ; !hash-hash-2 ; |
|---|
| 132 |
!open-brace-2 ; !open-square-2 ; |
|---|
| 133 |
|
|---|
| 134 |
/* C keywords */ |
|---|
| 135 |
auto ; break ; case ; char ; const ; continue ; default ; do ; double ; |
|---|
| 136 |
else ; enum ; extern ; float ; for ; goto ; if ; int ; long ; register ; |
|---|
| 137 |
return ; short ; signed ; sizeof ; static ; struct ; switch ; typedef ; |
|---|
| 138 |
union ; unsigned ; void ; volatile ; while ; |
|---|
| 139 |
|
|---|
| 140 |
/* C++ keywords */ |
|---|
| 141 |
asm ; !bool ; !catch ; !class ; !const-cast ; !delete ; !dynamic-cast ; |
|---|
| 142 |
!explicit ; !export ; !false ; !friend ; inline ; !mutable ; !namespace ; |
|---|
| 143 |
!new ; !operator ; !private ; !protected ; !public ; !reinterpret-cast ; |
|---|
| 144 |
!static-cast ; !template ; !this ; !throw ; !true ; !try ; !typeid ; |
|---|
| 145 |
!typename ; !using ; !virtual ; wchar-t ; |
|---|
| 146 |
|
|---|
| 147 |
/* ISO keywords */ |
|---|
| 148 |
!and-2 ; !and-eq-2 ; !compl-2 ; !logical-and-2 ; !logical-or-2 ; |
|---|
| 149 |
!not-2 ; !not-eq-2 ; !or-2 ; !or-eq-2 ; !xor-2 ; !xor-eq-2 ; |
|---|
| 150 |
|
|---|
| 151 |
/* TenDRA keywords */ |
|---|
| 152 |
!accept ; !after ; alignof ; !all ; !allow ; !ambiguous ; !analysis ; |
|---|
| 153 |
!anonymous ; |
|---|
| 154 |
!argument ; !arith-cap ; !array ; !as ; !assert ; !assignment ; !begin ; |
|---|
| 155 |
!bitfield ; !block ; bottom ; !cast ; !character ; !class-cap ; !code ; |
|---|
| 156 |
!comment ; !compatible ; !complete ; !compute ; !conditional ; |
|---|
| 157 |
!conversion ; !decimal ; !decl ; !define ; !define-cap ; !defined ; |
|---|
| 158 |
!definition ; !depth ; !directive ; !directory ; !disallow ; discard ; |
|---|
| 159 |
!dollar ; !either ; !elif ; ellipsis-exp ; !end ; !endif ; !environment ; |
|---|
| 160 |
!equality ; !error ; !escape ; exhaustive ; !exp-cap ; !explain ; |
|---|
| 161 |
!extend ; !external ; !extra ; fall ; !file ; !float-cap ; !forward ; |
|---|
| 162 |
!func-cap ; !function ; !hexadecimal ; !hiding ; !ident ; !identif ; |
|---|
| 163 |
!ifdef ; !ifndef ; !ignore ; !implement ; !implicit ; !import ; !include ; |
|---|
| 164 |
!includes ; !include-next ; !incompatible ; !incomplete ; !indented ; |
|---|
| 165 |
!initialization ; !integer ; !interface ; !internal ; !into ; !int-cap ; |
|---|
| 166 |
!keyword ; !limit ; !line ; !linkage ; lit ; !longlong ; !lvalue ; |
|---|
| 167 |
!macro ; !main ; !member ; !member-cap ; !name ; !nat-cap ; !nested ; |
|---|
| 168 |
!nline ; !no ; !no-def ; !object ; !octal ; !of ; !off ; !on ; !option ; |
|---|
| 169 |
!overflow ; !overload ; !pointer ; !postpone ; !pragma ; !precedence ; |
|---|
| 170 |
!preserve ; !printf ; !proc-cap ; !promote ; !promoted ; !prototype ; |
|---|
| 171 |
ptrdiff-t ; !qualifier ; !quote ; reachable ; !reference ; !reject ; |
|---|
| 172 |
!representation ; !reset ; !resolution ; !rvalue ; !scalar-cap ; !scanf ; |
|---|
| 173 |
set ; size-t ; !size-t-2 ; !sort ; !std ; !stmt-cap ; !string ; |
|---|
| 174 |
!struct-cap ; !suspend ; !tag ; !tag-cap ; !tendra ; !text ; !this-name ; |
|---|
| 175 |
!token ; !type ; !type-cap ; !typeof ; !un-known ; !unassert ; !undef ; |
|---|
| 176 |
!unify ; !union-cap ; !unmatched ; !unpostpone ; unreachable ; unused ; |
|---|
| 177 |
!use ; !value ; !variable ; !variety-cap ; !volatile-t ; !vtable ; |
|---|
| 178 |
!warning ; weak ; !writeable ; !zzzz ; |
|---|
| 179 |
|
|---|
| 180 |
/* Miscellaneous symbols */ |
|---|
| 181 |
!array-op ; !builtin-file ; !builtin-line ; !close-template ; !cond-op ; |
|---|
| 182 |
!delete-full ; !delete-array ; !delete-array-full ; !func-op ; !hash-op ; |
|---|
| 183 |
!hash-hash-op ; inset-start ; inset-end ; !macro-arg ; !new-full ; |
|---|
| 184 |
!new-array ; !new-array-full ; !open-init ; !open-template ; !zzzzzz ; |
|---|
| 185 |
|
|---|
| 186 |
|
|---|
| 187 |
/* |
|---|
| 188 |
ALTERNATIVE REPRESENTATIONS |
|---|
| 189 |
|
|---|
| 190 |
The ISO keywords and digraphs will have been replaced by their primary |
|---|
| 191 |
representations by this stage. These rules are effectively identities |
|---|
| 192 |
for these alternatives. Don't try removing them - SID gets very |
|---|
| 193 |
confused. |
|---|
| 194 |
*/ |
|---|
| 195 |
|
|---|
| 196 |
%productions% |
|---|
| 197 |
|
|---|
| 198 |
close-brace = { close-brace-1 ; } ; |
|---|
| 199 |
close-square = { close-square-1 ; } ; |
|---|
| 200 |
open-brace = { open-brace-1 ; } ; |
|---|
| 201 |
open-square = { open-square-1 ; } ; |
|---|
| 202 |
|
|---|
| 203 |
and = { and-1 ; } ; |
|---|
| 204 |
and-eq = { and-eq-1 ; } ; |
|---|
| 205 |
compl = { compl-1 ; } ; |
|---|
| 206 |
logical-and = { logical-and-1 ; } ; |
|---|
| 207 |
logical-or = { logical-or-1 ; } ; |
|---|
| 208 |
not = { not-1 ; } ; |
|---|
| 209 |
not-eq = { not-eq-1 ; } ; |
|---|
| 210 |
or = { or-1 ; } ; |
|---|
| 211 |
or-eq = { or-eq-1 ; } ; |
|---|
| 212 |
xor = { xor-1 ; } ; |
|---|
| 213 |
xor-eq = { xor-eq-1 ; } ; |
|---|
| 214 |
|
|---|
| 215 |
|
|---|
| 216 |
/* |
|---|
| 217 |
LEXICAL TOKENS |
|---|
| 218 |
|
|---|
| 219 |
These actions give the lexical token numbers for various symbols. |
|---|
| 220 |
*/ |
|---|
| 221 |
|
|---|
| 222 |
<lex_crt> : () -> ( :LEX ) ; |
|---|
| 223 |
<lex_open_round> : () -> ( :LEX ) ; |
|---|
| 224 |
<lex_semicolon> : () -> ( :LEX ) ; |
|---|
| 225 |
<lex_alignof> : () -> ( :LEX ) ; |
|---|
| 226 |
<lex_sizeof> : () -> ( :LEX ) ; |
|---|
| 227 |
|
|---|
| 228 |
|
|---|
| 229 |
/* |
|---|
| 230 |
EXPECTED SYMBOLS |
|---|
| 231 |
|
|---|
| 232 |
These rules are used when a certain symbol is expected. If it is |
|---|
| 233 |
not present then the action expected is called with the appropriate |
|---|
| 234 |
lexical token number. |
|---|
| 235 |
*/ |
|---|
| 236 |
|
|---|
| 237 |
<expected> : ( :LEX ) -> () ; |
|---|
| 238 |
<error_fatal> : () -> () ; |
|---|
| 239 |
<error_syntax> : () -> () ; |
|---|
| 240 |
|
|---|
| 241 |
open-round-x = { |
|---|
| 242 |
open-round ; |
|---|
| 243 |
## t = <lex_open_round> ; <expected> ( t ) ; |
|---|
| 244 |
} ; |
|---|
| 245 |
|
|---|
| 246 |
semicolon-x = { |
|---|
| 247 |
semicolon ; |
|---|
| 248 |
## t = <lex_semicolon> ; <expected> ( t ) ; |
|---|
| 249 |
} ; |
|---|
| 250 |
|
|---|
| 251 |
|
|---|
| 252 |
/* |
|---|
| 253 |
IDENTIFIERS |
|---|
| 254 |
|
|---|
| 255 |
The identifier terminal is exclusive - it does not include those |
|---|
| 256 |
identifiers which are actually type and namespace names. This rule |
|---|
| 257 |
gives all identifiers and sets the appropriate identifier type. |
|---|
| 258 |
*/ |
|---|
| 259 |
|
|---|
| 260 |
<id_anon> : () -> ( :IDENTIFIER ) ; |
|---|
| 261 |
<id_none> : () -> ( :IDENTIFIER ) ; |
|---|
| 262 |
|
|---|
| 263 |
any-identifier : () -> ( id : IDENTIFIER ) = { |
|---|
| 264 |
id = identifier ; |
|---|
| 265 |
|| id = type-name ; |
|---|
| 266 |
|| id = statement-name ; |
|---|
| 267 |
} ; |
|---|
| 268 |
|
|---|
| 269 |
any-identifier-opt : () -> ( id : IDENTIFIER ) = { |
|---|
| 270 |
id = any-identifier ; |
|---|
| 271 |
|| id = <id_anon> ; |
|---|
| 272 |
} ; |
|---|
| 273 |
|
|---|
| 274 |
id-entry : () -> ( id : IDENTIFIER ) = { |
|---|
| 275 |
id = any-identifier ; |
|---|
| 276 |
## |
|---|
| 277 |
<error_syntax> ; |
|---|
| 278 |
id = <id_none> ; |
|---|
| 279 |
} ; |
|---|
| 280 |
|
|---|
| 281 |
operator-id : () -> ( id : IDENTIFIER ) = { |
|---|
| 282 |
<error_syntax> ; |
|---|
| 283 |
id = <id_none> ; |
|---|
| 284 |
} ; |
|---|
| 285 |
|
|---|
| 286 |
|
|---|
| 287 |
/* |
|---|
| 288 |
LITERAL EXPRESSIONS |
|---|
| 289 |
|
|---|
| 290 |
These rules describe the literal expressions. These are the integer |
|---|
| 291 |
and floating point literals and the character and string literals. |
|---|
| 292 |
Concatenation of adjacent string literals has already been performed. |
|---|
| 293 |
*/ |
|---|
| 294 |
|
|---|
| 295 |
integer-literal : () -> ( e : EXP ) = { |
|---|
| 296 |
e = integer-exp ; |
|---|
| 297 |
} ; |
|---|
| 298 |
|
|---|
| 299 |
character-literal : () -> ( e : EXP ) = { |
|---|
| 300 |
e = char-exp ; |
|---|
| 301 |
|| e = wchar-exp ; |
|---|
| 302 |
} ; |
|---|
| 303 |
|
|---|
| 304 |
floating-literal : () -> ( e : EXP ) = { |
|---|
| 305 |
e = floating-exp ; |
|---|
| 306 |
} ; |
|---|
| 307 |
|
|---|
| 308 |
string-literal : () -> ( e : EXP ) = { |
|---|
| 309 |
e = string-exp ; |
|---|
| 310 |
|| e = wstring-exp ; |
|---|
| 311 |
} ; |
|---|
| 312 |
|
|---|
| 313 |
literal : () -> ( e : EXP ) = { |
|---|
| 314 |
e = integer-literal ; |
|---|
| 315 |
|| e = character-literal ; |
|---|
| 316 |
|| e = floating-literal ; |
|---|
| 317 |
|| e = string-literal ; |
|---|
| 318 |
} ; |
|---|
| 319 |
|
|---|
| 320 |
|
|---|
| 321 |
/* |
|---|
| 322 |
PRIMARY EXPRESSIONS |
|---|
| 323 |
|
|---|
| 324 |
This rule describes the primary expressions. These include the |
|---|
| 325 |
literals, the identity expressions, the this expression and the |
|---|
| 326 |
parenthesised expressions. The assertion expressions are an |
|---|
| 327 |
extension. |
|---|
| 328 |
*/ |
|---|
| 329 |
|
|---|
| 330 |
<exp_ellipsis> : () -> ( :EXP ) ; |
|---|
| 331 |
<exp_paren_begin> : () -> () ; |
|---|
| 332 |
<exp_paren_end> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 333 |
<exp_identifier> : ( :IDENTIFIER ) -> ( :EXP ) ; |
|---|
| 334 |
|
|---|
| 335 |
expression : () -> ( :EXP ) ; |
|---|
| 336 |
|
|---|
| 337 |
primary-expression : () -> ( e : EXP ) = { |
|---|
| 338 |
e = literal ; |
|---|
| 339 |
|| |
|---|
| 340 |
id = identifier ; |
|---|
| 341 |
e = <exp_identifier> ( id ) ; |
|---|
| 342 |
|| |
|---|
| 343 |
ellipsis-exp ; |
|---|
| 344 |
e = <exp_ellipsis> ; |
|---|
| 345 |
|| |
|---|
| 346 |
open-round ; |
|---|
| 347 |
<exp_paren_begin> ; |
|---|
| 348 |
a = expression ; |
|---|
| 349 |
e = <exp_paren_end> ( a ) ; |
|---|
| 350 |
close-round ; |
|---|
| 351 |
|| |
|---|
| 352 |
e = complex-exp ; |
|---|
| 353 |
} ; |
|---|
| 354 |
|
|---|
| 355 |
|
|---|
| 356 |
/* |
|---|
| 357 |
EXPRESSION LISTS |
|---|
| 358 |
|
|---|
| 359 |
These rules describes the lists of expressions. Note that the |
|---|
| 360 |
constituents are assignment-expressions so that any commas are list |
|---|
| 361 |
separators rather than comma operators. |
|---|
| 362 |
*/ |
|---|
| 363 |
|
|---|
| 364 |
<list_exp_null> : () -> ( :LIST-EXP ) ; |
|---|
| 365 |
<list_exp_cons> : ( :EXP, :LIST-EXP ) -> ( :LIST-EXP ) ; |
|---|
| 366 |
|
|---|
| 367 |
assignment-expression : () -> ( :EXP ) ; |
|---|
| 368 |
|
|---|
| 369 |
expression-list : () -> ( p : LIST-EXP ) = { |
|---|
| 370 |
e = assignment-expression ; |
|---|
| 371 |
{ |
|---|
| 372 |
comma ; q = expression-list ; |
|---|
| 373 |
|| q = <list_exp_null> ; |
|---|
| 374 |
} ; |
|---|
| 375 |
p = <list_exp_cons> ( e, q ) ; |
|---|
| 376 |
} ; |
|---|
| 377 |
|
|---|
| 378 |
expression-list-opt : () -> ( p : LIST-EXP ) = { |
|---|
| 379 |
p = expression-list ; |
|---|
| 380 |
|| p = <list_exp_null> ; |
|---|
| 381 |
} ; |
|---|
| 382 |
|
|---|
| 383 |
|
|---|
| 384 |
/* |
|---|
| 385 |
FIELD SELECTOR EXPRESSIONS |
|---|
| 386 |
|
|---|
| 387 |
These rules are used to perform field selector look-up following a |
|---|
| 388 |
'.' or '->' operator. The input namespace gives the class being |
|---|
| 389 |
selected from (or the null namespace in case of an error). Note |
|---|
| 390 |
the provisions for dummy destructor calls. |
|---|
| 391 |
*/ |
|---|
| 392 |
|
|---|
| 393 |
<rescan_member> : ( :NAMESPACE, :IDENTIFIER ) -> ( :IDENTIFIER ) ; |
|---|
| 394 |
|
|---|
| 395 |
field-id-expression : ( ns : NAMESPACE ) -> ( id : IDENTIFIER ) = { |
|---|
| 396 |
uid = any-identifier ; |
|---|
| 397 |
id = <rescan_member> ( ns, uid ) ; |
|---|
| 398 |
} ; |
|---|
| 399 |
|
|---|
| 400 |
|
|---|
| 401 |
/* |
|---|
| 402 |
POSTFIX EXPRESSIONS |
|---|
| 403 |
|
|---|
| 404 |
These rules describes the postfix expressions. These include array |
|---|
| 405 |
indexing, function calls and function style casts, field selectors, |
|---|
| 406 |
postfix increment and decrement operations, new style casts and |
|---|
| 407 |
type identification operators. |
|---|
| 408 |
*/ |
|---|
| 409 |
|
|---|
| 410 |
<exp_postinc> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 411 |
<exp_postdec> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 412 |
<exp_index> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 413 |
<exp_func> : ( :EXP, :LIST-EXP ) -> ( :EXP ) ; |
|---|
| 414 |
|
|---|
| 415 |
<exp_dot_begin> : ( :EXP ) -> ( :EXP, :TYPE, :NAMESPACE ) ; |
|---|
| 416 |
<exp_dot_end> : ( :EXP, :TYPE, :NAMESPACE, :IDENTIFIER ) -> ( :EXP ) ; |
|---|
| 417 |
<exp_arrow_begin> : ( :EXP ) -> ( :EXP, :TYPE, :NAMESPACE ) ; |
|---|
| 418 |
<exp_arrow_end> : ( :EXP, :TYPE, :NAMESPACE, :IDENTIFIER ) -> ( :EXP ) ; |
|---|
| 419 |
<rescan_token> : () -> () ; |
|---|
| 420 |
|
|---|
| 421 |
<no_type_defns> : () -> ( :COUNT ) ; |
|---|
| 422 |
<no_side_effects> : () -> ( :COUNT ) ; |
|---|
| 423 |
<diff_type_defns> : ( :COUNT ) -> ( :COUNT ) ; |
|---|
| 424 |
<diff_side_effects> : ( :COUNT ) -> ( :COUNT ) ; |
|---|
| 425 |
<sizeof_begin> : () -> () ; |
|---|
| 426 |
<sizeof_end> : () -> () ; |
|---|
| 427 |
|
|---|
| 428 |
type-id : () -> ( :TYPE, :COUNT ) ; |
|---|
| 429 |
type-id-false : () -> ( :TYPE, :COUNT ) ; |
|---|
| 430 |
type-id-true : () -> ( :TYPE, :COUNT ) ; |
|---|
| 431 |
|
|---|
| 432 |
postfix-expression : () -> ( e : EXP ) = { |
|---|
| 433 |
e = primary-expression ; |
|---|
| 434 |
|| |
|---|
| 435 |
a = postfix-expression ; |
|---|
| 436 |
open-square ; b = expression ; close-square ; |
|---|
| 437 |
e = <exp_index> ( a, b ) ; |
|---|
| 438 |
|| |
|---|
| 439 |
a = postfix-expression ; |
|---|
| 440 |
open-round ; p = expression-list-opt ; |
|---|
| 441 |
e = <exp_func> ( a, p ) ; |
|---|
| 442 |
close-round ; |
|---|
| 443 |
|| |
|---|
| 444 |
a = postfix-expression ; |
|---|
| 445 |
( b, t, ns ) = <exp_dot_begin> ( a ) ; |
|---|
| 446 |
dot ; id = field-id-expression ( ns ) ; |
|---|
| 447 |
e = <exp_dot_end> ( b, t, ns, id ) ; |
|---|
| 448 |
<rescan_token> ; |
|---|
| 449 |
|| |
|---|
| 450 |
a = postfix-expression ; |
|---|
| 451 |
( b, t, ns ) = <exp_arrow_begin> ( a ) ; |
|---|
| 452 |
arrow ; id = field-id-expression ( ns ) ; |
|---|
| 453 |
e = <exp_arrow_end> ( b, t, ns, id ) ; |
|---|
| 454 |
<rescan_token> ; |
|---|
| 455 |
|| |
|---|
| 456 |
a = postfix-expression ; plus-plus ; |
|---|
| 457 |
e = <exp_postinc> ( a ) ; |
|---|
| 458 |
|| |
|---|
| 459 |
a = postfix-expression ; minus-minus ; |
|---|
| 460 |
e = <exp_postdec> ( a ) ; |
|---|
| 461 |
} ; |
|---|
| 462 |
|
|---|
| 463 |
|
|---|
| 464 |
/* |
|---|
| 465 |
UNARY EXPRESSIONS |
|---|
| 466 |
|
|---|
| 467 |
These rules describe the unary expressions. These include the simple |
|---|
| 468 |
unary operations (indirection, address, unary plus, unary minus, logical |
|---|
| 469 |
negation and bitwise complement), the prefix increment and decrement |
|---|
| 470 |
operations and sizeof expressions, as well as the new and delete |
|---|
| 471 |
expressions. |
|---|
| 472 |
*/ |
|---|
| 473 |
|
|---|
| 474 |
<exp_not> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 475 |
<exp_ref> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 476 |
<exp_indir> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 477 |
<exp_unary> : ( :LEX, :EXP ) -> ( :EXP ) ; |
|---|
| 478 |
<exp_preinc> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 479 |
<exp_predec> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 480 |
|
|---|
| 481 |
<exp_none> : () -> ( :EXP ) ; |
|---|
| 482 |
<exp_sizeof> : ( :LEX, :TYPE, :EXP, :COUNT ) -> ( :EXP ) ; |
|---|
| 483 |
<type_of> : ( :LEX, :EXP, :COUNT ) -> ( :TYPE ) ; |
|---|
| 484 |
|
|---|
| 485 |
unary-expression : () -> ( :EXP ) ; |
|---|
| 486 |
cast-expression : () -> ( :EXP ) ; |
|---|
| 487 |
|
|---|
| 488 |
sizeof-expression : ( op : LEX ) -> ( e : EXP ) = { |
|---|
| 489 |
<sizeof_begin> ; |
|---|
| 490 |
n1 = <no_side_effects> ; |
|---|
| 491 |
m1 = <no_type_defns> ; |
|---|
| 492 |
{ |
|---|
| 493 |
a = unary-expression ; |
|---|
| 494 |
n2 = <diff_side_effects> ( n1 ) ; |
|---|
| 495 |
m2 = <diff_type_defns> ( m1 ) ; |
|---|
| 496 |
t = <type_of> ( op, a, n2 ) ; |
|---|
| 497 |
c = <exp_sizeof> ( op, t, a, m2 ) ; |
|---|
| 498 |
|| |
|---|
| 499 |
open-round ; ( t, m2 ) = type-id-true ; |
|---|
| 500 |
a = <exp_none> ; |
|---|
| 501 |
c = <exp_sizeof> ( op, t, a, m2 ) ; |
|---|
| 502 |
close-round ; |
|---|
| 503 |
} ; |
|---|
| 504 |
<sizeof_end> ; |
|---|
| 505 |
e = c ; |
|---|
| 506 |
} ; |
|---|
| 507 |
|
|---|
| 508 |
unary-operator : () -> () = { |
|---|
| 509 |
plus ; |
|---|
| 510 |
|| minus ; |
|---|
| 511 |
|| compl ; |
|---|
| 512 |
|| abs ; |
|---|
| 513 |
} ; |
|---|
| 514 |
|
|---|
| 515 |
unary-expression : () -> ( e : EXP ) = { |
|---|
| 516 |
e = postfix-expression ; |
|---|
| 517 |
|| |
|---|
| 518 |
plus-plus ; a = unary-expression ; |
|---|
| 519 |
e = <exp_preinc> ( a ) ; |
|---|
| 520 |
|| |
|---|
| 521 |
minus-minus ; a = unary-expression ; |
|---|
| 522 |
e = <exp_predec> ( a ) ; |
|---|
| 523 |
|| |
|---|
| 524 |
star ; a = cast-expression ; |
|---|
| 525 |
e = <exp_indir> ( a ) ; |
|---|
| 526 |
|| |
|---|
| 527 |
and ; a = cast-expression ; |
|---|
| 528 |
e = <exp_ref> ( a ) ; |
|---|
| 529 |
|| |
|---|
| 530 |
not ; a = cast-expression ; |
|---|
| 531 |
e = <exp_not> ( a ) ; |
|---|
| 532 |
|| |
|---|
| 533 |
op = <lex_crt> ; unary-operator ; |
|---|
| 534 |
a = cast-expression ; |
|---|
| 535 |
e = <exp_unary> ( op, a ) ; |
|---|
| 536 |
|| |
|---|
| 537 |
sizeof ; op = <lex_sizeof> ; e = sizeof-expression ( op ) ; |
|---|
| 538 |
|| |
|---|
| 539 |
alignof ; op = <lex_alignof> ; e = sizeof-expression ( op ) ; |
|---|
| 540 |
} ; |
|---|
| 541 |
|
|---|
| 542 |
|
|---|
| 543 |
/* |
|---|
| 544 |
CAST EXPRESSIONS |
|---|
| 545 |
|
|---|
| 546 |
This rule describes the traditional style cast expressions, consisting |
|---|
| 547 |
of a bracketed type identifier followed by an expression. The ignore |
|---|
| 548 |
keyword is an extension which is semantically equivalent to casting |
|---|
| 549 |
to void. |
|---|
| 550 |
*/ |
|---|
| 551 |
|
|---|
| 552 |
<exp_cast> : ( :TYPE, :EXP, :COUNT ) -> ( :EXP ) ; |
|---|
| 553 |
<exp_lit> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 554 |
<exp_ignore> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 555 |
|
|---|
| 556 |
cast-expression : () -> ( e : EXP ) = { |
|---|
| 557 |
e = unary-expression ; |
|---|
| 558 |
|| |
|---|
| 559 |
lit ; a = cast-expression ; |
|---|
| 560 |
e = <exp_lit> ( a ); |
|---|
| 561 |
|| |
|---|
| 562 |
open-round ; ( t, n ) = type-id-false ; close-round ; |
|---|
| 563 |
a = cast-expression ; |
|---|
| 564 |
e = <exp_cast> ( t, a, n ) ; |
|---|
| 565 |
|| |
|---|
| 566 |
discard ; a = cast-expression ; |
|---|
| 567 |
e = <exp_ignore> ( a ) ; |
|---|
| 568 |
} ; |
|---|
| 569 |
|
|---|
| 570 |
|
|---|
| 571 |
/* |
|---|
| 572 |
MULTIPLICATIVE EXPRESSIONS |
|---|
| 573 |
|
|---|
| 574 |
This rule describes the multiplicative expressions. These include |
|---|
| 575 |
the division and remainder operations, as well as multiplication. |
|---|
| 576 |
*/ |
|---|
| 577 |
|
|---|
| 578 |
<exp_div> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 579 |
<exp_rem> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 580 |
<exp_mult> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 581 |
|
|---|
| 582 |
multiplicative-expression : () -> ( e : EXP ) = { |
|---|
| 583 |
e = cast-expression ; |
|---|
| 584 |
|| |
|---|
| 585 |
a = multiplicative-expression ; star ; b = cast-expression ; |
|---|
| 586 |
e = <exp_mult> ( a, b ) ; |
|---|
| 587 |
|| |
|---|
| 588 |
a = multiplicative-expression ; div ; b = cast-expression ; |
|---|
| 589 |
e = <exp_div> ( a, b ) ; |
|---|
| 590 |
|| |
|---|
| 591 |
a = multiplicative-expression ; rem ; b = cast-expression ; |
|---|
| 592 |
e = <exp_rem> ( a, b ) ; |
|---|
| 593 |
} ; |
|---|
| 594 |
|
|---|
| 595 |
|
|---|
| 596 |
/* |
|---|
| 597 |
ADDITIVE EXPRESSIONS |
|---|
| 598 |
|
|---|
| 599 |
This rule describes the additive expressions. These include both the |
|---|
| 600 |
addition and the subtraction operations. |
|---|
| 601 |
*/ |
|---|
| 602 |
|
|---|
| 603 |
<exp_plus> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 604 |
<exp_minus> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 605 |
|
|---|
| 606 |
additive-expression : () -> ( e : EXP ) = { |
|---|
| 607 |
e = multiplicative-expression ; |
|---|
| 608 |
|| |
|---|
| 609 |
a = additive-expression ; plus ; b = multiplicative-expression ; |
|---|
| 610 |
e = <exp_plus> ( a, b ) ; |
|---|
| 611 |
|| |
|---|
| 612 |
a = additive-expression ; minus ; b = multiplicative-expression ; |
|---|
| 613 |
e = <exp_minus> ( a, b ) ; |
|---|
| 614 |
} ; |
|---|
| 615 |
|
|---|
| 616 |
|
|---|
| 617 |
/* |
|---|
| 618 |
SHIFT EXPRESSIONS |
|---|
| 619 |
|
|---|
| 620 |
This rule describes the shift expressions. Both left and right shifts |
|---|
| 621 |
are included. |
|---|
| 622 |
*/ |
|---|
| 623 |
|
|---|
| 624 |
<exp_lshift> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 625 |
<exp_rshift> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 626 |
|
|---|
| 627 |
shift-expression : () -> ( e : EXP ) = { |
|---|
| 628 |
e = additive-expression ; |
|---|
| 629 |
|| |
|---|
| 630 |
a = shift-expression ; lshift ; b = additive-expression ; |
|---|
| 631 |
e = <exp_lshift> ( a, b ) ; |
|---|
| 632 |
|| |
|---|
| 633 |
a = shift-expression ; rshift ; b = additive-expression ; |
|---|
| 634 |
e = <exp_rshift> ( a, b ) ; |
|---|
| 635 |
} ; |
|---|
| 636 |
|
|---|
| 637 |
|
|---|
| 638 |
/* |
|---|
| 639 |
RELATIONAL EXPRESSIONS |
|---|
| 640 |
|
|---|
| 641 |
These rules describe the relational expressions, less than, greater |
|---|
| 642 |
than, less than or equal and greater than or equal. |
|---|
| 643 |
*/ |
|---|
| 644 |
|
|---|
| 645 |
<exp_relation> : ( :LEX, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 646 |
|
|---|
| 647 |
relational-operator : () -> () = { |
|---|
| 648 |
less ; |
|---|
| 649 |
|| greater ; |
|---|
| 650 |
|| less-eq ; |
|---|
| 651 |
|| greater-eq ; |
|---|
| 652 |
} ; |
|---|
| 653 |
|
|---|
| 654 |
relational-expression : () -> ( e : EXP ) = { |
|---|
| 655 |
e = shift-expression ; |
|---|
| 656 |
|| |
|---|
| 657 |
a = relational-expression ; |
|---|
| 658 |
op = <lex_crt> ; relational-operator ; |
|---|
| 659 |
b = shift-expression ; |
|---|
| 660 |
e = <exp_relation> ( op, a, b ) ; |
|---|
| 661 |
} ; |
|---|
| 662 |
|
|---|
| 663 |
|
|---|
| 664 |
/* |
|---|
| 665 |
EQUALITY EXPRESSIONS |
|---|
| 666 |
|
|---|
| 667 |
These rules describe the equality expressions, equal and not equal. |
|---|
| 668 |
*/ |
|---|
| 669 |
|
|---|
| 670 |
<exp_equality> : ( :LEX, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 671 |
|
|---|
| 672 |
equality-operator : () -> () = { |
|---|
| 673 |
eq ; |
|---|
| 674 |
|| not-eq ; |
|---|
| 675 |
} ; |
|---|
| 676 |
|
|---|
| 677 |
equality-expression : () -> ( e : EXP ) = { |
|---|
| 678 |
e = relational-expression ; |
|---|
| 679 |
|| |
|---|
| 680 |
a = equality-expression ; |
|---|
| 681 |
op = <lex_crt> ; equality-operator ; |
|---|
| 682 |
b = relational-expression ; |
|---|
| 683 |
e = <exp_equality> ( op, a, b ) ; |
|---|
| 684 |
} ; |
|---|
| 685 |
|
|---|
| 686 |
|
|---|
| 687 |
/* |
|---|
| 688 |
MAXIMUM AND MINIMUM EXPRESSIONS (EXTENSION) |
|---|
| 689 |
|
|---|
| 690 |
These rules describes the maximum and minimum expressions. |
|---|
| 691 |
*/ |
|---|
| 692 |
|
|---|
| 693 |
<exp_maxmin> : ( :LEX, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 694 |
|
|---|
| 695 |
maxmin-operator : () -> () = { |
|---|
| 696 |
max ; |
|---|
| 697 |
|| min ; |
|---|
| 698 |
} ; |
|---|
| 699 |
|
|---|
| 700 |
maxmin-expression : () -> ( e : EXP ) = { |
|---|
| 701 |
e = equality-expression ; |
|---|
| 702 |
|| |
|---|
| 703 |
a = maxmin-expression ; |
|---|
| 704 |
op = <lex_crt> ; maxmin-operator ; |
|---|
| 705 |
b = equality-expression ; |
|---|
| 706 |
e = <exp_maxmin> ( op, a, b ) ; |
|---|
| 707 |
} ; |
|---|
| 708 |
|
|---|
| 709 |
|
|---|
| 710 |
/* |
|---|
| 711 |
AND EXPRESSIONS |
|---|
| 712 |
|
|---|
| 713 |
This rule describes the bitwise and expressions. |
|---|
| 714 |
*/ |
|---|
| 715 |
|
|---|
| 716 |
<exp_and> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 717 |
|
|---|
| 718 |
and-expression : () -> ( e : EXP ) = { |
|---|
| 719 |
e = maxmin-expression ; |
|---|
| 720 |
|| |
|---|
| 721 |
a = and-expression ; and ; b = maxmin-expression ; |
|---|
| 722 |
e = <exp_and> ( a, b ) ; |
|---|
| 723 |
} ; |
|---|
| 724 |
|
|---|
| 725 |
|
|---|
| 726 |
/* |
|---|
| 727 |
EXCLUSIVE OR EXPRESSIONS |
|---|
| 728 |
|
|---|
| 729 |
This rule describes the bitwise exclusive or expressions. |
|---|
| 730 |
*/ |
|---|
| 731 |
|
|---|
| 732 |
<exp_xor> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 733 |
|
|---|
| 734 |
exclusive-or-expression : () -> ( e : EXP ) = { |
|---|
| 735 |
e = and-expression ; |
|---|
| 736 |
|| |
|---|
| 737 |
a = exclusive-or-expression ; xor ; b = and-expression ; |
|---|
| 738 |
e = <exp_xor> ( a, b ) ; |
|---|
| 739 |
} ; |
|---|
| 740 |
|
|---|
| 741 |
|
|---|
| 742 |
/* |
|---|
| 743 |
INCLUSIVE OR EXPRESSIONS |
|---|
| 744 |
|
|---|
| 745 |
This rule describes the bitwise inclusive or expressions. |
|---|
| 746 |
*/ |
|---|
| 747 |
|
|---|
| 748 |
<exp_or> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 749 |
|
|---|
| 750 |
inclusive-or-expression : () -> ( e : EXP ) = { |
|---|
| 751 |
e = exclusive-or-expression ; |
|---|
| 752 |
|| |
|---|
| 753 |
a = inclusive-or-expression ; or ; b = exclusive-or-expression ; |
|---|
| 754 |
e = <exp_or> ( a, b ) ; |
|---|
| 755 |
} ; |
|---|
| 756 |
|
|---|
| 757 |
|
|---|
| 758 |
/* |
|---|
| 759 |
LOGICAL AND EXPRESSIONS |
|---|
| 760 |
|
|---|
| 761 |
This rule describes the logical and expressions. |
|---|
| 762 |
*/ |
|---|
| 763 |
|
|---|
| 764 |
<exp_log_and> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 765 |
|
|---|
| 766 |
logical-and-expression : () -> ( e : EXP ) = { |
|---|
| 767 |
e = inclusive-or-expression ; |
|---|
| 768 |
|| |
|---|
| 769 |
a = logical-and-expression ; |
|---|
| 770 |
logical-and ; b = inclusive-or-expression ; |
|---|
| 771 |
e = <exp_log_and> ( a, b ) ; |
|---|
| 772 |
} ; |
|---|
| 773 |
|
|---|
| 774 |
|
|---|
| 775 |
/* |
|---|
| 776 |
LOGICAL OR EXPRESSIONS |
|---|
| 777 |
|
|---|
| 778 |
This rule describes the logical or expressions. |
|---|
| 779 |
*/ |
|---|
| 780 |
|
|---|
| 781 |
<exp_log_or> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 782 |
|
|---|
| 783 |
logical-or-expression : () -> ( e : EXP ) = { |
|---|
| 784 |
e = logical-and-expression ; |
|---|
| 785 |
|| |
|---|
| 786 |
a = logical-or-expression ; |
|---|
| 787 |
logical-or ; b = logical-and-expression ; |
|---|
| 788 |
e = <exp_log_or> ( a, b ) ; |
|---|
| 789 |
} ; |
|---|
| 790 |
|
|---|
| 791 |
|
|---|
| 792 |
/* |
|---|
| 793 |
CONDITIONAL EXPRESSIONS |
|---|
| 794 |
|
|---|
| 795 |
This rule describes the conditional expressions, consisting of the |
|---|
| 796 |
'?:' operator. |
|---|
| 797 |
*/ |
|---|
| 798 |
|
|---|
| 799 |
<exp_cond> : ( :EXP, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 800 |
|
|---|
| 801 |
conditional-expression : () -> ( e : EXP ) = { |
|---|
| 802 |
e = logical-or-expression ; |
|---|
| 803 |
|| |
|---|
| 804 |
c = logical-or-expression ; |
|---|
| 805 |
question ; a = expression ; |
|---|
| 806 |
colon ; b = conditional-expression ; |
|---|
| 807 |
e = <exp_cond> ( c, a, b ) ; |
|---|
| 808 |
} ; |
|---|
| 809 |
|
|---|
| 810 |
|
|---|
| 811 |
/* |
|---|
| 812 |
ASSIGNMENT EXPRESSIONS |
|---|
| 813 |
|
|---|
| 814 |
These rules describe the assignment expressions. These include both |
|---|
| 815 |
simple assignment and the 'operate and becomes' operators like '+='. |
|---|
| 816 |
*/ |
|---|
| 817 |
|
|---|
| 818 |
<exp_assign> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 819 |
<exp_assign_op> : ( :LEX, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 820 |
|
|---|
| 821 |
assignment-operator : () -> () = { |
|---|
| 822 |
and-eq ; |
|---|
| 823 |
|| div-eq ; |
|---|
| 824 |
|| lshift-eq ; |
|---|
| 825 |
|| minus-eq ; |
|---|
| 826 |
|| or-eq ; |
|---|
| 827 |
|| plus-eq ; |
|---|
| 828 |
|| rem-eq ; |
|---|
| 829 |
|| rshift-eq ; |
|---|
| 830 |
|| star-eq ; |
|---|
| 831 |
|| xor-eq ; |
|---|
| 832 |
} ; |
|---|
| 833 |
|
|---|
| 834 |
assignment-expression : () -> ( e : EXP ) = { |
|---|
| 835 |
e = conditional-expression ; |
|---|
| 836 |
|| |
|---|
| 837 |
a = unary-expression ; |
|---|
| 838 |
assign ; b = assignment-expression ; |
|---|
| 839 |
e = <exp_assign> ( a, b ) ; |
|---|
| 840 |
|| |
|---|
| 841 |
a = unary-expression ; |
|---|
| 842 |
op = <lex_crt> ; assignment-operator ; |
|---|
| 843 |
b = assignment-expression ; |
|---|
| 844 |
e = <exp_assign_op> ( op, a, b ) ; |
|---|
| 845 |
} ; |
|---|
| 846 |
|
|---|
| 847 |
expression-entry : () -> ( e : EXP ) = { |
|---|
| 848 |
e = assignment-expression ; |
|---|
| 849 |
## |
|---|
| 850 |
<error_syntax> ; |
|---|
| 851 |
e = <exp_none> ; |
|---|
| 852 |
} ; |
|---|
| 853 |
|
|---|
| 854 |
|
|---|
| 855 |
/* |
|---|
| 856 |
FLOW ANALYSIS EXPRESSIONS (EXTENSION) |
|---|
| 857 |
|
|---|
| 858 |
This rule describes the flow analysis expressions, which are an |
|---|
| 859 |
extension to the standard syntax. These consist of the assignment |
|---|
| 860 |
expressions, plus operations for setting and discarding values. |
|---|
| 861 |
*/ |
|---|
| 862 |
|
|---|
| 863 |
<exp_set> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 864 |
<exp_unused> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 865 |
|
|---|
| 866 |
flow-expression : () -> ( e : EXP ) = { |
|---|
| 867 |
set ; open-round ; a = expression ; |
|---|
| 868 |
e = <exp_set> ( a ) ; |
|---|
| 869 |
close-round ; |
|---|
| 870 |
|| |
|---|
| 871 |
unused ; open-round ; a = expression ; |
|---|
| 872 |
e = <exp_unused> ( a ) ; |
|---|
| 873 |
close-round ; |
|---|
| 874 |
} ; |
|---|
| 875 |
|
|---|
| 876 |
inset-flow-expression : () -> ( e : EXP ) = { |
|---|
| 877 |
inset-start ; set ; a = expression ; |
|---|
| 878 |
e = <exp_set> ( a ) ; |
|---|
| 879 |
inset-end ; |
|---|
| 880 |
|| |
|---|
| 881 |
inset-start ; unused ; a = expression ; |
|---|
| 882 |
e = <exp_unused> ( a ) ; |
|---|
| 883 |
inset-end ; |
|---|
| 884 |
} ; |
|---|
| 885 |
|
|---|
| 886 |
inset-flow-statement : () -> ( e : EXP ) = { |
|---|
| 887 |
inset-start ; set ; a = expression ; |
|---|
| 888 |
e = <exp_set> ( a ) ; |
|---|
| 889 |
semicolon ; inset-end ; |
|---|
| 890 |
|| |
|---|
| 891 |
inset-start ; unused ; a = expression ; |
|---|
| 892 |
e = <exp_unused> ( a ) ; |
|---|
| 893 |
semicolon ; inset-end ; |
|---|
| 894 |
} ; |
|---|
| 895 |
|
|---|
| 896 |
|
|---|
| 897 |
/* |
|---|
| 898 |
EXPRESSIONS |
|---|
| 899 |
|
|---|
| 900 |
This rule describes the top level expressions. These are derived |
|---|
| 901 |
from the flow-expressions by the addition of the comma operator. |
|---|
| 902 |
*/ |
|---|
| 903 |
|
|---|
| 904 |
<exp_comma> : ( :LIST-EXP ) -> ( :EXP ) ; |
|---|
| 905 |
|
|---|
| 906 |
comma-expression-head : () -> ( e : EXP ) = { |
|---|
| 907 |
e = assignment-expression ; comma ; |
|---|
| 908 |
|| |
|---|
| 909 |
e = flow-expression ; |
|---|
| 910 |
|| |
|---|
| 911 |
e = inset-flow-expression ; |
|---|
| 912 |
} ; |
|---|
| 913 |
|
|---|
| 914 |
comma-expression-tail : () -> ( p : LIST-EXP ) = { |
|---|
| 915 |
a = assignment-expression ; |
|---|
| 916 |
q = <list_exp_null> ; |
|---|
| 917 |
p = <list_exp_cons> ( a, q ) ; |
|---|
| 918 |
|| |
|---|
| 919 |
a = comma-expression-head ; q = comma-expression-tail ; |
|---|
| 920 |
p = <list_exp_cons> ( a, q ) ; |
|---|
| 921 |
} ; |
|---|
| 922 |
|
|---|
| 923 |
expression : () -> ( e : EXP ) = { |
|---|
| 924 |
e = assignment-expression ; |
|---|
| 925 |
|| |
|---|
| 926 |
a = comma-expression-head ; q = comma-expression-tail ; |
|---|
| 927 |
p = <list_exp_cons> ( a, q ) ; |
|---|
| 928 |
e = <exp_comma> ( p ) ; |
|---|
| 929 |
} ; |
|---|
| 930 |
|
|---|
| 931 |
|
|---|
| 932 |
/* |
|---|
| 933 |
INITIALISER EXPRESSIONS |
|---|
| 934 |
|
|---|
| 935 |
An initialiser expression consists of an assignment expression |
|---|
| 936 |
with all its temporary variables bound to it. |
|---|
| 937 |
*/ |
|---|
| 938 |
|
|---|
| 939 |
initialiser-expression : () -> ( e : EXP ) = { |
|---|
| 940 |
e = assignment-expression ; |
|---|
| 941 |
} ; |
|---|
| 942 |
|
|---|
| 943 |
|
|---|
| 944 |
/* |
|---|
| 945 |
CONSTANT EXPRESSIONS |
|---|
| 946 |
|
|---|
| 947 |
This rule describes the constant expressions. Lexically these are |
|---|
| 948 |
identical to the conditional-expressions, but with restrictions on |
|---|
| 949 |
the permitted operands. Constant expressions are identified by |
|---|
| 950 |
evaluation - whenever a valid constant expression is encountered it |
|---|
| 951 |
is evaluated to give an integer literal expression. |
|---|
| 952 |
*/ |
|---|
| 953 |
|
|---|
| 954 |
<exp_eval> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 955 |
|
|---|
| 956 |
constant-expression : () -> ( e : EXP ) = { |
|---|
| 957 |
a = conditional-expression ; |
|---|
| 958 |
e = <exp_eval> ( a ) ; |
|---|
| 959 |
} ; |
|---|
| 960 |
|
|---|
| 961 |
|
|---|
| 962 |
/* |
|---|
| 963 |
LABELLED STATEMENTS |
|---|
| 964 |
|
|---|
| 965 |
This rule describes the labelled statements. These include the case |
|---|
| 966 |
and default statements as well as the simple labels. Note that the |
|---|
| 967 |
statements following the labels are only the first component of the |
|---|
| 968 |
label body. Actually imposing some structure on the labelled statements |
|---|
| 969 |
is the most difficult part of the statement processing. |
|---|
| 970 |
*/ |
|---|
| 971 |
|
|---|
| 972 |
<stmt_case_begin> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 973 |
<stmt_case_end> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 974 |
<stmt_default_begin> : () -> ( :EXP ) ; |
|---|
| 975 |
<stmt_default_end> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 976 |
<stmt_label_begin> : ( :IDENTIFIER ) -> ( :EXP ) ; |
|---|
| 977 |
<stmt_label_end> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 978 |
<stmt_label_set> : () -> () ; |
|---|
| 979 |
<stmt_label_mod> : () -> () ; |
|---|
| 980 |
<stmt_label_clear> : () -> () ; |
|---|
| 981 |
|
|---|
| 982 |
statement : () -> ( :EXP ) ; |
|---|
| 983 |
|
|---|
| 984 |
fall-check : () -> () = { |
|---|
| 985 |
fall ; <stmt_label_set> ; |
|---|
| 986 |
|| fall ; semicolon ; <stmt_label_set> ; |
|---|
| 987 |
|| $ ; |
|---|
| 988 |
} ; |
|---|
| 989 |
|
|---|
| 990 |
labelled-statement : () -> ( e : EXP ) = { |
|---|
| 991 |
fall-check ; |
|---|
| 992 |
case ; c = constant-expression ; |
|---|
| 993 |
a = <stmt_case_begin> ( c ) ; |
|---|
| 994 |
<stmt_label_set> ; |
|---|
| 995 |
colon ; b = statement ; |
|---|
| 996 |
e = <stmt_case_end> ( a, b ) ; |
|---|
| 997 |
|| |
|---|
| 998 |
fall-check ; |
|---|
| 999 |
default ; |
|---|
| 1000 |
a = <stmt_default_begin> ; |
|---|
| 1001 |
<stmt_label_set> ; |
|---|
| 1002 |
colon ; b = statement ; |
|---|
| 1003 |
e = <stmt_default_end> ( a, b ) ; |
|---|
| 1004 |
|| |
|---|
| 1005 |
id = any-identifier ; |
|---|
| 1006 |
<stmt_label_mod> ; |
|---|
| 1007 |
a = <stmt_label_begin> ( id ) ; |
|---|
| 1008 |
colon ; b = statement ; |
|---|
| 1009 |
e = <stmt_label_end> ( a, b ) ; |
|---|
| 1010 |
} ; |
|---|
| 1011 |
|
|---|
| 1012 |
|
|---|
| 1013 |
/* |
|---|
| 1014 |
EXPRESSION STATEMENTS |
|---|
| 1015 |
|
|---|
| 1016 |
This rule describes the expression statements, consisting of an optional |
|---|
| 1017 |
expression followed by a semicolon. |
|---|
| 1018 |
*/ |
|---|
| 1019 |
|
|---|
| 1020 |
<stmt_exp> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1021 |
<stmt_none> : () -> ( :EXP ) ; |
|---|
| 1022 |
<reach_check> : () -> ( :BOOL ) ; |
|---|
| 1023 |
<reach_prev> : ( :BOOL ) -> () ; |
|---|
| 1024 |
|
|---|
| 1025 |
block-expression : () -> ( e : EXP ) = { |
|---|
| 1026 |
e = expression ; |
|---|
| 1027 |
|| e = flow-expression ; |
|---|
| 1028 |
} ; |
|---|
| 1029 |
|
|---|
| 1030 |
expression-statement : () -> ( e : EXP ) = { |
|---|
| 1031 |
a = block-expression ; |
|---|
| 1032 |
r = <reach_check> ; |
|---|
| 1033 |
e = <stmt_exp> ( a ) ; |
|---|
| 1034 |
<stmt_label_clear> ; |
|---|
| 1035 |
semicolon ; |
|---|
| 1036 |
|| |
|---|
| 1037 |
a = inset-flow-statement ; |
|---|
| 1038 |
r = <reach_check> ; |
|---|
| 1039 |
e = <stmt_exp> ( a ) ; |
|---|
| 1040 |
<stmt_label_clear> ; |
|---|
| 1041 |
|| |
|---|
| 1042 |
semicolon ; |
|---|
| 1043 |
e = <stmt_none> ; |
|---|
| 1044 |
} ; |
|---|
| 1045 |
|
|---|
| 1046 |
|
|---|
| 1047 |
/* |
|---|
| 1048 |
COMPOUND STATEMENTS |
|---|
| 1049 |
|
|---|
| 1050 |
These rules describe the compound statements, consisting of a list of |
|---|
| 1051 |
statements enclosed within braces. Note that compound statements |
|---|
| 1052 |
automatically define a local scope. |
|---|
| 1053 |
*/ |
|---|
| 1054 |
|
|---|
| 1055 |
<stmt_compound_begin> : () -> ( :EXP ) ; |
|---|
| 1056 |
<stmt_compound_end> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1057 |
<stmt_compound_add> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1058 |
<stmt_compound_block> : ( :EXP ) -> ( :BOOL ) ; |
|---|
| 1059 |
<stmt_compound_mark> : ( :EXP ) -> () ; |
|---|
| 1060 |
<stmt_return_fall> : () -> ( :EXP ) ; |
|---|
| 1061 |
|
|---|
| 1062 |
<bool_true> : () -> ( :BOOL ) ; |
|---|
| 1063 |
<bool_false> : () -> ( :BOOL ) ; |
|---|
| 1064 |
|
|---|
| 1065 |
declaration-statement : ( :BOOL ) -> ( :EXP ) ; |
|---|
| 1066 |
|
|---|
| 1067 |
statement-seq-opt : ( c : EXP, d : BOOL ) -> ( e : EXP ) = { |
|---|
| 1068 |
a = statement ; |
|---|
| 1069 |
b = <stmt_compound_add> ( c, a ) ; |
|---|
| 1070 |
db = <bool_false> ; |
|---|
| 1071 |
e = statement-seq-opt ( b, db ) ; |
|---|
| 1072 |
|| |
|---|
| 1073 |
a = declaration-statement ( d ) ; |
|---|
| 1074 |
b = <stmt_compound_add> ( c, a ) ; |
|---|
| 1075 |
e = statement-seq-opt ( b, d ) ; |
|---|
| 1076 |
|| |
|---|
| 1077 |
e = c ; |
|---|
| 1078 |
} ; |
|---|
| 1079 |
|
|---|
| 1080 |
compound-statement : () -> ( e : EXP ) = { |
|---|
| 1081 |
c = <stmt_compound_begin> ; |
|---|
| 1082 |
open-brace ; |
|---|
| 1083 |
d = <stmt_compound_block> ( c ) ; |
|---|
| 1084 |
a = statement-seq-opt ( c, d ) ; |
|---|
| 1085 |
close-brace ; |
|---|
| 1086 |
e = <stmt_compound_end> ( a ) ; |
|---|
| 1087 |
<rescan_token> ; |
|---|
| 1088 |
} ; |
|---|
| 1089 |
|
|---|
| 1090 |
function-body : () -> ( e : EXP ) = { |
|---|
| 1091 |
c = <stmt_compound_begin> ; |
|---|
| 1092 |
open-brace ; |
|---|
| 1093 |
d = <stmt_compound_block> ( c ) ; |
|---|
| 1094 |
b = statement-seq-opt ( c, d ) ; |
|---|
| 1095 |
r = <stmt_return_fall> ; |
|---|
| 1096 |
a = <stmt_compound_add> ( b, r ) ; |
|---|
| 1097 |
close-brace ; |
|---|
| 1098 |
e = <stmt_compound_end> ( a ) ; |
|---|
| 1099 |
<rescan_token> ; |
|---|
| 1100 |
} ; |
|---|
| 1101 |
|
|---|
| 1102 |
function-definition-entry : () -> ( e : EXP ) = { |
|---|
| 1103 |
e = function-body ; |
|---|
| 1104 |
## |
|---|
| 1105 |
<error_syntax> ; |
|---|
| 1106 |
e = <exp_none> ; |
|---|
| 1107 |
} ; |
|---|
| 1108 |
|
|---|
| 1109 |
|
|---|
| 1110 |
/* |
|---|
| 1111 |
LOCAL STATEMENT SCOPES |
|---|
| 1112 |
|
|---|
| 1113 |
Several statements, in addition to the compound statements, form local |
|---|
| 1114 |
scopes (for example, the body of an iteration statement). This rule |
|---|
| 1115 |
describes such scopes, the initial scope expression begin passed in as |
|---|
| 1116 |
c to avoid predicate problems. Note that local scopes which are also |
|---|
| 1117 |
compound statements are treated differently from other (simple) |
|---|
| 1118 |
statements. |
|---|
| 1119 |
*/ |
|---|
| 1120 |
|
|---|
| 1121 |
simple-statement : () -> ( :EXP ) ; |
|---|
| 1122 |
|
|---|
| 1123 |
scoped-stmt-body : ( c : EXP ) -> ( e : EXP ) = { |
|---|
| 1124 |
open-brace ; |
|---|
| 1125 |
d = <stmt_compound_block> ( c ) ; |
|---|
| 1126 |
e = statement-seq-opt ( c, d ) ; |
|---|
| 1127 |
close-brace ; |
|---|
| 1128 |
|| |
|---|
| 1129 |
a = simple-statement ; |
|---|
| 1130 |
e = <stmt_compound_add> ( c, a ) ; |
|---|
| 1131 |
} ; |
|---|
| 1132 |
|
|---|
| 1133 |
scoped-statement : ( c : EXP ) -> ( e : EXP ) = { |
|---|
| 1134 |
a = scoped-stmt-body ( c ) ; |
|---|
| 1135 |
e = <stmt_compound_end> ( a ) ; |
|---|
| 1136 |
<rescan_token> ; |
|---|
| 1137 |
## |
|---|
| 1138 |
<error_syntax> ; |
|---|
| 1139 |
e = <stmt_compound_end> ( c ) ; |
|---|
| 1140 |
<rescan_token> ; |
|---|
| 1141 |
} ; |
|---|
| 1142 |
|
|---|
| 1143 |
|
|---|
| 1144 |
/* |
|---|
| 1145 |
DECLARATION STATEMENTS |
|---|
| 1146 |
|
|---|
| 1147 |
This rule describes the (non-empty) declaration statements, consisting |
|---|
| 1148 |
of just a declaration. See expression-statement for a discussion of |
|---|
| 1149 |
empty statements. The look-ahead required to distinguish declaration- |
|---|
| 1150 |
statements from expression-statements is implemented using the predicate |
|---|
| 1151 |
is_decl_statement. |
|---|
| 1152 |
*/ |
|---|
| 1153 |
|
|---|
| 1154 |
<is_decl_statement> : ( :BOOL ) -> ( :BOOL ) ; |
|---|
| 1155 |
<stmt_decl> : () -> ( :EXP ) ; |
|---|
| 1156 |
|
|---|
| 1157 |
declaration : () -> () ; |
|---|
| 1158 |
|
|---|
| 1159 |
declaration-statement : ( d : BOOL ) -> ( e : EXP ) = { |
|---|
| 1160 |
? = <is_decl_statement> ( d ) ; |
|---|
| 1161 |
declaration ; |
|---|
| 1162 |
e = <stmt_decl> ; |
|---|
| 1163 |
<stmt_label_clear> ; |
|---|
| 1164 |
} ; |
|---|
| 1165 |
|
|---|
| 1166 |
|
|---|
| 1167 |
/* |
|---|
| 1168 |
TARGET DEPENDENT CONDITIONAL COMPILATIONS |
|---|
| 1169 |
|
|---|
| 1170 |
These rules describe the unresolved target dependent conditional |
|---|
| 1171 |
compilations. Note that these must be structured, as opposed to the |
|---|
| 1172 |
normal unstructured preprocessing directives. Any braces required |
|---|
| 1173 |
to make the lists of statements in target dependent conditional |
|---|
| 1174 |
bodies into compound statements are automatically inserted by the |
|---|
| 1175 |
preprocessor. |
|---|
| 1176 |
*/ |
|---|
| 1177 |
|
|---|
| 1178 |
<stmt_hash_if> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1179 |
<stmt_hash_elif> : ( :EXP, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1180 |
<stmt_hash_endif> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1181 |
<cond_hash_if> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1182 |
<cond_hash_elif> : ( :EXP ) -> () ; |
|---|
| 1183 |
<cond_hash_else> : () -> () ; |
|---|
| 1184 |
<cond_hash_endif> : ( :EXP ) -> () ; |
|---|
| 1185 |
|
|---|
| 1186 |
target-condition-head : () -> ( e : EXP, p : EXP, r : BOOL ) = { |
|---|
| 1187 |
c = hash-if ; |
|---|
| 1188 |
p = <cond_hash_if> ( c ) ; |
|---|
| 1189 |
r = <reach_check> ; |
|---|
| 1190 |
a = compound-statement ; |
|---|
| 1191 |
<reach_prev> ( r ) ; |
|---|
| 1192 |
e = <stmt_hash_if> ( c, a ) ; |
|---|
| 1193 |
|| |
|---|
| 1194 |
( a, p, r ) = target-condition-head ; |
|---|
| 1195 |
c = hash-elif ; |
|---|
| 1196 |
<cond_hash_elif> ( c ) ; |
|---|
| 1197 |
s = <reach_check> ; |
|---|
| 1198 |
b = compound-statement ; |
|---|
| 1199 |
<reach_prev> ( r ) ; |
|---|
| 1200 |
e = <stmt_hash_elif> ( a, c, b ) ; |
|---|
| 1201 |
} ; |
|---|
| 1202 |
|
|---|
| 1203 |
target-condition : () -> ( e : EXP ) = { |
|---|
| 1204 |
( a, p, r ) = target-condition-head ; |
|---|
| 1205 |
{ |
|---|
| 1206 |
hash-else ; |
|---|
| 1207 |
<cond_hash_else> ; |
|---|
| 1208 |
s = <reach_check> ; |
|---|
| 1209 |
b = compound-statement ; |
|---|
| 1210 |
|| |
|---|
| 1211 |
b = <stmt_none> ; |
|---|
| 1212 |
} ; |
|---|
| 1213 |
<cond_hash_endif> ( p ) ; |
|---|
| 1214 |
hash-endif ; |
|---|
| 1215 |
<reach_prev> ( r ) ; |
|---|
| 1216 |
e = <stmt_hash_endif> ( a, b ) ; |
|---|
| 1217 |
} ; |
|---|
| 1218 |
|
|---|
| 1219 |
|
|---|
| 1220 |
/* |
|---|
| 1221 |
SELECTION STATEMENTS |
|---|
| 1222 |
|
|---|
| 1223 |
These rules describe the selection statements, consisting of the if |
|---|
| 1224 |
and switch statements, plus the target dependent conditionals above. |
|---|
| 1225 |
The way that the dangling else problem is dealt with is interesting. |
|---|
| 1226 |
A simple optional else-block leads to an ambiguity, however an |
|---|
| 1227 |
exception handler gives precisely what is required. To paraphrase, |
|---|
| 1228 |
an if statement always has an associated else, except when it doesn't. |
|---|
| 1229 |
*/ |
|---|
| 1230 |
|
|---|
| 1231 |
<stmt_if_begin> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1232 |
<stmt_if_cont> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1233 |
<stmt_if_end> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1234 |
<stmt_else> : () -> () ; |
|---|
| 1235 |
<stmt_no_else> : () -> ( :EXP ) ; |
|---|
| 1236 |
<stmt_switch_begin> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1237 |
<stmt_switch_end> : ( :EXP, :EXP, :BOOL ) -> ( :EXP ) ; |
|---|
| 1238 |
|
|---|
| 1239 |
<condition_get> : () -> ( :CONDITION ) ; |
|---|
| 1240 |
<condition_set> : ( :CONDITION ) -> () ; |
|---|
| 1241 |
|
|---|
| 1242 |
selection-statement : () -> ( e : EXP ) = { |
|---|
| 1243 |
if ; |
|---|
| 1244 |
x = <condition_get> ; |
|---|
| 1245 |
r = <reach_check> ; |
|---|
| 1246 |
open-round-x ; c = expression ; |
|---|
| 1247 |
a = <stmt_if_begin> ( c ) ; |
|---|
| 1248 |
close-round ; |
|---|
| 1249 |
bs = <stmt_compound_begin> ; |
|---|
| 1250 |
b = scoped-statement ( bs ) ; |
|---|
| 1251 |
<reach_prev> ( r ) ; |
|---|
| 1252 |
d = <stmt_if_cont> ( a, b ) ; |
|---|
| 1253 |
{ |
|---|
| 1254 |
else ; |
|---|
| 1255 |
<stmt_else> ; |
|---|
| 1256 |
fs = <stmt_compound_begin> ; |
|---|
| 1257 |
f = scoped-statement ( fs ) ; |
|---|
| 1258 |
## |
|---|
| 1259 |
f = <stmt_no_else> ; |
|---|
| 1260 |
} ; |
|---|
| 1261 |
<reach_prev> ( r ) ; |
|---|
| 1262 |
e = <stmt_if_end> ( d, f ) ; |
|---|
| 1263 |
<condition_set> ( x ) ; |
|---|
| 1264 |
<stmt_label_clear> ; |
|---|
| 1265 |
|| |
|---|
| 1266 |
switch ; |
|---|
| 1267 |
r = <reach_check> ; |
|---|
| 1268 |
open-round ; c = expression ; |
|---|
| 1269 |
a = <stmt_switch_begin> ( c ) ; |
|---|
| 1270 |
close-round ; |
|---|
| 1271 |
{ |
|---|
| 1272 |
exhaustive ; ex = <bool_true> ; |
|---|
| 1273 |
|| ex = <bool_false> ; |
|---|
| 1274 |
} ; |
|---|
| 1275 |
bs = <stmt_compound_begin> ; |
|---|
| 1276 |
b = scoped-statement ( bs ) ; |
|---|
| 1277 |
<reach_prev> ( r ) ; |
|---|
| 1278 |
e = <stmt_switch_end> ( a, b, ex ) ; |
|---|
| 1279 |
<stmt_label_clear> ; |
|---|
| 1280 |
|| |
|---|
| 1281 |
e = target-condition ; |
|---|
| 1282 |
<stmt_label_clear> ; |
|---|
| 1283 |
} ; |
|---|
| 1284 |
|
|---|
| 1285 |
|
|---|
| 1286 |
/* |
|---|
| 1287 |
ITERATION STATEMENTS |
|---|
| 1288 |
|
|---|
| 1289 |
These rules describe the iteration statements, consisting of the |
|---|
| 1290 |
while, do and for statements. |
|---|
| 1291 |
*/ |
|---|
| 1292 |
|
|---|
| 1293 |
<stmt_while_begin> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1294 |
<stmt_while_end> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1295 |
<stmt_do_begin> : () -> ( :EXP ) ; |
|---|
| 1296 |
<stmt_do_end> : ( :EXP, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1297 |
<stmt_for_begin> : () -> ( :EXP ) ; |
|---|
| 1298 |
<stmt_for_init> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1299 |
<stmt_for_cond> : ( :EXP, :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1300 |
<stmt_for_end> : ( :EXP, :EXP ) -> ( :EXP ) ; |
|---|
| 1301 |
<bind_temporary> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1302 |
<exp_location> : ( :EXP ) -> ( :EXP ) ; |
|---|
| 1303 |
|
|---|
| 1304 |
for-init-statement : () -> ( e : EXP ) = { |
|---|
| 1305 |
e = expression-statement ; |
|---|
| 1306 |
} ; |
|---|
| 1307 |
|
|---|
| 1308 |
for-cond-statement : () -> ( e : EXP ) = { |
|---|
| 1309 |
{ |
|---|
| 1310 |
a = expression ; |
|---|
| 1311 |
|| a = <exp_none> ; |
|---|
| 1312 |
} ; |
|---|
| 1313 |
b = <bind_temporary> ( a ) ; |
|---|
| 1314 |
e = <exp_location> ( b ) ; |
|---|
| 1315 |
semicolon ; |
|---|
| 1316 |
} ; |
|---|
| 1317 |
|
|---|
| 1318 |
for-end-statement : () -> ( e : EXP ) = { |
|---|
| 1319 |
a = expression ; |
|---|
| 1320 |
b = <stmt_exp> ( a ) ; |
|---|
| 1321 |
e = <bind_temporary> ( b ) ; |
|---|
| 1322 |
|| |
|---|
| 1323 |
e = <exp_none> ; |
|---|
| 1324 |
|
|---|