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