| 1 | %{ |
| 2 | /* |
| 3 | * ctf.y |
| 4 | * |
| 5 | * Common Trace Format Metadata Grammar. |
| 6 | */ |
| 7 | |
| 8 | #include <stdio.h> |
| 9 | #include <unistd.h> |
| 10 | #include <string.h> |
| 11 | #include <stdlib.h> |
| 12 | #include <assert.h> |
| 13 | #include <helpers/list.h> |
| 14 | #include <glib.h> |
| 15 | #include "ctf-parser.h" |
| 16 | #include "ctf-ast.h" |
| 17 | |
| 18 | #define printf_dbg(fmt, args...) fprintf(stderr, "%s: " fmt, __func__, args) |
| 19 | #define printf_dbg_noarg(fmt) fprintf(stderr, "%s: " fmt, __func__) |
| 20 | |
| 21 | int yyparse(void); |
| 22 | int yylex(void); |
| 23 | |
| 24 | static CDS_LIST_HEAD(allocated_strings); |
| 25 | int yydebug; |
| 26 | |
| 27 | struct scope; |
| 28 | struct scope { |
| 29 | struct scope *parent; |
| 30 | GHashTable *types; |
| 31 | }; |
| 32 | |
| 33 | struct gc_string { |
| 34 | struct cds_list_head gc; |
| 35 | char s[]; |
| 36 | }; |
| 37 | |
| 38 | struct scope root_scope; |
| 39 | struct scope *cs = &root_scope; /* current scope */ |
| 40 | |
| 41 | char *strredup(char **dest, const char *src) |
| 42 | { |
| 43 | size_t len = strlen(src) + 1; |
| 44 | |
| 45 | *dest = realloc(*dest, len); |
| 46 | if (!*dest) |
| 47 | return NULL; |
| 48 | strcpy(*dest, src); |
| 49 | return *dest; |
| 50 | } |
| 51 | |
| 52 | static struct gc_string *gc_string_alloc(size_t len) |
| 53 | { |
| 54 | struct gc_string *gstr; |
| 55 | |
| 56 | gstr = malloc(sizeof(*gstr) + len); |
| 57 | cds_list_add(&gstr->gc, &allocated_strings); |
| 58 | return gstr; |
| 59 | } |
| 60 | |
| 61 | void setstring(const char *src) |
| 62 | { |
| 63 | yylval.gs = gc_string_alloc(strlen(src) + 1); |
| 64 | strcpy(yylval.gs->s, src); |
| 65 | } |
| 66 | |
| 67 | static void init_scope(struct scope *scope, struct scope *parent) |
| 68 | { |
| 69 | scope->parent = parent; |
| 70 | scope->types = g_hash_table_new_full(g_str_hash, g_str_equal, |
| 71 | (GDestroyNotify) free, NULL); |
| 72 | } |
| 73 | |
| 74 | static void finalize_scope(struct scope *scope) |
| 75 | { |
| 76 | g_hash_table_destroy(scope->types); |
| 77 | } |
| 78 | |
| 79 | static void push_scope(void) |
| 80 | { |
| 81 | struct scope *ns; |
| 82 | |
| 83 | printf_dbg_noarg("push scope\n"); |
| 84 | ns = malloc(sizeof(struct scope)); |
| 85 | init_scope(ns, cs); |
| 86 | cs = ns; |
| 87 | } |
| 88 | |
| 89 | static void pop_scope(void) |
| 90 | { |
| 91 | struct scope *os; |
| 92 | |
| 93 | printf_dbg_noarg("pop scope\n"); |
| 94 | os = cs; |
| 95 | cs = os->parent; |
| 96 | finalize_scope(os); |
| 97 | free(os); |
| 98 | } |
| 99 | |
| 100 | int lookup_type(struct scope *s, const char *id) |
| 101 | { |
| 102 | int ret; |
| 103 | |
| 104 | ret = (int) g_hash_table_lookup(s->types, id); |
| 105 | printf_dbg("lookup %p %s %d\n", s, id, ret); |
| 106 | return ret; |
| 107 | } |
| 108 | |
| 109 | int is_type(const char *id) |
| 110 | { |
| 111 | struct scope *it; |
| 112 | int ret = 0; |
| 113 | |
| 114 | for (it = cs; it != NULL; it = it->parent) { |
| 115 | if (lookup_type(it, id)) { |
| 116 | ret = 1; |
| 117 | break; |
| 118 | } |
| 119 | } |
| 120 | printf_dbg("is type %s %d\n", id, ret); |
| 121 | return ret; |
| 122 | } |
| 123 | |
| 124 | static void add_type(const char *id) |
| 125 | { |
| 126 | char *type_id = NULL; |
| 127 | |
| 128 | printf_dbg("add type %s\n", id); |
| 129 | if (lookup_type(cs, id)) |
| 130 | return; |
| 131 | strredup(&type_id, id); |
| 132 | g_hash_table_insert(cs->types, type_id, type_id); |
| 133 | } |
| 134 | |
| 135 | void yyerror(const char *str) |
| 136 | { |
| 137 | fprintf(stderr, "error %s\n", str); |
| 138 | } |
| 139 | |
| 140 | int yywrap(void) |
| 141 | { |
| 142 | return 1; |
| 143 | } |
| 144 | |
| 145 | static void free_strings(void) |
| 146 | { |
| 147 | struct gc_string *gstr, *tmp; |
| 148 | |
| 149 | cds_list_for_each_entry_safe(gstr, tmp, &allocated_strings, gc) |
| 150 | free(gstr); |
| 151 | } |
| 152 | |
| 153 | int main(int argc, char **argv) |
| 154 | { |
| 155 | yydebug = 1; |
| 156 | init_scope(&root_scope, NULL); |
| 157 | yyparse(); |
| 158 | finalize_scope(&root_scope); |
| 159 | free_strings(); |
| 160 | return 0; |
| 161 | } |
| 162 | |
| 163 | %} |
| 164 | |
| 165 | %start file |
| 166 | /* %glr-parser */ |
| 167 | %token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT |
| 168 | %token <gs> IDENTIFIER ID_TYPE |
| 169 | %token ERROR |
| 170 | %union |
| 171 | { |
| 172 | long long ll; |
| 173 | char c; |
| 174 | struct gc_string *gs; |
| 175 | struct ctf_node *n; |
| 176 | } |
| 177 | |
| 178 | /* %token <c>UPPERCASE_L LOWERCASE_L _U _NONDIGIT */ |
| 179 | /*%type <n> decl type_decl event_decl stream_decl trace_decl type_def |
| 180 | %type <n> event_attrib field_attrib assign_attrib |
| 181 | %type <n> event_attrib_list attrib_list field_list appendval_list |
| 182 | %type <n> field value type_expr typename typename_postfix |
| 183 | %type <gs> typename_prefix identifier */ |
| 184 | %% |
| 185 | |
| 186 | file: |
| 187 | declaration |
| 188 | | file declaration |
| 189 | ; |
| 190 | |
| 191 | keywords: |
| 192 | VOID |
| 193 | | CHAR |
| 194 | | SHORT |
| 195 | | INT |
| 196 | | LONG |
| 197 | | FLOAT |
| 198 | | DOUBLE |
| 199 | | SIGNED |
| 200 | | UNSIGNED |
| 201 | | _BOOL |
| 202 | | _COMPLEX |
| 203 | | FLOATING_POINT |
| 204 | | INTEGER |
| 205 | | STRING |
| 206 | | ENUM |
| 207 | | VARIANT |
| 208 | | STRUCT |
| 209 | | CONST |
| 210 | | TYPEDEF |
| 211 | | EVENT |
| 212 | | STREAM |
| 213 | | TRACE |
| 214 | ; |
| 215 | |
| 216 | /* 1.5 Constants */ |
| 217 | |
| 218 | c_char_sequence: |
| 219 | c_char |
| 220 | | c_char_sequence c_char |
| 221 | ; |
| 222 | |
| 223 | c_char: |
| 224 | CHAR_STRING_TOKEN |
| 225 | | ESCSEQ |
| 226 | ; |
| 227 | |
| 228 | /* 1.6 String literals */ |
| 229 | |
| 230 | s_char_sequence: |
| 231 | s_char |
| 232 | | s_char_sequence s_char |
| 233 | ; |
| 234 | |
| 235 | s_char: |
| 236 | CHAR_STRING_TOKEN |
| 237 | | ESCSEQ |
| 238 | ; |
| 239 | |
| 240 | /* 2: Phrase structure grammar */ |
| 241 | |
| 242 | postfix_expression: |
| 243 | IDENTIFIER |
| 244 | | ID_TYPE |
| 245 | | keywords |
| 246 | | DECIMAL_CONSTANT |
| 247 | | OCTAL_CONSTANT |
| 248 | | HEXADECIMAL_CONSTANT |
| 249 | | STRING_LITERAL_START DQUOTE |
| 250 | | STRING_LITERAL_START s_char_sequence DQUOTE |
| 251 | | CHARACTER_CONSTANT_START c_char_sequence SQUOTE |
| 252 | | LPAREN unary_expression RPAREN |
| 253 | | postfix_expression LSBRAC unary_expression RSBRAC |
| 254 | | postfix_expression DOT IDENTIFIER |
| 255 | | postfix_expression DOT ID_TYPE |
| 256 | | postfix_expression RARROW IDENTIFIER |
| 257 | | postfix_expression RARROW ID_TYPE |
| 258 | ; |
| 259 | |
| 260 | unary_expression: |
| 261 | postfix_expression |
| 262 | | PLUS postfix_expression |
| 263 | | MINUS postfix_expression |
| 264 | ; |
| 265 | |
| 266 | unary_expression_or_range: |
| 267 | unary_expression DOTDOTDOT unary_expression |
| 268 | | unary_expression |
| 269 | ; |
| 270 | |
| 271 | /* 2.2: Declarations */ |
| 272 | |
| 273 | declaration: |
| 274 | declaration_specifiers SEMICOLON |
| 275 | | event_declaration |
| 276 | | stream_declaration |
| 277 | | trace_declaration |
| 278 | | declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON |
| 279 | | TYPEDEF declaration_specifiers type_declarator_list SEMICOLON |
| 280 | | declaration_specifiers TYPEDEF type_declarator_list SEMICOLON |
| 281 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list SEMICOLON |
| 282 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list SEMICOLON |
| 283 | ; |
| 284 | |
| 285 | event_declaration: |
| 286 | event_declaration_begin event_declaration_end |
| 287 | | event_declaration_begin ctf_assignment_expression_list event_declaration_end |
| 288 | ; |
| 289 | |
| 290 | event_declaration_begin: |
| 291 | EVENT LBRAC |
| 292 | { |
| 293 | push_scope(); |
| 294 | } |
| 295 | ; |
| 296 | |
| 297 | event_declaration_end: |
| 298 | RBRAC SEMICOLON |
| 299 | { |
| 300 | pop_scope(); |
| 301 | } |
| 302 | ; |
| 303 | |
| 304 | |
| 305 | stream_declaration: |
| 306 | stream_declaration_begin stream_declaration_end |
| 307 | | stream_declaration_begin ctf_assignment_expression_list stream_declaration_end |
| 308 | ; |
| 309 | |
| 310 | stream_declaration_begin: |
| 311 | STREAM LBRAC |
| 312 | { |
| 313 | push_scope(); |
| 314 | } |
| 315 | ; |
| 316 | |
| 317 | stream_declaration_end: |
| 318 | RBRAC SEMICOLON |
| 319 | { |
| 320 | pop_scope(); |
| 321 | } |
| 322 | ; |
| 323 | |
| 324 | |
| 325 | trace_declaration: |
| 326 | trace_declaration_begin trace_declaration_end |
| 327 | | trace_declaration_begin ctf_assignment_expression_list trace_declaration_end |
| 328 | ; |
| 329 | |
| 330 | trace_declaration_begin: |
| 331 | TRACE LBRAC |
| 332 | { |
| 333 | push_scope(); |
| 334 | } |
| 335 | ; |
| 336 | |
| 337 | trace_declaration_end: |
| 338 | RBRAC SEMICOLON |
| 339 | { |
| 340 | pop_scope(); |
| 341 | } |
| 342 | ; |
| 343 | |
| 344 | declaration_specifiers: |
| 345 | CONST |
| 346 | | type_specifier |
| 347 | | declaration_specifiers CONST |
| 348 | | declaration_specifiers type_specifier |
| 349 | ; |
| 350 | |
| 351 | type_declarator_list: |
| 352 | type_declarator |
| 353 | | type_declarator_list COMMA type_declarator |
| 354 | ; |
| 355 | |
| 356 | abstract_type_declarator_list: |
| 357 | abstract_type_declarator |
| 358 | | abstract_type_declarator_list COMMA abstract_type_declarator |
| 359 | ; |
| 360 | |
| 361 | type_specifier: |
| 362 | VOID |
| 363 | | CHAR |
| 364 | | SHORT |
| 365 | | INT |
| 366 | | LONG |
| 367 | | FLOAT |
| 368 | | DOUBLE |
| 369 | | SIGNED |
| 370 | | UNSIGNED |
| 371 | | _BOOL |
| 372 | | _COMPLEX |
| 373 | | ID_TYPE |
| 374 | | FLOATING_POINT LBRAC RBRAC |
| 375 | | FLOATING_POINT LBRAC ctf_assignment_expression_list RBRAC |
| 376 | | INTEGER LBRAC RBRAC |
| 377 | | INTEGER LBRAC ctf_assignment_expression_list RBRAC |
| 378 | | STRING LBRAC RBRAC |
| 379 | | STRING LBRAC ctf_assignment_expression_list RBRAC |
| 380 | | ENUM enum_type_specifier |
| 381 | | VARIANT variant_type_specifier |
| 382 | | STRUCT struct_type_specifier |
| 383 | ; |
| 384 | |
| 385 | struct_type_specifier: |
| 386 | struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end |
| 387 | | IDENTIFIER struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end |
| 388 | | ID_TYPE struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end |
| 389 | | IDENTIFIER |
| 390 | | ID_TYPE |
| 391 | ; |
| 392 | |
| 393 | struct_declaration_begin: |
| 394 | LBRAC |
| 395 | { |
| 396 | push_scope(); |
| 397 | } |
| 398 | ; |
| 399 | |
| 400 | struct_declaration_end: |
| 401 | RBRAC |
| 402 | { |
| 403 | pop_scope(); |
| 404 | } |
| 405 | ; |
| 406 | |
| 407 | variant_type_specifier: |
| 408 | variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 409 | | LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 410 | | LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 411 | | IDENTIFIER variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 412 | | IDENTIFIER LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 413 | | IDENTIFIER LT IDENTIFIER GT |
| 414 | | IDENTIFIER LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 415 | | IDENTIFIER LT ID_TYPE GT |
| 416 | | ID_TYPE variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 417 | | ID_TYPE LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 418 | | ID_TYPE LT IDENTIFIER GT |
| 419 | | ID_TYPE LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end |
| 420 | | ID_TYPE LT ID_TYPE GT |
| 421 | ; |
| 422 | |
| 423 | variant_declaration_begin: |
| 424 | LBRAC |
| 425 | { |
| 426 | push_scope(); |
| 427 | } |
| 428 | ; |
| 429 | |
| 430 | variant_declaration_end: |
| 431 | RBRAC |
| 432 | { |
| 433 | pop_scope(); |
| 434 | } |
| 435 | ; |
| 436 | |
| 437 | type_specifier_or_integer_constant: |
| 438 | declaration_specifiers |
| 439 | | DECIMAL_CONSTANT |
| 440 | | OCTAL_CONSTANT |
| 441 | | HEXADECIMAL_CONSTANT |
| 442 | ; |
| 443 | |
| 444 | enum_type_specifier: |
| 445 | LBRAC enumerator_list RBRAC |
| 446 | | LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC |
| 447 | | IDENTIFIER LBRAC enumerator_list RBRAC |
| 448 | | IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC |
| 449 | | ID_TYPE LBRAC enumerator_list RBRAC |
| 450 | | ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC |
| 451 | | LBRAC enumerator_list COMMA RBRAC |
| 452 | | LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC |
| 453 | | IDENTIFIER LBRAC enumerator_list COMMA RBRAC |
| 454 | | IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC |
| 455 | | IDENTIFIER |
| 456 | | IDENTIFIER LT type_specifier_or_integer_constant GT |
| 457 | | ID_TYPE LBRAC enumerator_list COMMA RBRAC |
| 458 | | ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC |
| 459 | | ID_TYPE |
| 460 | | ID_TYPE LT type_specifier_or_integer_constant GT |
| 461 | ; |
| 462 | |
| 463 | struct_or_variant_declaration_list: |
| 464 | /* empty */ |
| 465 | | struct_or_variant_declaration_list struct_or_variant_declaration |
| 466 | ; |
| 467 | |
| 468 | struct_or_variant_declaration: |
| 469 | specifier_qualifier_list struct_or_variant_declarator_list SEMICOLON |
| 470 | | specifier_qualifier_list TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON |
| 471 | | TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON |
| 472 | | specifier_qualifier_list TYPEDEF type_declarator_list SEMICOLON |
| 473 | | TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON specifier_qualifier_list abstract_type_declarator_list SEMICOLON |
| 474 | | TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON type_declarator_list SEMICOLON |
| 475 | ; |
| 476 | |
| 477 | specifier_qualifier_list: |
| 478 | CONST |
| 479 | | type_specifier |
| 480 | | specifier_qualifier_list CONST |
| 481 | | specifier_qualifier_list type_specifier |
| 482 | ; |
| 483 | |
| 484 | struct_or_variant_declarator_list: |
| 485 | struct_or_variant_declarator |
| 486 | | struct_or_variant_declarator_list COMMA struct_or_variant_declarator |
| 487 | ; |
| 488 | |
| 489 | struct_or_variant_declarator: |
| 490 | declarator |
| 491 | | COLON unary_expression |
| 492 | | declarator COLON unary_expression |
| 493 | ; |
| 494 | |
| 495 | enumerator_list: |
| 496 | enumerator |
| 497 | | enumerator_list COMMA enumerator |
| 498 | ; |
| 499 | |
| 500 | enumerator: |
| 501 | IDENTIFIER |
| 502 | | ID_TYPE |
| 503 | | keywords |
| 504 | | STRING_LITERAL_START DQUOTE |
| 505 | | STRING_LITERAL_START s_char_sequence DQUOTE |
| 506 | | IDENTIFIER EQUAL unary_expression_or_range |
| 507 | | ID_TYPE EQUAL unary_expression_or_range |
| 508 | | keywords EQUAL unary_expression_or_range |
| 509 | | STRING_LITERAL_START DQUOTE EQUAL unary_expression_or_range |
| 510 | | STRING_LITERAL_START s_char_sequence DQUOTE EQUAL unary_expression_or_range |
| 511 | ; |
| 512 | |
| 513 | abstract_declarator_list: |
| 514 | abstract_declarator |
| 515 | | abstract_declarator_list COMMA abstract_declarator |
| 516 | ; |
| 517 | |
| 518 | abstract_declarator: |
| 519 | direct_abstract_declarator |
| 520 | | pointer direct_abstract_declarator |
| 521 | ; |
| 522 | |
| 523 | direct_abstract_declarator: |
| 524 | /* empty */ |
| 525 | | IDENTIFIER |
| 526 | | LPAREN abstract_declarator RPAREN |
| 527 | | direct_abstract_declarator LSBRAC type_specifier_or_integer_constant RSBRAC |
| 528 | | direct_abstract_declarator LSBRAC RSBRAC |
| 529 | ; |
| 530 | |
| 531 | declarator: |
| 532 | direct_declarator |
| 533 | | pointer direct_declarator |
| 534 | ; |
| 535 | |
| 536 | direct_declarator: |
| 537 | IDENTIFIER |
| 538 | | LPAREN declarator RPAREN |
| 539 | | direct_declarator LSBRAC type_specifier_or_integer_constant RSBRAC |
| 540 | ; |
| 541 | |
| 542 | type_declarator: |
| 543 | direct_type_declarator |
| 544 | | pointer direct_type_declarator |
| 545 | ; |
| 546 | |
| 547 | direct_type_declarator: |
| 548 | IDENTIFIER |
| 549 | { |
| 550 | add_type($1->s); |
| 551 | } |
| 552 | | LPAREN type_declarator RPAREN |
| 553 | | direct_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC |
| 554 | ; |
| 555 | |
| 556 | abstract_type_declarator: |
| 557 | direct_abstract_type_declarator |
| 558 | | pointer direct_abstract_type_declarator |
| 559 | ; |
| 560 | |
| 561 | direct_abstract_type_declarator: |
| 562 | /* empty */ |
| 563 | | IDENTIFIER |
| 564 | { |
| 565 | add_type($1->s); |
| 566 | } |
| 567 | | LPAREN abstract_type_declarator RPAREN |
| 568 | | direct_abstract_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC |
| 569 | | direct_abstract_type_declarator LSBRAC RSBRAC |
| 570 | ; |
| 571 | |
| 572 | pointer: |
| 573 | STAR |
| 574 | | STAR pointer |
| 575 | | STAR type_qualifier_list pointer |
| 576 | ; |
| 577 | |
| 578 | type_qualifier_list: |
| 579 | CONST |
| 580 | | type_qualifier_list CONST |
| 581 | ; |
| 582 | |
| 583 | /* 2.3: CTF-specific declarations */ |
| 584 | |
| 585 | ctf_assignment_expression_list: |
| 586 | ctf_assignment_expression SEMICOLON |
| 587 | | ctf_assignment_expression_list ctf_assignment_expression SEMICOLON |
| 588 | ; |
| 589 | |
| 590 | ctf_assignment_expression: |
| 591 | unary_expression EQUAL unary_expression |
| 592 | | unary_expression TYPEASSIGN type_specifier |
| 593 | | declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list |
| 594 | | TYPEDEF declaration_specifiers type_declarator_list |
| 595 | | declaration_specifiers TYPEDEF type_declarator_list |
| 596 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list |
| 597 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list |
| 598 | ; |