- Timestamp:
- May 27, 2015, 11:09:08 AM (10 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 42336618
- Parents:
- e15b0a0a
- File:
-
- 1 edited
-
src/Parser/cfa.y (modified) (25 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/cfa.y
re15b0a0a r4d51835 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 26 22:38:42201513 // Update Count : 99512 // Last Modified On : Wed May 27 09:20:53 2015 13 // Update Count : 1015 14 14 // 15 15 … … 177 177 %type<en> field field_list 178 178 179 %type<decl> function_array function_declarator function_definitionfunction_no_ptr function_ptr179 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr 180 180 181 181 %type<decl> identifier_parameter_array identifier_parameter_declarator identifier_parameter_function … … 279 279 280 280 push: 281 {282 typedefTable.enterScope();283 }284 ;281 { 282 typedefTable.enterScope(); 283 } 284 ; 285 285 286 286 pop: 287 {288 typedefTable.leaveScope();289 }290 ;287 { 288 typedefTable.leaveScope(); 289 } 290 ; 291 291 292 292 //************************* CONSTANTS ******************************** 293 293 294 294 constant: 295 // ENUMERATIONconstant is not included here; it is treated as a variable with type296 // "enumeration constant".297 INTEGERconstant{ $$ = new ConstantNode(ConstantNode::Integer, $1); }298 | FLOATINGconstant{ $$ = new ConstantNode(ConstantNode::Float, $1); }299 | CHARACTERconstant{ $$ = new ConstantNode(ConstantNode::Character, $1); }300 ;295 // ENUMERATIONconstant is not included here; it is treated as a variable with type 296 // "enumeration constant". 297 INTEGERconstant { $$ = new ConstantNode(ConstantNode::Integer, $1); } 298 | FLOATINGconstant { $$ = new ConstantNode(ConstantNode::Float, $1); } 299 | CHARACTERconstant { $$ = new ConstantNode(ConstantNode::Character, $1); } 300 ; 301 301 302 302 identifier: 303 IDENTIFIER304 | ATTR_IDENTIFIER// CFA305 | zero_one// CFA306 ;303 IDENTIFIER 304 | ATTR_IDENTIFIER // CFA 305 | zero_one // CFA 306 ; 307 307 308 308 no_01_identifier: 309 IDENTIFIER310 | ATTR_IDENTIFIER// CFA311 ;309 IDENTIFIER 310 | ATTR_IDENTIFIER // CFA 311 ; 312 312 313 313 no_attr_identifier: 314 IDENTIFIER315 ;314 IDENTIFIER 315 ; 316 316 317 317 zero_one: // CFA 318 ZERO319 | ONE320 ;318 ZERO 319 | ONE 320 ; 321 321 322 322 string_literal_list: // juxtaposed strings are concatenated 323 STRINGliteral{ $$ = new ConstantNode(ConstantNode::String, $1); }324 | string_literal_list STRINGliteral{ $$ = $1->append( $2 ); }325 ;323 STRINGliteral { $$ = new ConstantNode(ConstantNode::String, $1); } 324 | string_literal_list STRINGliteral { $$ = $1->append( $2 ); } 325 ; 326 326 327 327 //************************* EXPRESSIONS ******************************** 328 328 329 329 primary_expression: 330 IDENTIFIER// typedef name cannot be used as a variable name331 { $$ = new VarRefNode($1); }332 | zero_one333 { $$ = new VarRefNode($1); }334 | constant335 { $$ = $1; }336 | string_literal_list337 { $$ = $1; }338 | '(' comma_expression ')'339 { $$ = $2; }340 | '(' compound_statement ')'// GCC, lambda expression341 { $$ = new ValofExprNode($2); }342 ;330 IDENTIFIER // typedef name cannot be used as a variable name 331 { $$ = new VarRefNode($1); } 332 | zero_one 333 { $$ = new VarRefNode($1); } 334 | constant 335 { $$ = $1; } 336 | string_literal_list 337 { $$ = $1; } 338 | '(' comma_expression ')' 339 { $$ = $2; } 340 | '(' compound_statement ')' // GCC, lambda expression 341 { $$ = new ValofExprNode($2); } 342 ; 343 343 344 344 postfix_expression: 345 primary_expression346 | postfix_expression '[' push assignment_expression pop ']'347 // CFA, comma_expression disallowed in the context because it results in a commom user error:348 // subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards349 // compatible, there seems to be little advantage to this feature and many disadvantages. It350 // ispossible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j].351 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Index), $1, $4); }352 | postfix_expression '(' argument_expression_list ')'353 { $$ = new CompositeExprNode($1, $3); }354 | postfix_expression '.' no_attr_identifier355 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), $1, new VarRefNode($3)); }356 | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector357 | postfix_expression ARROW no_attr_identifier358 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), $1, new VarRefNode($3)); }359 | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector360 | postfix_expression ICR361 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); }362 | postfix_expression DECR363 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); }364 // GCC has priority: cast_expression365 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99366 { $$ = 0; }367 ;345 primary_expression 346 | postfix_expression '[' push assignment_expression pop ']' 347 // CFA, comma_expression disallowed in the context because it results in a commom user error: 348 // subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards 349 // compatible, there seems to be little advantage to this feature and many disadvantages. It is 350 // possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j]. 351 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Index), $1, $4); } 352 | postfix_expression '(' argument_expression_list ')' 353 { $$ = new CompositeExprNode($1, $3); } 354 | postfix_expression '.' no_attr_identifier 355 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), $1, new VarRefNode($3)); } 356 | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector 357 | postfix_expression ARROW no_attr_identifier 358 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), $1, new VarRefNode($3)); } 359 | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector 360 | postfix_expression ICR 361 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); } 362 | postfix_expression DECR 363 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); } 364 // GCC has priority: cast_expression 365 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99 366 { $$ = 0; } 367 ; 368 368 369 369 argument_expression_list: 370 argument_expression371 | argument_expression_list ',' argument_expression372 { $$ = (ExpressionNode *)($1->set_link($3)); }373 ;370 argument_expression 371 | argument_expression_list ',' argument_expression 372 { $$ = (ExpressionNode *)($1->set_link($3)); } 373 ; 374 374 375 375 argument_expression: 376 // empty377 { $$ = 0; }// use default argument378 | assignment_expression379 | no_attr_identifier ':' assignment_expression380 { $$ = $3->set_asArgName($1); }381 // Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However,382 // there is insufficient look ahead to distinguish between this list of parameter names and a383 // tuple, so thetuple form must be used with an appropriate semantic check.384 | '[' push assignment_expression pop ']' ':' assignment_expression385 { $$ = $7->set_asArgName($3); }386 | '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression387 { $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }388 ;376 // empty 377 { $$ = 0; } // use default argument 378 | assignment_expression 379 | no_attr_identifier ':' assignment_expression 380 { $$ = $3->set_asArgName($1); } 381 // Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However, there is 382 // insufficient look ahead to distinguish between this list of parameter names and a tuple, so the 383 // tuple form must be used with an appropriate semantic check. 384 | '[' push assignment_expression pop ']' ':' assignment_expression 385 { $$ = $7->set_asArgName($3); } 386 | '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression 387 { $$ = $9->set_asArgName( new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); } 388 ; 389 389 390 390 field_list: // CFA, tuple field selector 391 field392 | field_list ',' field{ $$ = (ExpressionNode *)$1->set_link( $3 ); }393 ;391 field 392 | field_list ',' field { $$ = (ExpressionNode *)$1->set_link( $3 ); } 393 ; 394 394 395 395 field: // CFA, tuple field selector 396 no_attr_identifier397 { $$ = new VarRefNode( $1 ); }398 | no_attr_identifier '.' field399 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $3); }400 | no_attr_identifier '.' '[' push field_list pop ']'401 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $5); }402 | no_attr_identifier ARROW field403 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $3); }404 | no_attr_identifier ARROW '[' push field_list pop ']'405 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $5); }406 ;396 no_attr_identifier 397 { $$ = new VarRefNode( $1 ); } 398 | no_attr_identifier '.' field 399 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $3); } 400 | no_attr_identifier '.' '[' push field_list pop ']' 401 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $5); } 402 | no_attr_identifier ARROW field 403 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $3); } 404 | no_attr_identifier ARROW '[' push field_list pop ']' 405 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $5); } 406 ; 407 407 408 408 unary_expression: 409 postfix_expression410 | ICR unary_expression411 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Incr), $2); }412 | DECR unary_expression413 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); }414 | EXTENSION cast_expression// GCC415 { $$ = $2; }416 | unary_operator cast_expression417 { $$ = new CompositeExprNode($1, $2); }418 | '!' cast_expression419 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); }420 | '*' cast_expression// CFA421 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); }422 // '*' is is separated from unary_operator because of shift/reduce conflict in:423 // { * X; } // dereference X424 // { * int X; } // CFA declaration of pointer to int425 // '&' must be moved here if C++ reference variables are supported.426 | SIZEOF unary_expression427 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); }428 | SIZEOF '(' type_name_no_function ')'429 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), new TypeValueNode($3)); }430 | ATTR_IDENTIFIER431 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1)); }432 | ATTR_IDENTIFIER '(' type_name ')'433 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), new TypeValueNode($3)); }434 | ATTR_IDENTIFIER '(' argument_expression ')'435 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), $3); }436 | ALIGNOF unary_expression// GCC, variable alignment437 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), $2); }438 | ALIGNOF '(' type_name_no_function ')'// GCC, type alignment439 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); }440 | ANDAND no_attr_identifier// GCC, address of label441 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress), new VarRefNode($2, true)); }442 ;409 postfix_expression 410 | ICR unary_expression 411 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Incr), $2); } 412 | DECR unary_expression 413 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); } 414 | EXTENSION cast_expression // GCC 415 { $$ = $2; } 416 | unary_operator cast_expression 417 { $$ = new CompositeExprNode($1, $2); } 418 | '!' cast_expression 419 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); } 420 | '*' cast_expression // CFA 421 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); } 422 // '*' is is separated from unary_operator because of shift/reduce conflict in: 423 // { * X; } // dereference X 424 // { * int X; } // CFA declaration of pointer to int 425 // '&' must be moved here if C++ reference variables are supported. 426 | SIZEOF unary_expression 427 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); } 428 | SIZEOF '(' type_name_no_function ')' 429 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), new TypeValueNode($3)); } 430 | ATTR_IDENTIFIER 431 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1)); } 432 | ATTR_IDENTIFIER '(' type_name ')' 433 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), new TypeValueNode($3)); } 434 | ATTR_IDENTIFIER '(' argument_expression ')' 435 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), $3); } 436 | ALIGNOF unary_expression // GCC, variable alignment 437 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), $2); } 438 | ALIGNOF '(' type_name_no_function ')' // GCC, type alignment 439 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); } 440 | ANDAND no_attr_identifier // GCC, address of label 441 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress), new VarRefNode($2, true)); } 442 ; 443 443 444 444 unary_operator: 445 '&'{ $$ = new OperatorNode(OperatorNode::AddressOf); }446 | '+'{ $$ = new OperatorNode(OperatorNode::UnPlus); }447 | '-'{ $$ = new OperatorNode(OperatorNode::UnMinus); }448 | '~'{ $$ = new OperatorNode(OperatorNode::BitNeg); }449 ;445 '&' { $$ = new OperatorNode(OperatorNode::AddressOf); } 446 | '+' { $$ = new OperatorNode(OperatorNode::UnPlus); } 447 | '-' { $$ = new OperatorNode(OperatorNode::UnMinus); } 448 | '~' { $$ = new OperatorNode(OperatorNode::BitNeg); } 449 ; 450 450 451 451 cast_expression: 452 unary_expression453 | '(' type_name_no_function ')' cast_expression454 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }455 | '(' type_name_no_function ')' tuple456 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); }457 ;452 unary_expression 453 | '(' type_name_no_function ')' cast_expression 454 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); } 455 | '(' type_name_no_function ')' tuple 456 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast), new TypeValueNode($2), $4); } 457 ; 458 458 459 459 multiplicative_expression: 460 cast_expression461 | multiplicative_expression '*' cast_expression462 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mul),$1,$3); }463 | multiplicative_expression '/' cast_expression464 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Div),$1,$3); }465 | multiplicative_expression '%' cast_expression466 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mod),$1,$3); }467 ;460 cast_expression 461 | multiplicative_expression '*' cast_expression 462 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mul),$1,$3); } 463 | multiplicative_expression '/' cast_expression 464 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Div),$1,$3); } 465 | multiplicative_expression '%' cast_expression 466 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mod),$1,$3); } 467 ; 468 468 469 469 additive_expression: 470 multiplicative_expression471 | additive_expression '+' multiplicative_expression472 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Plus),$1,$3); }473 | additive_expression '-' multiplicative_expression474 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Minus),$1,$3); }475 ;470 multiplicative_expression 471 | additive_expression '+' multiplicative_expression 472 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Plus),$1,$3); } 473 | additive_expression '-' multiplicative_expression 474 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Minus),$1,$3); } 475 ; 476 476 477 477 shift_expression: 478 additive_expression479 | shift_expression LS additive_expression480 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LShift),$1,$3); }481 | shift_expression RS additive_expression482 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::RShift),$1,$3); }483 ;478 additive_expression 479 | shift_expression LS additive_expression 480 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LShift),$1,$3); } 481 | shift_expression RS additive_expression 482 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::RShift),$1,$3); } 483 ; 484 484 485 485 relational_expression: 486 shift_expression487 | relational_expression '<' shift_expression488 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LThan),$1,$3); }489 | relational_expression '>' shift_expression490 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GThan),$1,$3); }491 | relational_expression LE shift_expression492 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LEThan),$1,$3); }493 | relational_expression GE shift_expression494 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GEThan),$1,$3); }495 ;486 shift_expression 487 | relational_expression '<' shift_expression 488 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LThan),$1,$3); } 489 | relational_expression '>' shift_expression 490 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GThan),$1,$3); } 491 | relational_expression LE shift_expression 492 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LEThan),$1,$3); } 493 | relational_expression GE shift_expression 494 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GEThan),$1,$3); } 495 ; 496 496 497 497 equality_expression: 498 relational_expression499 | equality_expression EQ relational_expression500 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Eq), $1, $3); }501 | equality_expression NE relational_expression502 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neq), $1, $3); }503 ;498 relational_expression 499 | equality_expression EQ relational_expression 500 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Eq), $1, $3); } 501 | equality_expression NE relational_expression 502 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neq), $1, $3); } 503 ; 504 504 505 505 AND_expression: 506 equality_expression507 | AND_expression '&' equality_expression508 { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::BitAnd), $1, $3); }509 ;506 equality_expression 507 | AND_expression '&' equality_expression 508 { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::BitAnd), $1, $3); } 509 ; 510 510 511 511 exclusive_OR_expression: 512 AND_expression513 | exclusive_OR_expression '^' AND_expression514 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Xor), $1, $3); }515 ;512 AND_expression 513 | exclusive_OR_expression '^' AND_expression 514 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Xor), $1, $3); } 515 ; 516 516 517 517 inclusive_OR_expression: 518 exclusive_OR_expression519 | inclusive_OR_expression '|' exclusive_OR_expression520 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::BitOr), $1, $3); }521 ;518 exclusive_OR_expression 519 | inclusive_OR_expression '|' exclusive_OR_expression 520 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::BitOr), $1, $3); } 521 ; 522 522 523 523 logical_AND_expression: 524 inclusive_OR_expression525 | logical_AND_expression ANDAND inclusive_OR_expression526 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::And), $1, $3); }527 ;524 inclusive_OR_expression 525 | logical_AND_expression ANDAND inclusive_OR_expression 526 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::And), $1, $3); } 527 ; 528 528 529 529 logical_OR_expression: 530 logical_AND_expression531 | logical_OR_expression OROR logical_AND_expression532 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Or), $1, $3); }533 ;530 logical_AND_expression 531 | logical_OR_expression OROR logical_AND_expression 532 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Or), $1, $3); } 533 ; 534 534 535 535 conditional_expression: 536 logical_OR_expression537 | logical_OR_expression '?' comma_expression ':' conditional_expression538 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList((*$1,*$3,*$5))); }539 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand540 { $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond),$1,$4); }541 | logical_OR_expression '?' comma_expression ':' tuple // CFA, tuple expression542 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); }543 ;536 logical_OR_expression 537 | logical_OR_expression '?' comma_expression ':' conditional_expression 538 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList((*$1,*$3,*$5))); } 539 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 540 { $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond),$1,$4); } 541 | logical_OR_expression '?' comma_expression ':' tuple // CFA, tuple expression 542 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); } 543 ; 544 544 545 545 constant_expression: 546 conditional_expression547 ;546 conditional_expression 547 ; 548 548 549 549 assignment_expression: 550 // CFA, assignment is separated from assignment_operator to ensure no assignment operations 551 // for tuples 552 conditional_expression 553 | unary_expression '=' assignment_expression 554 { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::Assign), $1, $3); } 555 | unary_expression assignment_operator assignment_expression 556 { $$ =new CompositeExprNode($2, $1, $3); } 557 | tuple assignment_opt // CFA, tuple expression 558 { $$ = ($2 == 0) ? $1 : new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $2 ); } 559 ; 550 // CFA, assignment is separated from assignment_operator to ensure no assignment operations for tuples 551 conditional_expression 552 | unary_expression '=' assignment_expression 553 { $$ =new CompositeExprNode(new OperatorNode(OperatorNode::Assign), $1, $3); } 554 | unary_expression assignment_operator assignment_expression 555 { $$ =new CompositeExprNode($2, $1, $3); } 556 | tuple assignment_opt // CFA, tuple expression 557 { $$ = ($2 == 0) ? $1 : new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $2 ); } 558 ; 560 559 561 560 assignment_expression_opt: 562 // empty563 { $$ = new NullExprNode; }564 | assignment_expression565 ;561 // empty 562 { $$ = new NullExprNode; } 563 | assignment_expression 564 ; 566 565 567 566 tuple: // CFA, tuple 568 // CFA, one assignment_expression is factored out of comma_expression to eliminate a 569 // shift/reduce conflict with comma_expression in new_identifier_parameter_array and 570 // new_abstract_array 571 '[' push pop ']' 572 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); } 573 | '[' push assignment_expression pop ']' 574 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), $3 ); } 575 | '[' push ',' tuple_expression_list pop ']' 576 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(new NullExprNode)->set_link( $4 ) ); } 577 | '[' push assignment_expression ',' tuple_expression_list pop ']' 578 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 ) ) ); } 579 ; 567 // CFA, one assignment_expression is factored out of comma_expression to eliminate a shift/reduce 568 // conflict with comma_expression in new_identifier_parameter_array and new_abstract_array 569 '[' push pop ']' 570 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); } 571 | '[' push assignment_expression pop ']' 572 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), $3 ); } 573 | '[' push ',' tuple_expression_list pop ']' 574 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(new NullExprNode)->set_link( $4 ) ); } 575 | '[' push assignment_expression ',' tuple_expression_list pop ']' 576 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 ) ) ); } 577 ; 580 578 581 579 tuple_expression_list: 582 assignment_expression_opt583 | tuple_expression_list ',' assignment_expression_opt584 { $$ = (ExpressionNode *)$1->set_link( $3 ); }585 ;580 assignment_expression_opt 581 | tuple_expression_list ',' assignment_expression_opt 582 { $$ = (ExpressionNode *)$1->set_link( $3 ); } 583 ; 586 584 587 585 assignment_operator: 588 MULTassign{ $$ = new OperatorNode(OperatorNode::MulAssn); }589 | DIVassign{ $$ = new OperatorNode(OperatorNode::DivAssn); }590 | MODassign{ $$ = new OperatorNode(OperatorNode::ModAssn); }591 | PLUSassign{ $$ = new OperatorNode(OperatorNode::PlusAssn); }592 | MINUSassign{ $$ = new OperatorNode(OperatorNode::MinusAssn); }593 | LSassign{ $$ = new OperatorNode(OperatorNode::LSAssn); }594 | RSassign{ $$ = new OperatorNode(OperatorNode::RSAssn); }595 | ANDassign{ $$ = new OperatorNode(OperatorNode::AndAssn); }596 | ERassign{ $$ = new OperatorNode(OperatorNode::ERAssn); }597 | ORassign{ $$ = new OperatorNode(OperatorNode::OrAssn); }598 ;586 MULTassign { $$ = new OperatorNode(OperatorNode::MulAssn); } 587 | DIVassign { $$ = new OperatorNode(OperatorNode::DivAssn); } 588 | MODassign { $$ = new OperatorNode(OperatorNode::ModAssn); } 589 | PLUSassign { $$ = new OperatorNode(OperatorNode::PlusAssn); } 590 | MINUSassign { $$ = new OperatorNode(OperatorNode::MinusAssn); } 591 | LSassign { $$ = new OperatorNode(OperatorNode::LSAssn); } 592 | RSassign { $$ = new OperatorNode(OperatorNode::RSAssn); } 593 | ANDassign { $$ = new OperatorNode(OperatorNode::AndAssn); } 594 | ERassign { $$ = new OperatorNode(OperatorNode::ERAssn); } 595 | ORassign { $$ = new OperatorNode(OperatorNode::OrAssn); } 596 ; 599 597 600 598 comma_expression: 601 assignment_expression602 | comma_expression ',' assignment_expression // { $$ = (ExpressionNode *)$1->add_to_list($3); }603 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); }604 ;599 assignment_expression 600 | comma_expression ',' assignment_expression // { $$ = (ExpressionNode *)$1->add_to_list($3); } 601 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); } 602 ; 605 603 606 604 comma_expression_opt: 607 // empty608 { $$ = 0; }609 | comma_expression610 ;605 // empty 606 { $$ = 0; } 607 | comma_expression 608 ; 611 609 612 610 //*************************** STATEMENTS ******************************* 613 611 614 612 statement: 615 labeled_statement616 | compound_statement617 | expression_statement{ $$ = $1; }618 | selection_statement619 | iteration_statement620 | jump_statement621 | exception_statement622 | asm_statement623 ;613 labeled_statement 614 | compound_statement 615 | expression_statement { $$ = $1; } 616 | selection_statement 617 | iteration_statement 618 | jump_statement 619 | exception_statement 620 | asm_statement 621 ; 624 622 625 623 labeled_statement: 626 no_attr_identifier ':' attribute_list_opt statement627 { $$ = $4->add_label($1);}628 ;624 no_attr_identifier ':' attribute_list_opt statement 625 { $$ = $4->add_label($1);} 626 ; 629 627 630 628 compound_statement: 631 '{' '}'632 { $$ = new CompoundStmtNode( (StatementNode *)0 ); }633 | '{'634 // Two scopes are necessary because the block itself has a scope, but every declaration within635 // theblock also requires its own scope636 push push637 label_declaration_opt// GCC, local labels638 block_item_list pop '}'// C99, intermix declarations and statements639 { $$ = new CompoundStmtNode( $5 ); }640 ;629 '{' '}' 630 { $$ = new CompoundStmtNode( (StatementNode *)0 ); } 631 | '{' 632 // Two scopes are necessary because the block itself has a scope, but every declaration within the 633 // block also requires its own scope 634 push push 635 label_declaration_opt // GCC, local labels 636 block_item_list pop '}' // C99, intermix declarations and statements 637 { $$ = new CompoundStmtNode( $5 ); } 638 ; 641 639 642 640 block_item_list: // C99 643 block_item644 | block_item_list push block_item645 { if ($1 != 0) { $1->set_link($3); $$ = $1; } }646 ;641 block_item 642 | block_item_list push block_item 643 { if ($1 != 0) { $1->set_link($3); $$ = $1; } } 644 ; 647 645 648 646 block_item: 649 declaration // CFA, new & old style declarations 650 { $$ = new StatementNode( $1 ); } 651 | EXTENSION declaration // GCC 652 { $$ = new StatementNode( $2 ); } 653 | statement pop 654 ; 647 declaration // CFA, new & old style declarations 648 { $$ = new StatementNode( $1 ); } 649 | EXTENSION declaration // GCC 650 { $$ = new StatementNode( $2 ); } 651 | function_definition 652 { $$ = new StatementNode( $1 ); } 653 | statement pop 654 ; 655 655 656 656 statement_list: 657 statement658 | statement_list statement659 { if ($1 != 0) { $1->set_link($2); $$ = $1; } }660 ;657 statement 658 | statement_list statement 659 { if ($1 != 0) { $1->set_link($2); $$ = $1; } } 660 ; 661 661 662 662 expression_statement: 663 comma_expression_opt ';'664 { $$ = new StatementNode(StatementNode::Exp, $1, 0); }665 ;663 comma_expression_opt ';' 664 { $$ = new StatementNode(StatementNode::Exp, $1, 0); } 665 ; 666 666 667 667 selection_statement: 668 IF '(' comma_expression ')' statement %prec THEN669 // explicitly deal with the shift/reduce conflict on if/else670 { $$ = new StatementNode(StatementNode::If, $3, $5); }671 | IF '(' comma_expression ')' statement ELSE statement672 { $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); }673 | SWITCH '(' comma_expression ')' case_clause// CFA674 { $$ = new StatementNode(StatementNode::Switch, $3, $5); }675 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA676 { $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ }677 // The semantics of the declaration list is changed to include any associated initialization,678 // which is performed *before* the transfer to the appropriate case clause. Statements after679 // the initial declaration list can never be executed, and therefore, are removed from the680 // grammar even though Callows it.681 | CHOOSE '(' comma_expression ')' case_clause// CFA682 { $$ = new StatementNode(StatementNode::Choose, $3, $5); }683 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA684 { $$ = new StatementNode(StatementNode::Choose, $3, $8); }685 ;668 IF '(' comma_expression ')' statement %prec THEN 669 // explicitly deal with the shift/reduce conflict on if/else 670 { $$ = new StatementNode(StatementNode::If, $3, $5); } 671 | IF '(' comma_expression ')' statement ELSE statement 672 { $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); } 673 | SWITCH '(' comma_expression ')' case_clause // CFA 674 { $$ = new StatementNode(StatementNode::Switch, $3, $5); } 675 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA 676 { $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ } 677 // The semantics of the declaration list is changed to include any associated initialization, which is 678 // performed *before* the transfer to the appropriate case clause. Statements after the initial 679 // declaration list can never be executed, and therefore, are removed from the grammar even though C 680 // allows it. 681 | CHOOSE '(' comma_expression ')' case_clause // CFA 682 { $$ = new StatementNode(StatementNode::Choose, $3, $5); } 683 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA 684 { $$ = new StatementNode(StatementNode::Choose, $3, $8); } 685 ; 686 686 687 687 // CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a … … 689 689 690 690 case_value: // CFA 691 constant_expression{ $$ = $1; }692 | constant_expression ELLIPSIS constant_expression// GCC, subrange693 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); }694 | subrange// CFA, subrange695 ;691 constant_expression { $$ = $1; } 692 | constant_expression ELLIPSIS constant_expression // GCC, subrange 693 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); } 694 | subrange // CFA, subrange 695 ; 696 696 697 697 case_value_list: // CFA 698 case_value699 | case_value_list ',' case_value700 { $$ = new CompositeExprNode(new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(tupleContents($1))->set_link($3) ); }701 ;698 case_value 699 | case_value_list ',' case_value 700 { $$ = new CompositeExprNode(new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(tupleContents($1))->set_link($3) ); } 701 ; 702 702 703 703 case_label: // CFA 704 CASE case_value_list ':'{ $$ = new StatementNode(StatementNode::Case, $2, 0); }705 | DEFAULT ':'{ $$ = new StatementNode(StatementNode::Default); }706 // A semantic check is required to ensure only one default clause per switch/choose statement.707 ;704 CASE case_value_list ':' { $$ = new StatementNode(StatementNode::Case, $2, 0); } 705 | DEFAULT ':' { $$ = new StatementNode(StatementNode::Default); } 706 // A semantic check is required to ensure only one default clause per switch/choose statement. 707 ; 708 708 709 709 case_label_list: // CFA 710 case_label711 | case_label_list case_label{ $$ = (StatementNode *)($1->set_link($2)); }712 ;710 case_label 711 | case_label_list case_label { $$ = (StatementNode *)($1->set_link($2)); } 712 ; 713 713 714 714 case_clause: // CFA 715 case_label_list statement{ $$ = $1->append_last_case($2); }716 ;715 case_label_list statement { $$ = $1->append_last_case($2); } 716 ; 717 717 718 718 switch_clause_list_opt: // CFA 719 // empty720 { $$ = 0; }721 | switch_clause_list722 ;719 // empty 720 { $$ = 0; } 721 | switch_clause_list 722 ; 723 723 724 724 switch_clause_list: // CFA 725 case_label_list statement_list726 { $$ = $1->append_last_case($2); }727 | switch_clause_list case_label_list statement_list728 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }729 ;725 case_label_list statement_list 726 { $$ = $1->append_last_case($2); } 727 | switch_clause_list case_label_list statement_list 728 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); } 729 ; 730 730 731 731 choose_clause_list_opt: // CFA 732 // empty733 { $$ = 0; }734 | choose_clause_list735 ;732 // empty 733 { $$ = 0; } 734 | choose_clause_list 735 ; 736 736 737 737 choose_clause_list: // CFA 738 case_label_list fall_through739 { $$ = $1->append_last_case($2); }740 | case_label_list statement_list fall_through_opt741 { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); }742 | choose_clause_list case_label_list fall_through743 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }744 | choose_clause_list case_label_list statement_list fall_through_opt745 { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); }746 ;738 case_label_list fall_through 739 { $$ = $1->append_last_case($2); } 740 | case_label_list statement_list fall_through_opt 741 { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); } 742 | choose_clause_list case_label_list fall_through 743 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); } 744 | choose_clause_list case_label_list statement_list fall_through_opt 745 { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); } 746 ; 747 747 748 748 fall_through_opt: // CFA 749 // empty750 { $$ = 0; }751 | fall_through752 ;749 // empty 750 { $$ = 0; } 751 | fall_through 752 ; 753 753 754 754 fall_through: // CFA 755 FALLTHRU{ $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }756 | FALLTHRU ';'{ $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }757 ;755 FALLTHRU { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); } 756 | FALLTHRU ';' { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); } 757 ; 758 758 759 759 iteration_statement: 760 WHILE '(' comma_expression ')' statement761 { $$ = new StatementNode(StatementNode::While, $3, $5); }762 | DO statement WHILE '(' comma_expression ')' ';'763 { $$ = new StatementNode(StatementNode::Do, $5, $2); }764 | FOR '(' push for_control_expression ')' statement765 { $$ = new StatementNode(StatementNode::For, $4, $6); }766 ;760 WHILE '(' comma_expression ')' statement 761 { $$ = new StatementNode(StatementNode::While, $3, $5); } 762 | DO statement WHILE '(' comma_expression ')' ';' 763 { $$ = new StatementNode(StatementNode::Do, $5, $2); } 764 | FOR '(' push for_control_expression ')' statement 765 { $$ = new StatementNode(StatementNode::For, $4, $6); } 766 ; 767 767 768 768 for_control_expression: 769 comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt770 { $$ = new ForCtlExprNode($1, $4, $6); }771 | declaration comma_expression_opt ';' comma_expression_opt // C99772 // Like C++, the loop index can be declared local to the loop.773 { $$ = new ForCtlExprNode($1, $2, $4); }774 ;769 comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt 770 { $$ = new ForCtlExprNode($1, $4, $6); } 771 | declaration comma_expression_opt ';' comma_expression_opt // C99 772 // Like C++, the loop index can be declared local to the loop. 773 { $$ = new ForCtlExprNode($1, $2, $4); } 774 ; 775 775 776 776 jump_statement: 777 GOTO no_attr_identifier ';' 778 { $$ = new StatementNode(StatementNode::Goto, $2); } 779 | GOTO '*' comma_expression ';' // GCC, computed goto 780 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto 781 // *i+3; => goto *(i+3); whereas normal operator precedence yields goto (*i)+3; 782 { $$ = new StatementNode(StatementNode::Goto, $3); } 783 | CONTINUE ';' 784 // A semantic check is required to ensure this statement appears only in the body of an 785 // iteration statement. 786 { $$ = new StatementNode(StatementNode::Continue, 0, 0); } 787 | CONTINUE no_attr_identifier ';' // CFA, multi-level continue 788 // A semantic check is required to ensure this statement appears only in the body of an 789 // iteration statement, and the target of the transfer appears only at the start of an 790 // iteration statement. 791 { $$ = new StatementNode(StatementNode::Continue, $2); } 792 | BREAK ';' 793 // A semantic check is required to ensure this statement appears only in the body of an 794 // iteration statement. 795 { $$ = new StatementNode(StatementNode::Break, 0, 0); } 796 | BREAK no_attr_identifier ';' // CFA, multi-level exit 797 // A semantic check is required to ensure this statement appears only in the body of an 798 // iteration statement, and the target of the transfer appears only at the start of an 799 // iteration statement. 800 { $$ = new StatementNode(StatementNode::Break, $2 ); } 801 | RETURN comma_expression_opt ';' 802 { $$ = new StatementNode(StatementNode::Return, $2, 0); } 803 | THROW assignment_expression ';' 804 { $$ = new StatementNode(StatementNode::Throw, $2, 0); } 805 | THROW ';' 806 { $$ = new StatementNode(StatementNode::Throw, 0, 0); } 807 ; 777 GOTO no_attr_identifier ';' 778 { $$ = new StatementNode(StatementNode::Goto, $2); } 779 | GOTO '*' comma_expression ';' // GCC, computed goto 780 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => 781 // goto *(i+3); whereas normal operator precedence yields goto (*i)+3; 782 { $$ = new StatementNode(StatementNode::Goto, $3); } 783 | CONTINUE ';' 784 // A semantic check is required to ensure this statement appears only in the body of an iteration 785 // statement. 786 { $$ = new StatementNode(StatementNode::Continue, 0, 0); } 787 | CONTINUE no_attr_identifier ';' // CFA, multi-level continue 788 // A semantic check is required to ensure this statement appears only in the body of an iteration 789 // statement, and the target of the transfer appears only at the start of an iteration statement. 790 { $$ = new StatementNode(StatementNode::Continue, $2); } 791 | BREAK ';' 792 // A semantic check is required to ensure this statement appears only in the body of an iteration 793 // statement. 794 { $$ = new StatementNode(StatementNode::Break, 0, 0); } 795 | BREAK no_attr_identifier ';' // CFA, multi-level exit 796 // A semantic check is required to ensure this statement appears only in the body of an iteration 797 // statement, and the target of the transfer appears only at the start of an iteration statement. 798 { $$ = new StatementNode(StatementNode::Break, $2 ); } 799 | RETURN comma_expression_opt ';' 800 { $$ = new StatementNode(StatementNode::Return, $2, 0); } 801 | THROW assignment_expression ';' 802 { $$ = new StatementNode(StatementNode::Throw, $2, 0); } 803 | THROW ';' 804 { $$ = new StatementNode(StatementNode::Throw, 0, 0); } 805 ; 808 806 809 807 exception_statement: 810 TRY compound_statement handler_list811 { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }812 | TRY compound_statement finally_clause813 { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }814 | TRY compound_statement handler_list finally_clause815 {816 $3->set_link($4);817 $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3))));818 }819 ;808 TRY compound_statement handler_list 809 { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); } 810 | TRY compound_statement finally_clause 811 { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); } 812 | TRY compound_statement handler_list finally_clause 813 { 814 $3->set_link($4); 815 $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); 816 } 817 ; 820 818 821 819 handler_list: 822 // There must be at least one catch clause823 handler_clause824 // ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for825 // its tryblock.826 | CATCH '(' ELLIPSIS ')' compound_statement827 { $$ = StatementNode::newCatchStmt( 0, $5, true ); }828 | handler_clause CATCH '(' ELLIPSIS ')' compound_statement829 { $$ = $1->set_link( StatementNode::newCatchStmt( 0, $6, true ) ); }830 ;820 // There must be at least one catch clause 821 handler_clause 822 // ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for its try 823 // block. 824 | CATCH '(' ELLIPSIS ')' compound_statement 825 { $$ = StatementNode::newCatchStmt( 0, $5, true ); } 826 | handler_clause CATCH '(' ELLIPSIS ')' compound_statement 827 { $$ = $1->set_link( StatementNode::newCatchStmt( 0, $6, true ) ); } 828 ; 831 829 832 830 handler_clause: 833 CATCH '(' push push exception_declaration pop ')' compound_statement pop834 { $$ = StatementNode::newCatchStmt($5, $8); }835 | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop836 { $$ = $1->set_link( StatementNode::newCatchStmt($6, $9) ); }837 ;831 CATCH '(' push push exception_declaration pop ')' compound_statement pop 832 { $$ = StatementNode::newCatchStmt($5, $8); } 833 | handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop 834 { $$ = $1->set_link( StatementNode::newCatchStmt($6, $9) ); } 835 ; 838 836 839 837 finally_clause: 840 FINALLY compound_statement 841 { $$ = new StatementNode(StatementNode::Finally, 0, $2); 842 std::cout << "Just created a finally node" << std::endl; 843 } 844 ; 838 FINALLY compound_statement 839 { 840 $$ = new StatementNode(StatementNode::Finally, 0, $2); 841 std::cout << "Just created a finally node" << std::endl; 842 } 843 ; 845 844 846 845 exception_declaration: 847 // A semantic check is required to ensure type_specifier does not create a new type, e.g.:848 //849 // catch ( struct { int i; } x ) ...850 //851 // This new type cannot catch any thrown type because of name equivalence among types.852 type_specifier853 | type_specifier declarator854 {855 typedefTable.addToEnclosingScope( TypedefTable::ID );856 $$ = $2->addType( $1 );857 }858 | type_specifier variable_abstract_declarator859 { $$ = $2->addType( $1 ); }860 | new_abstract_declarator_tuple no_attr_identifier// CFA861 {862 typedefTable.addToEnclosingScope( TypedefTable::ID );863 $$ = $1->addName( $2 );864 }865 | new_abstract_declarator_tuple// CFA866 ;846 // A semantic check is required to ensure type_specifier does not create a new type, e.g.: 847 // 848 // catch ( struct { int i; } x ) ... 849 // 850 // This new type cannot catch any thrown type because of name equivalence among types. 851 type_specifier 852 | type_specifier declarator 853 { 854 typedefTable.addToEnclosingScope( TypedefTable::ID ); 855 $$ = $2->addType( $1 ); 856 } 857 | type_specifier variable_abstract_declarator 858 { $$ = $2->addType( $1 ); } 859 | new_abstract_declarator_tuple no_attr_identifier // CFA 860 { 861 typedefTable.addToEnclosingScope( TypedefTable::ID ); 862 $$ = $1->addName( $2 ); 863 } 864 | new_abstract_declarator_tuple // CFA 865 ; 867 866 868 867 asm_statement: 869 ASM type_qualifier_list_opt '(' constant_expression ')' ';' 870 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 871 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' // remaining GCC 872 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 873 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';' 874 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 875 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ':' 876 asm_clobbers_list ')' ';' 877 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 878 ; 868 ASM type_qualifier_list_opt '(' constant_expression ')' ';' 869 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 870 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' // remaining GCC 871 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 872 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';' 873 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 874 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list ')' ';' 875 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 876 ; 879 877 880 878 asm_operands_opt: // GCC 881 // empty882 | asm_operands_list883 ;879 // empty 880 | asm_operands_list 881 ; 884 882 885 883 asm_operands_list: // GCC 886 asm_operand887 | asm_operands_list ',' asm_operand888 ;884 asm_operand 885 | asm_operands_list ',' asm_operand 886 ; 889 887 890 888 asm_operand: // GCC 891 STRINGliteral '(' constant_expression ')' {}892 ;889 STRINGliteral '(' constant_expression ')' {} 890 ; 893 891 894 892 asm_clobbers_list: // GCC 895 STRINGliteral{}896 | asm_clobbers_list ',' STRINGliteral897 ;893 STRINGliteral {} 894 | asm_clobbers_list ',' STRINGliteral 895 ; 898 896 899 897 //******************************* DECLARATIONS ********************************* 900 898 901 899 declaration_list_opt: // used at beginning of switch statement 902 pop903 { $$ = 0; }904 | declaration_list905 ;900 pop 901 { $$ = 0; } 902 | declaration_list 903 ; 906 904 907 905 declaration_list: 908 declaration909 | declaration_list push declaration910 { $$ = $1->appendList( $3 ); }911 ;906 declaration 907 | declaration_list push declaration 908 { $$ = $1->appendList( $3 ); } 909 ; 912 910 913 911 old_declaration_list_opt: // used to declare parameter types in K&R style functions 914 pop915 { $$ = 0; }916 | old_declaration_list917 ;912 pop 913 { $$ = 0; } 914 | old_declaration_list 915 ; 918 916 919 917 old_declaration_list: 920 old_declaration921 | old_declaration_list push old_declaration922 { $$ = $1->appendList( $3 ); }923 ;918 old_declaration 919 | old_declaration_list push old_declaration 920 { $$ = $1->appendList( $3 ); } 921 ; 924 922 925 923 label_declaration_opt: // GCC, local label 926 // empty927 | label_declaration_list928 ;924 // empty 925 | label_declaration_list 926 ; 929 927 930 928 label_declaration_list: // GCC, local label 931 LABEL label_list ';'932 | label_declaration_list LABEL label_list ';'933 ;929 LABEL label_list ';' 930 | label_declaration_list LABEL label_list ';' 931 ; 934 932 935 933 label_list: // GCC, local label 936 no_attr_identifier_or_typedef_name{}937 | label_list ',' no_attr_identifier_or_typedef_name {}938 ;934 no_attr_identifier_or_typedef_name {} 935 | label_list ',' no_attr_identifier_or_typedef_name {} 936 ; 939 937 940 938 declaration: // CFA, new & old style declarations 941 new_declaration942 | old_declaration943 ;939 new_declaration 940 | old_declaration 941 ; 944 942 945 943 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and … … 956 954 957 955 new_declaration: // CFA 958 new_variable_declaration pop ';'959 | new_typedef_declaration pop ';'960 | new_function_declaration pop ';'961 | type_declaring_list pop ';'962 | context_specifier pop ';'963 ;956 new_variable_declaration pop ';' 957 | new_typedef_declaration pop ';' 958 | new_function_declaration pop ';' 959 | type_declaring_list pop ';' 960 | context_specifier pop ';' 961 ; 964 962 965 963 new_variable_declaration: // CFA 966 new_variable_specifier initializer_opt967 {968 typedefTable.addToEnclosingScope( TypedefTable::ID );969 $$ = $1;970 }971 | declaration_qualifier_list new_variable_specifier initializer_opt972 // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is973 // necessary topreclude them as a type_qualifier cannot appear in that context.974 {975 typedefTable.addToEnclosingScope( TypedefTable::ID );976 $$ = $2->addQualifiers( $1 );977 }978 | new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt979 {980 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );981 $$ = $1->appendList( $1->cloneType( $5 ) );982 }983 ;964 new_variable_specifier initializer_opt 965 { 966 typedefTable.addToEnclosingScope( TypedefTable::ID ); 967 $$ = $1; 968 } 969 | declaration_qualifier_list new_variable_specifier initializer_opt 970 // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is necessary to 971 // preclude them as a type_qualifier cannot appear in that context. 972 { 973 typedefTable.addToEnclosingScope( TypedefTable::ID ); 974 $$ = $2->addQualifiers( $1 ); 975 } 976 | new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt 977 { 978 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID ); 979 $$ = $1->appendList( $1->cloneType( $5 ) ); 980 } 981 ; 984 982 985 983 new_variable_specifier: // CFA 986 // A semantic check is required to ensure asm_name only appears on declarations with implicit987 // orexplicit static storage-class988 new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt989 {990 typedefTable.setNextIdentifier( *$2 );991 $$ = $1->addName( $2 );992 }993 | new_abstract_tuple identifier_or_typedef_name asm_name_opt994 {995 typedefTable.setNextIdentifier( *$2 );996 $$ = $1->addName( $2 );997 }998 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name asm_name_opt999 {1000 typedefTable.setNextIdentifier( *$3 );1001 $$ = $2->addQualifiers( $1 )->addName( $3 );1002 }1003 ;984 // A semantic check is required to ensure asm_name only appears on declarations with implicit or 985 // explicit static storage-class 986 new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt 987 { 988 typedefTable.setNextIdentifier( *$2 ); 989 $$ = $1->addName( $2 ); 990 } 991 | new_abstract_tuple identifier_or_typedef_name asm_name_opt 992 { 993 typedefTable.setNextIdentifier( *$2 ); 994 $$ = $1->addName( $2 ); 995 } 996 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name asm_name_opt 997 { 998 typedefTable.setNextIdentifier( *$3 ); 999 $$ = $2->addQualifiers( $1 )->addName( $3 ); 1000 } 1001 ; 1004 1002 1005 1003 new_function_declaration: // CFA 1006 new_function_specifier1007 {1008 typedefTable.addToEnclosingScope( TypedefTable::ID );1009 $$ = $1;1010 }1011 | type_qualifier_list new_function_specifier1012 {1013 typedefTable.addToEnclosingScope( TypedefTable::ID );1014 $$ = $2->addQualifiers( $1 );1015 }1016 | declaration_qualifier_list new_function_specifier1017 {1018 typedefTable.addToEnclosingScope( TypedefTable::ID );1019 $$ = $2->addQualifiers( $1 );1020 }1021 | declaration_qualifier_list type_qualifier_list new_function_specifier1022 {1023 typedefTable.addToEnclosingScope( TypedefTable::ID );1024 $$ = $3->addQualifiers( $1 )->addQualifiers( $2 );1025 }1026 | new_function_declaration pop ',' push identifier_or_typedef_name1027 {1028 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );1029 $$ = $1->appendList( $1->cloneType( $5 ) );1030 }1031 ;1004 new_function_specifier 1005 { 1006 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1007 $$ = $1; 1008 } 1009 | type_qualifier_list new_function_specifier 1010 { 1011 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1012 $$ = $2->addQualifiers( $1 ); 1013 } 1014 | declaration_qualifier_list new_function_specifier 1015 { 1016 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1017 $$ = $2->addQualifiers( $1 ); 1018 } 1019 | declaration_qualifier_list type_qualifier_list new_function_specifier 1020 { 1021 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1022 $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); 1023 } 1024 | new_function_declaration pop ',' push identifier_or_typedef_name 1025 { 1026 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID ); 1027 $$ = $1->appendList( $1->cloneType( $5 ) ); 1028 } 1029 ; 1032 1030 1033 1031 new_function_specifier: // CFA 1034 '[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')'1035 {1036 typedefTable.setNextIdentifier( *($5) );1037 $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );1038 }1039 | '[' push pop ']' TYPEDEFname '(' push new_parameter_type_list_opt pop ')'1040 {1041 typedefTable.setNextIdentifier( *($5) );1042 $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );1043 }1044 // identifier_or_typedef_name must be broken apart because of the sequence:1045 //1046 // '[' ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'1047 // '[' ']' type_specifier1048 //1049 // type_specifier can resolve to just TYPEDEFname (e.g. typedef int T; int f( T );). Therefore1050 // thismust be flattened to allow lookahead to the '(' without having to reduce1051 // identifier_or_typedef_name.1052 | new_abstract_tuple identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'1053 // To obtain LR(1), this rule must be factored out from function return type (see1054 // new_abstract_declarator).1055 {1056 $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );1057 }1058 | new_function_return identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'1059 {1060 $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );1061 }1062 ;1032 '[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')' 1033 { 1034 typedefTable.setNextIdentifier( *($5) ); 1035 $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1036 } 1037 | '[' push pop ']' TYPEDEFname '(' push new_parameter_type_list_opt pop ')' 1038 { 1039 typedefTable.setNextIdentifier( *($5) ); 1040 $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true ); 1041 } 1042 // identifier_or_typedef_name must be broken apart because of the sequence: 1043 // 1044 // '[' ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')' 1045 // '[' ']' type_specifier 1046 // 1047 // type_specifier can resolve to just TYPEDEFname (e.g. typedef int T; int f( T );). Therefore this 1048 // must be flattened to allow lookahead to the '(' without having to reduce 1049 // identifier_or_typedef_name. 1050 | new_abstract_tuple identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')' 1051 // To obtain LR(1), this rule must be factored out from function return type (see 1052 // new_abstract_declarator). 1053 { 1054 $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true ); 1055 } 1056 | new_function_return identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')' 1057 { 1058 $$ = DeclarationNode::newFunction( $2, $1, $5, 0, true ); 1059 } 1060 ; 1063 1061 1064 1062 new_function_return: // CFA 1065 '[' push new_parameter_list pop ']'1066 { $$ = DeclarationNode::newTuple( $3 ); }1067 | '[' push new_parameter_list pop ',' push new_abstract_parameter_list pop ']'1068 // To obtain LR(1), the last new_abstract_parameter_list is added into this flattened rule to1069 // lookahead to the ']'.1070 { $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }1071 ;1063 '[' push new_parameter_list pop ']' 1064 { $$ = DeclarationNode::newTuple( $3 ); } 1065 | '[' push new_parameter_list pop ',' push new_abstract_parameter_list pop ']' 1066 // To obtain LR(1), the last new_abstract_parameter_list is added into this flattened rule to 1067 // lookahead to the ']'. 1068 { $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); } 1069 ; 1072 1070 1073 1071 new_typedef_declaration: // CFA 1074 TYPEDEF new_variable_specifier1075 {1076 typedefTable.addToEnclosingScope( TypedefTable::TD);1077 $$ = $2->addTypedef();1078 }1079 | TYPEDEF new_function_specifier1080 {1081 typedefTable.addToEnclosingScope( TypedefTable::TD);1082 $$ = $2->addTypedef();1083 }1084 | new_typedef_declaration pop ',' push no_attr_identifier1085 {1086 typedefTable.addToEnclosingScope( *$5, TypedefTable::TD);1087 $$ = $1->appendList( $1->cloneType( $5 ) );1088 }1089 ;1072 TYPEDEF new_variable_specifier 1073 { 1074 typedefTable.addToEnclosingScope( TypedefTable::TD); 1075 $$ = $2->addTypedef(); 1076 } 1077 | TYPEDEF new_function_specifier 1078 { 1079 typedefTable.addToEnclosingScope( TypedefTable::TD); 1080 $$ = $2->addTypedef(); 1081 } 1082 | new_typedef_declaration pop ',' push no_attr_identifier 1083 { 1084 typedefTable.addToEnclosingScope( *$5, TypedefTable::TD); 1085 $$ = $1->appendList( $1->cloneType( $5 ) ); 1086 } 1087 ; 1090 1088 1091 1089 // Traditionally typedef is part of storage-class specifier for syntactic convenience only. Here, it is … … 1094 1092 1095 1093 typedef_declaration: 1096 TYPEDEF type_specifier declarator1097 {1098 typedefTable.addToEnclosingScope( TypedefTable::TD);1099 $$ = $3->addType( $2 )->addTypedef();1100 }1101 | typedef_declaration pop ',' push declarator1102 {1103 typedefTable.addToEnclosingScope( TypedefTable::TD);1104 $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );1105 }1106 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2)1107 {1108 typedefTable.addToEnclosingScope( TypedefTable::TD);1109 $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();1110 }1111 | type_specifier TYPEDEF declarator1112 {1113 typedefTable.addToEnclosingScope( TypedefTable::TD);1114 $$ = $3->addType( $1 )->addTypedef();1115 }1116 | type_specifier TYPEDEF type_qualifier_list declarator1117 {1118 typedefTable.addToEnclosingScope( TypedefTable::TD);1119 $$ = $4->addQualifiers($1)->addTypedef()->addType($1);1120 }1121 ;1094 TYPEDEF type_specifier declarator 1095 { 1096 typedefTable.addToEnclosingScope( TypedefTable::TD); 1097 $$ = $3->addType( $2 )->addTypedef(); 1098 } 1099 | typedef_declaration pop ',' push declarator 1100 { 1101 typedefTable.addToEnclosingScope( TypedefTable::TD); 1102 $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() ); 1103 } 1104 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2) 1105 { 1106 typedefTable.addToEnclosingScope( TypedefTable::TD); 1107 $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef(); 1108 } 1109 | type_specifier TYPEDEF declarator 1110 { 1111 typedefTable.addToEnclosingScope( TypedefTable::TD); 1112 $$ = $3->addType( $1 )->addTypedef(); 1113 } 1114 | type_specifier TYPEDEF type_qualifier_list declarator 1115 { 1116 typedefTable.addToEnclosingScope( TypedefTable::TD); 1117 $$ = $4->addQualifiers($1)->addTypedef()->addType($1); 1118 } 1119 ; 1122 1120 1123 1121 typedef_expression: // GCC, naming expression type 1124 TYPEDEF no_attr_identifier '=' assignment_expression1125 {1126 typedefTable.addToEnclosingScope(*($2), TypedefTable::TD);1127 $$ = DeclarationNode::newName( 0 ); // XXX1128 }1129 | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression1130 {1131 typedefTable.addToEnclosingScope(*($5), TypedefTable::TD);1132 $$ = DeclarationNode::newName( 0 ); // XXX1133 }1134 ;1122 TYPEDEF no_attr_identifier '=' assignment_expression 1123 { 1124 typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); 1125 $$ = DeclarationNode::newName( 0 ); // XXX 1126 } 1127 | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression 1128 { 1129 typedefTable.addToEnclosingScope(*($5), TypedefTable::TD); 1130 $$ = DeclarationNode::newName( 0 ); // XXX 1131 } 1132 ; 1135 1133 1136 1134 old_declaration: 1137 declaring_list pop ';'1138 | typedef_declaration pop ';'1139 | typedef_expression pop ';'// GCC, naming expression type1140 | sue_declaration_specifier pop ';'1141 ;1135 declaring_list pop ';' 1136 | typedef_declaration pop ';' 1137 | typedef_expression pop ';' // GCC, naming expression type 1138 | sue_declaration_specifier pop ';' 1139 ; 1142 1140 1143 1141 declaring_list: 1144 // A semantic check is required to ensure asm_name only appears on declarations with implicit1145 // orexplicit static storage-class1146 declaration_specifier declarator asm_name_opt initializer_opt1147 {1148 typedefTable.addToEnclosingScope( TypedefTable::ID );1149 $$ = ($2->addType( $1 ))->addInitializer($4);1150 }1151 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt1152 {1153 typedefTable.addToEnclosingScope( TypedefTable::ID );1154 $$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) );1155 }1156 ;1142 // A semantic check is required to ensure asm_name only appears on declarations with implicit or 1143 // explicit static storage-class 1144 declaration_specifier declarator asm_name_opt initializer_opt 1145 { 1146 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1147 $$ = ($2->addType( $1 ))->addInitializer($4); 1148 } 1149 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 1150 { 1151 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1152 $$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) ); 1153 } 1154 ; 1157 1155 1158 1156 declaration_specifier: // type specifier + storage class 1159 basic_declaration_specifier1160 | sue_declaration_specifier1161 | typedef_declaration_specifier1162 | typegen_declaration_specifier1163 ;1157 basic_declaration_specifier 1158 | sue_declaration_specifier 1159 | typedef_declaration_specifier 1160 | typegen_declaration_specifier 1161 ; 1164 1162 1165 1163 type_specifier: // declaration specifier - storage class 1166 basic_type_specifier1167 | sue_type_specifier1168 | typedef_type_specifier1169 | typegen_type_specifier1170 ;1164 basic_type_specifier 1165 | sue_type_specifier 1166 | typedef_type_specifier 1167 | typegen_type_specifier 1168 ; 1171 1169 1172 1170 type_qualifier_list_opt: // GCC, used in asm_statement 1173 // empty1174 { $$ = 0; }1175 | type_qualifier_list1176 ;1171 // empty 1172 { $$ = 0; } 1173 | type_qualifier_list 1174 ; 1177 1175 1178 1176 type_qualifier_list: 1179 // A semantic check is necessary to ensure a type qualifier is appropriate for the kind of1180 // declaration.1181 //1182 // ISO/IEC 9899:1999 Section 6.7.3(4) : If the same qualifier appears more than once in the1183 // same specifier-qualifier-list, either directly or via one or more typedefs, the behavior is1184 // the same asif it appeared only once.1185 type_qualifier1186 | type_qualifier_list type_qualifier1187 { $$ = $1->addQualifiers( $2 ); }1188 ;1177 // A semantic check is necessary to ensure a type qualifier is appropriate for the kind of 1178 // declaration. 1179 // 1180 // ISO/IEC 9899:1999 Section 6.7.3(4) : If the same qualifier appears more than once in the same 1181 // specifier-qualifier-list, either directly or via one or more typedefs, the behavior is the same as 1182 // if it appeared only once. 1183 type_qualifier 1184 | type_qualifier_list type_qualifier 1185 { $$ = $1->addQualifiers( $2 ); } 1186 ; 1189 1187 1190 1188 type_qualifier: 1191 type_qualifier_name1192 | attribute1193 { $$ = DeclarationNode::newQualifier( DeclarationNode::Attribute ); }1194 ;1189 type_qualifier_name 1190 | attribute 1191 { $$ = DeclarationNode::newQualifier( DeclarationNode::Attribute ); } 1192 ; 1195 1193 1196 1194 type_qualifier_name: 1197 CONST1198 { $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); }1199 | RESTRICT1200 { $$ = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }1201 | VOLATILE1202 { $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }1203 | LVALUE// CFA1204 { $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }1205 | ATOMIC1206 { $$ = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }1207 | FORALL '('1208 {1209 typedefTable.enterScope();1210 }1211 type_parameter_list ')'// CFA1212 {1213 typedefTable.leaveScope();1214 $$ = DeclarationNode::newForall( $4 );1215 }1216 ;1195 CONST 1196 { $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); } 1197 | RESTRICT 1198 { $$ = DeclarationNode::newQualifier( DeclarationNode::Restrict ); } 1199 | VOLATILE 1200 { $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); } 1201 | LVALUE // CFA 1202 { $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); } 1203 | ATOMIC 1204 { $$ = DeclarationNode::newQualifier( DeclarationNode::Atomic ); } 1205 | FORALL '(' 1206 { 1207 typedefTable.enterScope(); 1208 } 1209 type_parameter_list ')' // CFA 1210 { 1211 typedefTable.leaveScope(); 1212 $$ = DeclarationNode::newForall( $4 ); 1213 } 1214 ; 1217 1215 1218 1216 declaration_qualifier_list: 1219 storage_class_list1220 | type_qualifier_list storage_class_list// remaining OBSOLESCENT (see 2)1221 { $$ = $1->addQualifiers( $2 ); }1222 | declaration_qualifier_list type_qualifier_list storage_class_list1223 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }1224 ;1217 storage_class_list 1218 | type_qualifier_list storage_class_list // remaining OBSOLESCENT (see 2) 1219 { $$ = $1->addQualifiers( $2 ); } 1220 | declaration_qualifier_list type_qualifier_list storage_class_list 1221 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); } 1222 ; 1225 1223 1226 1224 storage_class_list: 1227 // A semantic check is necessary to ensure a storage class is appropriate for the kind of 1228 // declaration and that only one of each is specified, except for inline, which can appear 1229 // with the others. 1230 // 1231 // ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in 1232 // the declaration specifiers in a declaration. 1233 storage_class 1234 | storage_class_list storage_class 1235 { $$ = $1->addQualifiers( $2 ); } 1236 ; 1225 // A semantic check is necessary to ensure a storage class is appropriate for the kind of declaration 1226 // and that only one of each is specified, except for inline, which can appear with the others. 1227 // 1228 // ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in the 1229 // declaration specifiers in a declaration. 1230 storage_class 1231 | storage_class_list storage_class 1232 { $$ = $1->addQualifiers( $2 ); } 1233 ; 1237 1234 1238 1235 storage_class: 1239 storage_class_name1240 ;1236 storage_class_name 1237 ; 1241 1238 1242 1239 storage_class_name: 1243 EXTERN1244 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }1245 | STATIC1246 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); }1247 | AUTO1248 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }1249 | REGISTER1250 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); }1251 | INLINE// C991252 // INLINE is essentially a storage class specifier for functions, and hence, belongs here.1253 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); }1254 | FORTRAN// C991255 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }1256 ;1240 EXTERN 1241 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); } 1242 | STATIC 1243 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); } 1244 | AUTO 1245 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); } 1246 | REGISTER 1247 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); } 1248 | INLINE // C99 1249 // INLINE is essentially a storage class specifier for functions, and hence, belongs here. 1250 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); } 1251 | FORTRAN // C99 1252 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); } 1253 ; 1257 1254 1258 1255 basic_type_name: 1259 CHAR1260 { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }1261 | DOUBLE1262 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }1263 | FLOAT1264 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }1265 | INT1266 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); }1267 | LONG1268 { $$ = DeclarationNode::newModifier( DeclarationNode::Long ); }1269 | SHORT1270 { $$ = DeclarationNode::newModifier( DeclarationNode::Short ); }1271 | SIGNED1272 { $$ = DeclarationNode::newModifier( DeclarationNode::Signed ); }1273 | UNSIGNED1274 { $$ = DeclarationNode::newModifier( DeclarationNode::Unsigned ); }1275 | VOID1276 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }1277 | BOOL// C991278 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); }1279 | COMPLEX// C991280 { $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); }1281 | IMAGINARY// C991282 { $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); }1283 ;1256 CHAR 1257 { $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); } 1258 | DOUBLE 1259 { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); } 1260 | FLOAT 1261 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); } 1262 | INT 1263 { $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); } 1264 | LONG 1265 { $$ = DeclarationNode::newModifier( DeclarationNode::Long ); } 1266 | SHORT 1267 { $$ = DeclarationNode::newModifier( DeclarationNode::Short ); } 1268 | SIGNED 1269 { $$ = DeclarationNode::newModifier( DeclarationNode::Signed ); } 1270 | UNSIGNED 1271 { $$ = DeclarationNode::newModifier( DeclarationNode::Unsigned ); } 1272 | VOID 1273 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 1274 | BOOL // C99 1275 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 1276 | COMPLEX // C99 1277 { $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); } 1278 | IMAGINARY // C99 1279 { $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); } 1280 ; 1284 1281 1285 1282 basic_declaration_specifier: 1286 // A semantic check is necessary for conflicting storage classes.1287 basic_type_specifier1288 | declaration_qualifier_list basic_type_specifier1289 { $$ = $2->addQualifiers( $1 ); }1290 | basic_declaration_specifier storage_class// remaining OBSOLESCENT (see 2)1291 { $$ = $1->addQualifiers( $2 ); }1292 | basic_declaration_specifier storage_class type_qualifier_list1293 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }1294 | basic_declaration_specifier storage_class basic_type_specifier1295 { $$ = $3->addQualifiers( $2 )->addType( $1 ); }1296 ;1283 // A semantic check is necessary for conflicting storage classes. 1284 basic_type_specifier 1285 | declaration_qualifier_list basic_type_specifier 1286 { $$ = $2->addQualifiers( $1 ); } 1287 | basic_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1288 { $$ = $1->addQualifiers( $2 ); } 1289 | basic_declaration_specifier storage_class type_qualifier_list 1290 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); } 1291 | basic_declaration_specifier storage_class basic_type_specifier 1292 { $$ = $3->addQualifiers( $2 )->addType( $1 ); } 1293 ; 1297 1294 1298 1295 basic_type_specifier: 1299 direct_type_name1300 | type_qualifier_list_opt indirect_type_name type_qualifier_list_opt1301 { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }1302 ;1296 direct_type_name 1297 | type_qualifier_list_opt indirect_type_name type_qualifier_list_opt 1298 { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); } 1299 ; 1303 1300 1304 1301 direct_type_name: 1305 // A semantic check is necessary for conflicting type qualifiers.1306 basic_type_name1307 | type_qualifier_list basic_type_name1308 { $$ = $2->addQualifiers( $1 ); }1309 | direct_type_name type_qualifier1310 { $$ = $1->addQualifiers( $2 ); }1311 | direct_type_name basic_type_name1312 { $$ = $1->addType( $2 ); }1313 ;1302 // A semantic check is necessary for conflicting type qualifiers. 1303 basic_type_name 1304 | type_qualifier_list basic_type_name 1305 { $$ = $2->addQualifiers( $1 ); } 1306 | direct_type_name type_qualifier 1307 { $$ = $1->addQualifiers( $2 ); } 1308 | direct_type_name basic_type_name 1309 { $$ = $1->addType( $2 ); } 1310 ; 1314 1311 1315 1312 indirect_type_name: 1316 TYPEOF '(' type_name ')'// GCC: typeof(x) y;1317 { $$ = $3; }1318 | TYPEOF '(' comma_expression ')'// GCC: typeof(a+b) y;1319 { $$ = DeclarationNode::newTypeof( $3 ); }1320 | ATTR_TYPEGENname '(' type_name ')'// CFA: e.g., @type(x) y;1321 { $$ = DeclarationNode::newAttr( $1, $3 ); }1322 | ATTR_TYPEGENname '(' comma_expression ')'// CFA: e.g., @type(a+b) y;1323 { $$ = DeclarationNode::newAttr( $1, $3 ); }1324 ;1313 TYPEOF '(' type_name ')' // GCC: typeof(x) y; 1314 { $$ = $3; } 1315 | TYPEOF '(' comma_expression ')' // GCC: typeof(a+b) y; 1316 { $$ = DeclarationNode::newTypeof( $3 ); } 1317 | ATTR_TYPEGENname '(' type_name ')' // CFA: e.g., @type(x) y; 1318 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1319 | ATTR_TYPEGENname '(' comma_expression ')' // CFA: e.g., @type(a+b) y; 1320 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1321 ; 1325 1322 1326 1323 sue_declaration_specifier: 1327 sue_type_specifier1328 | declaration_qualifier_list sue_type_specifier1329 { $$ = $2->addQualifiers( $1 ); }1330 | sue_declaration_specifier storage_class// remaining OBSOLESCENT (see 2)1331 { $$ = $1->addQualifiers( $2 ); }1332 | sue_declaration_specifier storage_class type_qualifier_list1333 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }1334 ;1324 sue_type_specifier 1325 | declaration_qualifier_list sue_type_specifier 1326 { $$ = $2->addQualifiers( $1 ); } 1327 | sue_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1328 { $$ = $1->addQualifiers( $2 ); } 1329 | sue_declaration_specifier storage_class type_qualifier_list 1330 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); } 1331 ; 1335 1332 1336 1333 sue_type_specifier: 1337 elaborated_type_name// struct, union, enum1338 | type_qualifier_list elaborated_type_name1339 { $$ = $2->addQualifiers( $1 ); }1340 | sue_type_specifier type_qualifier1341 { $$ = $1->addQualifiers( $2 ); }1342 ;1334 elaborated_type_name // struct, union, enum 1335 | type_qualifier_list elaborated_type_name 1336 { $$ = $2->addQualifiers( $1 ); } 1337 | sue_type_specifier type_qualifier 1338 { $$ = $1->addQualifiers( $2 ); } 1339 ; 1343 1340 1344 1341 typedef_declaration_specifier: 1345 typedef_type_specifier1346 | declaration_qualifier_list typedef_type_specifier1347 { $$ = $2->addQualifiers( $1 ); }1348 | typedef_declaration_specifier storage_class// remaining OBSOLESCENT (see 2)1349 { $$ = $1->addQualifiers( $2 ); }1350 | typedef_declaration_specifier storage_class type_qualifier_list1351 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }1352 ;1342 typedef_type_specifier 1343 | declaration_qualifier_list typedef_type_specifier 1344 { $$ = $2->addQualifiers( $1 ); } 1345 | typedef_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1346 { $$ = $1->addQualifiers( $2 ); } 1347 | typedef_declaration_specifier storage_class type_qualifier_list 1348 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); } 1349 ; 1353 1350 1354 1351 typedef_type_specifier: // typedef types 1355 TYPEDEFname1356 { $$ = DeclarationNode::newFromTypedef( $1 ); }1357 | type_qualifier_list TYPEDEFname1358 { $$ = DeclarationNode::newFromTypedef( $2 )->addQualifiers( $1 ); }1359 | typedef_type_specifier type_qualifier1360 { $$ = $1->addQualifiers( $2 ); }1361 ;1352 TYPEDEFname 1353 { $$ = DeclarationNode::newFromTypedef( $1 ); } 1354 | type_qualifier_list TYPEDEFname 1355 { $$ = DeclarationNode::newFromTypedef( $2 )->addQualifiers( $1 ); } 1356 | typedef_type_specifier type_qualifier 1357 { $$ = $1->addQualifiers( $2 ); } 1358 ; 1362 1359 1363 1360 elaborated_type_name: 1364 aggregate_name1365 | enum_name1366 ;1361 aggregate_name 1362 | enum_name 1363 ; 1367 1364 1368 1365 aggregate_name: 1369 aggregate_key '{' field_declaration_list '}'1370 { $$ = DeclarationNode::newAggregate( $1, 0, 0, 0, $3 ); }1371 | aggregate_key no_attr_identifier_or_typedef_name1372 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, 0 ); }1373 | aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}'1374 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); }1375 | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' // CFA1376 { $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); }1377 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name // CFA1378 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); }1379 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA1380 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); }1381 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' // CFA1382 { $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); }1383 | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name // CFA1384 // push and pop are only to prevent S/R conflicts1385 { $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); }1386 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA1387 { $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); }1388 ;1366 aggregate_key '{' field_declaration_list '}' 1367 { $$ = DeclarationNode::newAggregate( $1, 0, 0, 0, $3 ); } 1368 | aggregate_key no_attr_identifier_or_typedef_name 1369 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, 0 ); } 1370 | aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}' 1371 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); } 1372 | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' // CFA 1373 { $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); } 1374 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name // CFA 1375 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); } 1376 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA 1377 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); } 1378 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' // CFA 1379 { $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); } 1380 | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name // CFA 1381 // push and pop are only to prevent S/R conflicts 1382 { $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); } 1383 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA 1384 { $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); } 1385 ; 1389 1386 1390 1387 aggregate_key: 1391 STRUCT attribute_list_opt1392 { $$ = DeclarationNode::Struct; }1393 | UNION attribute_list_opt1394 { $$ = DeclarationNode::Union; }1395 ;1388 STRUCT attribute_list_opt 1389 { $$ = DeclarationNode::Struct; } 1390 | UNION attribute_list_opt 1391 { $$ = DeclarationNode::Union; } 1392 ; 1396 1393 1397 1394 field_declaration_list: 1398 field_declaration1399 { $$ = $1; }1400 | field_declaration_list field_declaration1401 { $$ = $1->appendList( $2 ); }1402 ;1395 field_declaration 1396 { $$ = $1; } 1397 | field_declaration_list field_declaration 1398 { $$ = $1->appendList( $2 ); } 1399 ; 1403 1400 1404 1401 field_declaration: 1405 new_field_declaring_list ';'// CFA, new style field declaration1406 | EXTENSION new_field_declaring_list ';'// GCC1407 { $$ = $2; }1408 | field_declaring_list ';'1409 | EXTENSION field_declaring_list ';'// GCC1410 { $$ = $2; }1411 ;1402 new_field_declaring_list ';' // CFA, new style field declaration 1403 | EXTENSION new_field_declaring_list ';' // GCC 1404 { $$ = $2; } 1405 | field_declaring_list ';' 1406 | EXTENSION field_declaring_list ';' // GCC 1407 { $$ = $2; } 1408 ; 1412 1409 1413 1410 new_field_declaring_list: // CFA, new style field declaration 1414 new_abstract_declarator_tuple// CFA, no field name1415 | new_abstract_declarator_tuple no_attr_identifier_or_typedef_name1416 { $$ = $1->addName( $2 ); }1417 | new_field_declaring_list ',' no_attr_identifier_or_typedef_name1418 { $$ = $1->appendList( $1->cloneType( $3 ) ); }1419 | new_field_declaring_list ','// CFA, no field name1420 { $$ = $1->appendList( $1->cloneType( 0 ) ); }1421 ;1411 new_abstract_declarator_tuple // CFA, no field name 1412 | new_abstract_declarator_tuple no_attr_identifier_or_typedef_name 1413 { $$ = $1->addName( $2 ); } 1414 | new_field_declaring_list ',' no_attr_identifier_or_typedef_name 1415 { $$ = $1->appendList( $1->cloneType( $3 ) ); } 1416 | new_field_declaring_list ',' // CFA, no field name 1417 { $$ = $1->appendList( $1->cloneType( 0 ) ); } 1418 ; 1422 1419 1423 1420 field_declaring_list: 1424 type_specifier field_declarator1425 { $$ = $2->addType( $1 ); }1426 | field_declaring_list ',' attribute_list_opt field_declarator1427 { $$ = $1->appendList( $1->cloneBaseType( $4 ) ); }1428 ;1421 type_specifier field_declarator 1422 { $$ = $2->addType( $1 ); } 1423 | field_declaring_list ',' attribute_list_opt field_declarator 1424 { $$ = $1->appendList( $1->cloneBaseType( $4 ) ); } 1425 ; 1429 1426 1430 1427 field_declarator: 1431 // empty1432 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name1433 | bit_subrange_size// no field name1434 { $$ = DeclarationNode::newBitfield( $1 ); }1435 | variable_declarator bit_subrange_size_opt1436 // A semantic check is required to ensure bit_subrange only appears on base type int.1437 { $$ = $1->addBitfield( $2 ); }1438 | typedef_redeclarator bit_subrange_size_opt1439 // A semantic check is required to ensure bit_subrange only appears on base type int.1440 { $$ = $1->addBitfield( $2 ); }1441 | variable_abstract_declarator// CFA, no field name1442 ;1428 // empty 1429 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name 1430 | bit_subrange_size // no field name 1431 { $$ = DeclarationNode::newBitfield( $1 ); } 1432 | variable_declarator bit_subrange_size_opt 1433 // A semantic check is required to ensure bit_subrange only appears on base type int. 1434 { $$ = $1->addBitfield( $2 ); } 1435 | typedef_redeclarator bit_subrange_size_opt 1436 // A semantic check is required to ensure bit_subrange only appears on base type int. 1437 { $$ = $1->addBitfield( $2 ); } 1438 | variable_abstract_declarator // CFA, no field name 1439 ; 1443 1440 1444 1441 bit_subrange_size_opt: 1445 // empty1446 { $$ = 0; }1447 | bit_subrange_size1448 { $$ = $1; }1449 ;1442 // empty 1443 { $$ = 0; } 1444 | bit_subrange_size 1445 { $$ = $1; } 1446 ; 1450 1447 1451 1448 bit_subrange_size: 1452 ':' constant_expression1453 { $$ = $2; }1454 ;1449 ':' constant_expression 1450 { $$ = $2; } 1451 ; 1455 1452 1456 1453 enum_key: 1457 ENUM attribute_list_opt1458 ;1454 ENUM attribute_list_opt 1455 ; 1459 1456 1460 1457 enum_name: 1461 enum_key '{' enumerator_list comma_opt '}'1462 { $$ = DeclarationNode::newEnum( 0, $3 ); }1463 | enum_key no_attr_identifier_or_typedef_name '{' enumerator_list comma_opt '}'1464 { $$ = DeclarationNode::newEnum( $2, $4 ); }1465 | enum_key no_attr_identifier_or_typedef_name1466 { $$ = DeclarationNode::newEnum( $2, 0 ); }1467 ;1458 enum_key '{' enumerator_list comma_opt '}' 1459 { $$ = DeclarationNode::newEnum( 0, $3 ); } 1460 | enum_key no_attr_identifier_or_typedef_name '{' enumerator_list comma_opt '}' 1461 { $$ = DeclarationNode::newEnum( $2, $4 ); } 1462 | enum_key no_attr_identifier_or_typedef_name 1463 { $$ = DeclarationNode::newEnum( $2, 0 ); } 1464 ; 1468 1465 1469 1466 enumerator_list: 1470 no_attr_identifier_or_typedef_name enumerator_value_opt1471 { $$ = DeclarationNode::newEnumConstant( $1, $2 ); }1472 | enumerator_list ',' no_attr_identifier_or_typedef_name enumerator_value_opt1473 { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }1474 ;1467 no_attr_identifier_or_typedef_name enumerator_value_opt 1468 { $$ = DeclarationNode::newEnumConstant( $1, $2 ); } 1469 | enumerator_list ',' no_attr_identifier_or_typedef_name enumerator_value_opt 1470 { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); } 1471 ; 1475 1472 1476 1473 enumerator_value_opt: 1477 // empty1478 { $$ = 0; }1479 | '=' constant_expression1480 { $$ = $2; }1481 ;1474 // empty 1475 { $$ = 0; } 1476 | '=' constant_expression 1477 { $$ = $2; } 1478 ; 1482 1479 1483 1480 // Minimum of one parameter after which ellipsis is allowed only at the end. 1484 1481 1485 1482 new_parameter_type_list_opt: // CFA 1486 // empty1487 { $$ = 0; }1488 | new_parameter_type_list1489 ;1483 // empty 1484 { $$ = 0; } 1485 | new_parameter_type_list 1486 ; 1490 1487 1491 1488 new_parameter_type_list: // CFA, abstract + real 1492 new_abstract_parameter_list1493 | new_parameter_list1494 | new_parameter_list pop ',' push new_abstract_parameter_list1495 { $$ = $1->appendList( $5 ); }1496 | new_abstract_parameter_list pop ',' push ELLIPSIS1497 { $$ = $1->addVarArgs(); }1498 | new_parameter_list pop ',' push ELLIPSIS1499 { $$ = $1->addVarArgs(); }1500 ;1489 new_abstract_parameter_list 1490 | new_parameter_list 1491 | new_parameter_list pop ',' push new_abstract_parameter_list 1492 { $$ = $1->appendList( $5 ); } 1493 | new_abstract_parameter_list pop ',' push ELLIPSIS 1494 { $$ = $1->addVarArgs(); } 1495 | new_parameter_list pop ',' push ELLIPSIS 1496 { $$ = $1->addVarArgs(); } 1497 ; 1501 1498 1502 1499 new_parameter_list: // CFA 1503 // To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last1504 // new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules1505 // to getlookahead to the ']'.1506 new_parameter_declaration1507 | new_abstract_parameter_list pop ',' push new_parameter_declaration1508 { $$ = $1->appendList( $5 ); }1509 | new_parameter_list pop ',' push new_parameter_declaration1510 { $$ = $1->appendList( $5 ); }1511 | new_parameter_list pop ',' push new_abstract_parameter_list pop ',' push new_parameter_declaration1512 { $$ = $1->appendList( $5 )->appendList( $9 ); }1513 ;1500 // To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last 1501 // new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules to get 1502 // lookahead to the ']'. 1503 new_parameter_declaration 1504 | new_abstract_parameter_list pop ',' push new_parameter_declaration 1505 { $$ = $1->appendList( $5 ); } 1506 | new_parameter_list pop ',' push new_parameter_declaration 1507 { $$ = $1->appendList( $5 ); } 1508 | new_parameter_list pop ',' push new_abstract_parameter_list pop ',' push new_parameter_declaration 1509 { $$ = $1->appendList( $5 )->appendList( $9 ); } 1510 ; 1514 1511 1515 1512 new_abstract_parameter_list: // CFA, new & old style abstract 1516 new_abstract_parameter_declaration1517 | new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration1518 { $$ = $1->appendList( $5 ); }1519 ;1513 new_abstract_parameter_declaration 1514 | new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration 1515 { $$ = $1->appendList( $5 ); } 1516 ; 1520 1517 1521 1518 parameter_type_list_opt: 1522 // empty1523 { $$ = 0; }1524 | parameter_type_list1525 ;1519 // empty 1520 { $$ = 0; } 1521 | parameter_type_list 1522 ; 1526 1523 1527 1524 parameter_type_list: 1528 parameter_list1529 | parameter_list pop ',' push ELLIPSIS1530 { $$ = $1->addVarArgs(); }1531 ;1525 parameter_list 1526 | parameter_list pop ',' push ELLIPSIS 1527 { $$ = $1->addVarArgs(); } 1528 ; 1532 1529 1533 1530 parameter_list: // abstract + real 1534 abstract_parameter_declaration1535 | parameter_declaration1536 | parameter_list pop ',' push abstract_parameter_declaration1537 { $$ = $1->appendList( $5 ); }1538 | parameter_list pop ',' push parameter_declaration1539 { $$ = $1->appendList( $5 ); }1540 ;1531 abstract_parameter_declaration 1532 | parameter_declaration 1533 | parameter_list pop ',' push abstract_parameter_declaration 1534 { $$ = $1->appendList( $5 ); } 1535 | parameter_list pop ',' push parameter_declaration 1536 { $$ = $1->appendList( $5 ); } 1537 ; 1541 1538 1542 1539 // Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different … … 1545 1542 1546 1543 new_parameter_declaration: // CFA, new & old style parameter declaration 1547 parameter_declaration1548 | new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt1549 { $$ = $1->addName( $2 ); }1550 | new_abstract_tuple identifier_or_typedef_name assignment_opt1551 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).1552 { $$ = $1->addName( $2 ); }1553 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt1554 { $$ = $2->addName( $3 )->addQualifiers( $1 ); }1555 | new_function_specifier1556 ;1544 parameter_declaration 1545 | new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt 1546 { $$ = $1->addName( $2 ); } 1547 | new_abstract_tuple identifier_or_typedef_name assignment_opt 1548 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). 1549 { $$ = $1->addName( $2 ); } 1550 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt 1551 { $$ = $2->addName( $3 )->addQualifiers( $1 ); } 1552 | new_function_specifier 1553 ; 1557 1554 1558 1555 new_abstract_parameter_declaration: // CFA, new & old style parameter declaration 1559 abstract_parameter_declaration1560 | new_identifier_parameter_declarator_no_tuple1561 | new_abstract_tuple1562 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).1563 | type_qualifier_list new_abstract_tuple1564 { $$ = $2->addQualifiers( $1 ); }1565 | new_abstract_function1566 ;1556 abstract_parameter_declaration 1557 | new_identifier_parameter_declarator_no_tuple 1558 | new_abstract_tuple 1559 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). 1560 | type_qualifier_list new_abstract_tuple 1561 { $$ = $2->addQualifiers( $1 ); } 1562 | new_abstract_function 1563 ; 1567 1564 1568 1565 parameter_declaration: 1569 declaration_specifier identifier_parameter_declarator assignment_opt1570 {1571 typedefTable.addToEnclosingScope( TypedefTable::ID );1572 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );1573 }1574 | declaration_specifier typedef_parameter_redeclarator assignment_opt1575 {1576 typedefTable.addToEnclosingScope( TypedefTable::ID );1577 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );1578 }1579 ;1566 declaration_specifier identifier_parameter_declarator assignment_opt 1567 { 1568 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1569 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) ); 1570 } 1571 | declaration_specifier typedef_parameter_redeclarator assignment_opt 1572 { 1573 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1574 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) ); 1575 } 1576 ; 1580 1577 1581 1578 abstract_parameter_declaration: 1582 declaration_specifier1583 | declaration_specifier abstract_parameter_declarator1584 { $$ = $2->addType( $1 ); }1585 ;1579 declaration_specifier 1580 | declaration_specifier abstract_parameter_declarator 1581 { $$ = $2->addType( $1 ); } 1582 ; 1586 1583 1587 1584 // ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a … … 1590 1587 1591 1588 identifier_list: // K&R-style parameter list => no types 1592 no_attr_identifier1593 { $$ = DeclarationNode::newName( $1 ); }1594 | identifier_list ',' no_attr_identifier1595 { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }1596 ;1589 no_attr_identifier 1590 { $$ = DeclarationNode::newName( $1 ); } 1591 | identifier_list ',' no_attr_identifier 1592 { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); } 1593 ; 1597 1594 1598 1595 identifier_or_typedef_name: 1599 identifier1600 | TYPEDEFname1601 | TYPEGENname1602 ;1596 identifier 1597 | TYPEDEFname 1598 | TYPEGENname 1599 ; 1603 1600 1604 1601 no_01_identifier_or_typedef_name: 1605 no_01_identifier1606 | TYPEDEFname1607 | TYPEGENname1608 ;1602 no_01_identifier 1603 | TYPEDEFname 1604 | TYPEGENname 1605 ; 1609 1606 1610 1607 no_attr_identifier_or_typedef_name: 1611 no_attr_identifier1612 | TYPEDEFname1613 | TYPEGENname1614 ;1608 no_attr_identifier 1609 | TYPEDEFname 1610 | TYPEGENname 1611 ; 1615 1612 1616 1613 type_name_no_function: // sizeof, alignof, cast (constructor) 1617 new_abstract_declarator_tuple// CFA1618 | type_specifier1619 | type_specifier variable_abstract_declarator1620 { $$ = $2->addType( $1 ); }1621 ;1614 new_abstract_declarator_tuple // CFA 1615 | type_specifier 1616 | type_specifier variable_abstract_declarator 1617 { $$ = $2->addType( $1 ); } 1618 ; 1622 1619 1623 1620 type_name: // typeof, assertion 1624 new_abstract_declarator_tuple// CFA1625 | new_abstract_function// CFA1626 | type_specifier1627 | type_specifier abstract_declarator1628 { $$ = $2->addType( $1 ); }1629 ;1621 new_abstract_declarator_tuple // CFA 1622 | new_abstract_function // CFA 1623 | type_specifier 1624 | type_specifier abstract_declarator 1625 { $$ = $2->addType( $1 ); } 1626 ; 1630 1627 1631 1628 initializer_opt: 1632 // empty1633 { $$ = 0; }1634 | '=' initializer{ $$ = $2; }1635 ;1629 // empty 1630 { $$ = 0; } 1631 | '=' initializer { $$ = $2; } 1632 ; 1636 1633 1637 1634 initializer: 1638 assignment_expression{ $$ = new InitializerNode($1); }1639 | '{' initializer_list comma_opt '}'{ $$ = new InitializerNode($2, true); }1640 ;1635 assignment_expression { $$ = new InitializerNode($1); } 1636 | '{' initializer_list comma_opt '}' { $$ = new InitializerNode($2, true); } 1637 ; 1641 1638 1642 1639 initializer_list: 1643 initializer1644 | designation initializer{ $$ = $2->set_designators( $1 ); }1645 | initializer_list ',' initializer{ $$ = (InitializerNode *)( $1->set_link($3) ); }1646 | initializer_list ',' designation initializer1647 { $$ = (InitializerNode *)( $1->set_link( $4->set_designators($3) ) ); }1648 ;1640 initializer 1641 | designation initializer { $$ = $2->set_designators( $1 ); } 1642 | initializer_list ',' initializer { $$ = (InitializerNode *)( $1->set_link($3) ); } 1643 | initializer_list ',' designation initializer 1644 { $$ = (InitializerNode *)( $1->set_link( $4->set_designators($3) ) ); } 1645 ; 1649 1646 1650 1647 // There is an unreconcileable parsing problem between C99 and CFA with respect to designators. The problem is … … 1659 1656 1660 1657 designation: 1661 designator_list ':'// C99, CFA uses ":" instead of "="1662 | no_attr_identifier_or_typedef_name ':'// GCC, field name1663 { $$ = new VarRefNode( $1 ); }1664 ;1658 designator_list ':' // C99, CFA uses ":" instead of "=" 1659 | no_attr_identifier_or_typedef_name ':' // GCC, field name 1660 { $$ = new VarRefNode( $1 ); } 1661 ; 1665 1662 1666 1663 designator_list: // C99 1667 designator1668 | designator_list designator{ $$ = (ExpressionNode *)($1->set_link( $2 )); }1669 ;1664 designator 1665 | designator_list designator { $$ = (ExpressionNode *)($1->set_link( $2 )); } 1666 ; 1670 1667 1671 1668 designator: 1672 '.' no_attr_identifier_or_typedef_name// C99, field name1673 { $$ = new VarRefNode( $2 ); }1674 | '[' push assignment_expression pop ']'// C99, single array element1675 // assignment_expression used instead of constant_expression because of shift/reduce conflicts1676 // withtuple.1677 { $$ = $3; }1678 | '[' push subrange pop ']'// CFA, multiple array elements1679 { $$ = $3; }1680 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements1681 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); }1682 | '.' '[' push field_list pop ']'// CFA, tuple field selector1683 { $$ = $4; }1684 ;1669 '.' no_attr_identifier_or_typedef_name // C99, field name 1670 { $$ = new VarRefNode( $2 ); } 1671 | '[' push assignment_expression pop ']' // C99, single array element 1672 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with 1673 // tuple. 1674 { $$ = $3; } 1675 | '[' push subrange pop ']' // CFA, multiple array elements 1676 { $$ = $3; } 1677 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 1678 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); } 1679 | '.' '[' push field_list pop ']' // CFA, tuple field selector 1680 { $$ = $4; } 1681 ; 1685 1682 1686 1683 // The CFA type system is based on parametric polymorphism, the ability to declare functions with type … … 1704 1701 1705 1702 typegen_declaration_specifier: // CFA 1706 typegen_type_specifier1707 | declaration_qualifier_list typegen_type_specifier1708 { $$ = $2->addQualifiers( $1 ); }1709 | typegen_declaration_specifier storage_class// remaining OBSOLESCENT (see 2)1710 { $$ = $1->addQualifiers( $2 ); }1711 | typegen_declaration_specifier storage_class type_qualifier_list1712 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }1713 ;1703 typegen_type_specifier 1704 | declaration_qualifier_list typegen_type_specifier 1705 { $$ = $2->addQualifiers( $1 ); } 1706 | typegen_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1707 { $$ = $1->addQualifiers( $2 ); } 1708 | typegen_declaration_specifier storage_class type_qualifier_list 1709 { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); } 1710 ; 1714 1711 1715 1712 typegen_type_specifier: // CFA 1716 TYPEGENname '(' type_name_list ')'1717 { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }1718 | type_qualifier_list TYPEGENname '(' type_name_list ')'1719 { $$ = DeclarationNode::newFromTypeGen( $2, $4 )->addQualifiers( $1 ); }1720 | typegen_type_specifier type_qualifier1721 { $$ = $1->addQualifiers( $2 ); }1722 ;1713 TYPEGENname '(' type_name_list ')' 1714 { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); } 1715 | type_qualifier_list TYPEGENname '(' type_name_list ')' 1716 { $$ = DeclarationNode::newFromTypeGen( $2, $4 )->addQualifiers( $1 ); } 1717 | typegen_type_specifier type_qualifier 1718 { $$ = $1->addQualifiers( $2 ); } 1719 ; 1723 1720 1724 1721 type_parameter_list: // CFA 1725 type_parameter assignment_opt1726 | type_parameter_list ',' type_parameter assignment_opt1727 { $$ = $1->appendList( $3 ); }1728 ;1722 type_parameter assignment_opt 1723 | type_parameter_list ',' type_parameter assignment_opt 1724 { $$ = $1->appendList( $3 ); } 1725 ; 1729 1726 1730 1727 type_parameter: // CFA 1731 type_class no_attr_identifier_or_typedef_name1732 { typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); }1733 assertion_list_opt1734 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addAssertions( $4 ); }1735 | type_specifier identifier_parameter_declarator1736 ;1728 type_class no_attr_identifier_or_typedef_name 1729 { typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); } 1730 assertion_list_opt 1731 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addAssertions( $4 ); } 1732 | type_specifier identifier_parameter_declarator 1733 ; 1737 1734 1738 1735 type_class: // CFA 1739 TYPE1740 { $$ = DeclarationNode::Type; }1741 | DTYPE1742 { $$ = DeclarationNode::Ftype; }1743 | FTYPE1744 { $$ = DeclarationNode::Dtype; }1745 ;1736 TYPE 1737 { $$ = DeclarationNode::Type; } 1738 | DTYPE 1739 { $$ = DeclarationNode::Ftype; } 1740 | FTYPE 1741 { $$ = DeclarationNode::Dtype; } 1742 ; 1746 1743 1747 1744 assertion_list_opt: // CFA 1748 // empty1749 { $$ = 0; }1750 | assertion_list_opt assertion1751 { $$ = $1 == 0 ? $2 : $1->appendList( $2 ); }1752 ;1745 // empty 1746 { $$ = 0; } 1747 | assertion_list_opt assertion 1748 { $$ = $1 == 0 ? $2 : $1->appendList( $2 ); } 1749 ; 1753 1750 1754 1751 assertion: // CFA 1755 '|' no_attr_identifier_or_typedef_name '(' type_name_list ')'1756 {1757 typedefTable.openContext( *($2) );1758 $$ = DeclarationNode::newContextUse( $2, $4 );1759 }1760 | '|' '{' push context_declaration_list '}'1761 { $$ = $4; }1762 | '|' '(' push type_parameter_list pop ')' '{' push context_declaration_list '}' '(' type_name_list ')'1763 { $$ = 0; }1764 ;1752 '|' no_attr_identifier_or_typedef_name '(' type_name_list ')' 1753 { 1754 typedefTable.openContext( *($2) ); 1755 $$ = DeclarationNode::newContextUse( $2, $4 ); 1756 } 1757 | '|' '{' push context_declaration_list '}' 1758 { $$ = $4; } 1759 | '|' '(' push type_parameter_list pop ')' '{' push context_declaration_list '}' '(' type_name_list ')' 1760 { $$ = 0; } 1761 ; 1765 1762 1766 1763 type_name_list: // CFA 1767 type_name1768 { $$ = new TypeValueNode( $1 ); }1769 | assignment_expression1770 | type_name_list ',' type_name1771 { $$ = (ExpressionNode *)($1->set_link(new TypeValueNode( $3 ))); }1772 | type_name_list ',' assignment_expression1773 { $$ = (ExpressionNode *)($1->set_link($3)); }1774 ;1764 type_name 1765 { $$ = new TypeValueNode( $1 ); } 1766 | assignment_expression 1767 | type_name_list ',' type_name 1768 { $$ = (ExpressionNode *)($1->set_link(new TypeValueNode( $3 ))); } 1769 | type_name_list ',' assignment_expression 1770 { $$ = (ExpressionNode *)($1->set_link($3)); } 1771 ; 1775 1772 1776 1773 type_declaring_list: // CFA 1777 TYPE type_declarator1778 { $$ = $2; }1779 | storage_class_list TYPE type_declarator1780 { $$ = $3->addQualifiers( $1 ); }1781 | type_declaring_list ',' type_declarator1782 { $$ = $1->appendList( $3->copyStorageClasses( $1 ) ); }1783 ;1774 TYPE type_declarator 1775 { $$ = $2; } 1776 | storage_class_list TYPE type_declarator 1777 { $$ = $3->addQualifiers( $1 ); } 1778 | type_declaring_list ',' type_declarator 1779 { $$ = $1->appendList( $3->copyStorageClasses( $1 ) ); } 1780 ; 1784 1781 1785 1782 type_declarator: // CFA 1786 type_declarator_name assertion_list_opt1787 { $$ = $1->addAssertions( $2 ); }1788 | type_declarator_name assertion_list_opt '=' type_name1789 { $$ = $1->addAssertions( $2 )->addType( $4 ); }1790 ;1783 type_declarator_name assertion_list_opt 1784 { $$ = $1->addAssertions( $2 ); } 1785 | type_declarator_name assertion_list_opt '=' type_name 1786 { $$ = $1->addAssertions( $2 )->addType( $4 ); } 1787 ; 1791 1788 1792 1789 type_declarator_name: // CFA 1793 no_attr_identifier_or_typedef_name1794 {1795 typedefTable.addToEnclosingScope(*($1), TypedefTable::TD);1796 $$ = DeclarationNode::newTypeDecl( $1, 0 );1797 }1798 | no_01_identifier_or_typedef_name '(' push type_parameter_list pop ')'1799 {1800 typedefTable.addToEnclosingScope(*($1), TypedefTable::TG);1801 $$ = DeclarationNode::newTypeDecl( $1, $4 );1802 }1803 ;1790 no_attr_identifier_or_typedef_name 1791 { 1792 typedefTable.addToEnclosingScope(*($1), TypedefTable::TD); 1793 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 1794 } 1795 | no_01_identifier_or_typedef_name '(' push type_parameter_list pop ')' 1796 { 1797 typedefTable.addToEnclosingScope(*($1), TypedefTable::TG); 1798 $$ = DeclarationNode::newTypeDecl( $1, $4 ); 1799 } 1800 ; 1804 1801 1805 1802 context_specifier: // CFA 1806 CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}'1807 {1808 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );1809 $$ = DeclarationNode::newContext( $2, $5, 0 );1810 }1811 | CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{'1812 {1813 typedefTable.enterContext( *($2) );1814 typedefTable.enterScope();1815 }1816 context_declaration_list '}'1817 {1818 typedefTable.leaveContext();1819 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );1820 $$ = DeclarationNode::newContext( $2, $5, $10 );1821 }1822 ;1803 CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}' 1804 { 1805 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID ); 1806 $$ = DeclarationNode::newContext( $2, $5, 0 ); 1807 } 1808 | CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' 1809 { 1810 typedefTable.enterContext( *($2) ); 1811 typedefTable.enterScope(); 1812 } 1813 context_declaration_list '}' 1814 { 1815 typedefTable.leaveContext(); 1816 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID ); 1817 $$ = DeclarationNode::newContext( $2, $5, $10 ); 1818 } 1819 ; 1823 1820 1824 1821 context_declaration_list: // CFA 1825 context_declaration1826 | context_declaration_list push context_declaration1827 { $$ = $1->appendList( $3 ); }1828 ;1822 context_declaration 1823 | context_declaration_list push context_declaration 1824 { $$ = $1->appendList( $3 ); } 1825 ; 1829 1826 1830 1827 context_declaration: // CFA 1831 new_context_declaring_list pop ';'1832 | context_declaring_list pop ';'1833 ;1828 new_context_declaring_list pop ';' 1829 | context_declaring_list pop ';' 1830 ; 1834 1831 1835 1832 new_context_declaring_list: // CFA 1836 new_variable_specifier1837 {1838 typedefTable.addToEnclosingScope2( TypedefTable::ID );1839 $$ = $1;1840 }1841 | new_function_specifier1842 {1843 typedefTable.addToEnclosingScope2( TypedefTable::ID );1844 $$ = $1;1845 }1846 | new_context_declaring_list pop ',' push identifier_or_typedef_name1847 {1848 typedefTable.addToEnclosingScope2( *($5), TypedefTable::ID );1849 $$ = $1->appendList( $1->cloneType( $5 ) );1850 }1851 ;1833 new_variable_specifier 1834 { 1835 typedefTable.addToEnclosingScope2( TypedefTable::ID ); 1836 $$ = $1; 1837 } 1838 | new_function_specifier 1839 { 1840 typedefTable.addToEnclosingScope2( TypedefTable::ID ); 1841 $$ = $1; 1842 } 1843 | new_context_declaring_list pop ',' push identifier_or_typedef_name 1844 { 1845 typedefTable.addToEnclosingScope2( *($5), TypedefTable::ID ); 1846 $$ = $1->appendList( $1->cloneType( $5 ) ); 1847 } 1848 ; 1852 1849 1853 1850 context_declaring_list: // CFA 1854 type_specifier declarator1855 {1856 typedefTable.addToEnclosingScope2( TypedefTable::ID );1857 $$ = $2->addType( $1 );1858 }1859 | context_declaring_list pop ',' push declarator1860 {1861 typedefTable.addToEnclosingScope2( TypedefTable::ID );1862 $$ = $1->appendList( $1->cloneBaseType( $5 ) );1863 }1864 ;1851 type_specifier declarator 1852 { 1853 typedefTable.addToEnclosingScope2( TypedefTable::ID ); 1854 $$ = $2->addType( $1 ); 1855 } 1856 | context_declaring_list pop ',' push declarator 1857 { 1858 typedefTable.addToEnclosingScope2( TypedefTable::ID ); 1859 $$ = $1->appendList( $1->cloneBaseType( $5 ) ); 1860 } 1861 ; 1865 1862 1866 1863 //***************************** EXTERNAL DEFINITIONS ***************************** 1867 1864 1868 1865 translation_unit: 1869 // empty1870 {}// empty input file1871 | external_definition_list1872 {1873 if ( theTree ) {1874 theTree->appendList( $1 );1875 } else {1876 theTree = $1;1877 }1878 }1879 ;1866 // empty 1867 {} // empty input file 1868 | external_definition_list 1869 { 1870 if ( theTree ) { 1871 theTree->appendList( $1 ); 1872 } else { 1873 theTree = $1; 1874 } 1875 } 1876 ; 1880 1877 1881 1878 external_definition_list: 1882 external_definition1883 | external_definition_list push external_definition1884 { $$ = ($1 != NULL ) ? $1->appendList( $3 ) : $3; }1885 ;1879 external_definition 1880 | external_definition_list push external_definition 1881 { $$ = ($1 != NULL ) ? $1->appendList( $3 ) : $3; } 1882 ; 1886 1883 1887 1884 external_definition_list_opt: 1888 // empty1889 { $$ = 0; }1890 | external_definition_list1891 ;1885 // empty 1886 { $$ = 0; } 1887 | external_definition_list 1888 ; 1892 1889 1893 1890 external_definition: 1894 declaration 1895 | function_definition 1896 | asm_statement // GCC, global assembler statement 1897 {} 1898 | EXTERN STRINGliteral 1899 { 1900 linkageStack.push( linkage ); 1901 linkage = LinkageSpec::fromString( *$2 ); 1902 } 1903 '{' external_definition_list_opt '}' // C++-style linkage specifier 1904 { 1905 linkage = linkageStack.top(); 1906 linkageStack.pop(); 1907 $$ = $5; 1908 } 1909 | EXTENSION external_definition 1910 { $$ = $2; } 1911 ; 1891 declaration 1892 | external_function_definition 1893 | asm_statement // GCC, global assembler statement 1894 {} 1895 | EXTERN STRINGliteral 1896 { 1897 linkageStack.push( linkage ); 1898 linkage = LinkageSpec::fromString( *$2 ); 1899 } 1900 '{' external_definition_list_opt '}' // C++-style linkage specifier 1901 { 1902 linkage = linkageStack.top(); 1903 linkageStack.pop(); 1904 $$ = $5; 1905 } 1906 | EXTENSION external_definition 1907 { $$ = $2; } 1908 ; 1909 1910 external_function_definition: 1911 function_definition 1912 1913 // These rules are a concession to the "implicit int" type_specifier because there is a significant 1914 // amount of code with functions missing a type-specifier on the return type. Parsing is possible 1915 // because function_definition does not appear in the context of an expression (nested functions would 1916 // preclude this concession). A function prototype declaration must still have a type_specifier. 1917 // OBSOLESCENT (see 1) 1918 | function_declarator compound_statement 1919 { 1920 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1921 typedefTable.leaveScope(); 1922 $$ = $1->addFunctionBody( $2 ); 1923 } 1924 | old_function_declarator push old_declaration_list_opt compound_statement 1925 { 1926 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1927 typedefTable.leaveScope(); 1928 $$ = $1->addOldDeclList( $3 )->addFunctionBody( $4 ); 1929 } 1930 ; 1912 1931 1913 1932 function_definition: 1914 new_function_declaration compound_statement // CFA 1915 { 1916 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1917 typedefTable.leaveScope(); 1918 $$ = $1->addFunctionBody( $2 ); 1919 } 1920 // | declaration_qualifier_list new_function_specifier compound_statement // CFA 1921 // // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is 1922 // // necessary to preclude them as a type_qualifier cannot appear in this context. 1923 // { 1924 // typedefTable.addToEnclosingScope( TypedefTable::ID ); 1925 // typedefTable.leaveScope(); 1926 // $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 ); 1927 // } 1928 | declaration_specifier function_declarator compound_statement 1929 { 1930 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1931 typedefTable.leaveScope(); 1932 $$ = $2->addFunctionBody( $3 )->addType( $1 ); 1933 } 1934 1935 // These rules are a concession to the "implicit int" type_specifier because there is a 1936 // significant amount of code with functions missing a type-specifier on the return type. 1937 // Parsing is possible because function_definition does not appear in the context of an 1938 // expression (nested functions would preclude this concession). A function prototype 1939 // declaration must still have a type_specifier. OBSOLESCENT (see 1) 1940 | function_declarator compound_statement 1941 { 1942 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1943 typedefTable.leaveScope(); 1944 $$ = $1->addFunctionBody( $2 ); 1945 } 1946 | type_qualifier_list function_declarator compound_statement 1947 { 1948 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1949 typedefTable.leaveScope(); 1950 $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 ); 1951 } 1952 | declaration_qualifier_list function_declarator compound_statement 1953 { 1954 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1955 typedefTable.leaveScope(); 1956 $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 ); 1957 } 1958 | declaration_qualifier_list type_qualifier_list function_declarator compound_statement 1959 { 1960 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1961 typedefTable.leaveScope(); 1962 $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 ); 1963 } 1964 1965 // Old-style K&R function definition, OBSOLESCENT (see 4) 1966 | declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement 1967 { 1968 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1969 typedefTable.leaveScope(); 1970 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 ); 1971 } 1972 | old_function_declarator push old_declaration_list_opt compound_statement 1973 { 1974 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1975 typedefTable.leaveScope(); 1976 $$ = $1->addOldDeclList( $3 )->addFunctionBody( $4 ); 1977 } 1978 | type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1979 { 1980 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1981 typedefTable.leaveScope(); 1982 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 ); 1983 } 1984 1985 // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) 1986 | declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1987 { 1988 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1989 typedefTable.leaveScope(); 1990 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 ); 1991 } 1992 | declaration_qualifier_list type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1993 { 1994 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1995 typedefTable.leaveScope(); 1996 $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 ); 1997 } 1998 ; 1933 new_function_declaration compound_statement // CFA 1934 { 1935 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1936 typedefTable.leaveScope(); 1937 $$ = $1->addFunctionBody( $2 ); 1938 } 1939 | declaration_specifier function_declarator compound_statement 1940 { 1941 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1942 typedefTable.leaveScope(); 1943 $$ = $2->addFunctionBody( $3 )->addType( $1 ); 1944 } 1945 | type_qualifier_list function_declarator compound_statement 1946 { 1947 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1948 typedefTable.leaveScope(); 1949 $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 ); 1950 } 1951 | declaration_qualifier_list function_declarator compound_statement 1952 { 1953 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1954 typedefTable.leaveScope(); 1955 $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 ); 1956 } 1957 | declaration_qualifier_list type_qualifier_list function_declarator compound_statement 1958 { 1959 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1960 typedefTable.leaveScope(); 1961 $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 ); 1962 } 1963 1964 // Old-style K&R function definition, OBSOLESCENT (see 4) 1965 | declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement 1966 { 1967 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1968 typedefTable.leaveScope(); 1969 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 ); 1970 } 1971 | type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1972 { 1973 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1974 typedefTable.leaveScope(); 1975 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 ); 1976 } 1977 1978 // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) 1979 | declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1980 { 1981 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1982 typedefTable.leaveScope(); 1983 $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 ); 1984 } 1985 | declaration_qualifier_list type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1986 { 1987 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1988 typedefTable.leaveScope(); 1989 $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 ); 1990 } 1991 ; 1999 1992 2000 1993 declarator: 2001 variable_declarator2002 | function_declarator2003 | typedef_redeclarator2004 ;1994 variable_declarator 1995 | function_declarator 1996 | typedef_redeclarator 1997 ; 2005 1998 2006 1999 subrange: 2007 constant_expression '~' constant_expression// CFA, integer subrange2008 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); }2009 ;2000 constant_expression '~' constant_expression // CFA, integer subrange 2001 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); } 2002 ; 2010 2003 2011 2004 asm_name_opt: // GCC 2012 // empty2013 | ASM '(' string_literal_list ')' attribute_list_opt2014 ;2005 // empty 2006 | ASM '(' string_literal_list ')' attribute_list_opt 2007 ; 2015 2008 2016 2009 attribute_list_opt: // GCC 2017 // empty2018 | attribute_list2019 ;2010 // empty 2011 | attribute_list 2012 ; 2020 2013 2021 2014 attribute_list: // GCC 2022 attribute2023 | attribute_list attribute2024 ;2015 attribute 2016 | attribute_list attribute 2017 ; 2025 2018 2026 2019 attribute: // GCC 2027 ATTRIBUTE '(' '(' attribute_parameter_list ')' ')'2028 ;2020 ATTRIBUTE '(' '(' attribute_parameter_list ')' ')' 2021 ; 2029 2022 2030 2023 attribute_parameter_list: // GCC 2031 attrib2032 | attribute_parameter_list ',' attrib2033 ;2024 attrib 2025 | attribute_parameter_list ',' attrib 2026 ; 2034 2027 2035 2028 attrib: // GCC 2036 // empty2037 | any_word2038 | any_word '(' comma_expression_opt ')'2039 ;2029 // empty 2030 | any_word 2031 | any_word '(' comma_expression_opt ')' 2032 ; 2040 2033 2041 2034 any_word: // GCC 2042 identifier_or_typedef_name {}2043 | storage_class_name {}2044 | basic_type_name {}2045 | type_qualifier {}2046 ;2035 identifier_or_typedef_name {} 2036 | storage_class_name {} 2037 | basic_type_name {} 2038 | type_qualifier {} 2039 ; 2047 2040 2048 2041 // ============================================================================ … … 2065 2058 // valid declaration invalid definition 2066 2059 // ----------------- ------------------ 2067 // int f; int f {}2068 // int *f; int *f {}2060 // int f; int f {} 2061 // int *f; int *f {} 2069 2062 // int f[10]; int f[10] {} 2070 // int (*f)(int); int (*f)(int) {}2063 // int (*f)(int); int (*f)(int) {} 2071 2064 // 2072 2065 // To preclude this syntactic anomaly requires separating the grammar rules for variable and function … … 2078 2071 2079 2072 variable_declarator: 2080 paren_identifier attribute_list_opt2081 | variable_ptr2082 | variable_array attribute_list_opt2083 | variable_function attribute_list_opt2084 ;2073 paren_identifier attribute_list_opt 2074 | variable_ptr 2075 | variable_array attribute_list_opt 2076 | variable_function attribute_list_opt 2077 ; 2085 2078 2086 2079 paren_identifier: 2087 identifier2088 {2089 typedefTable.setNextIdentifier( *($1) );2090 $$ = DeclarationNode::newName( $1 );2091 }2092 | '(' paren_identifier ')'// redundant parenthesis2093 { $$ = $2; }2094 ;2080 identifier 2081 { 2082 typedefTable.setNextIdentifier( *($1) ); 2083 $$ = DeclarationNode::newName( $1 ); 2084 } 2085 | '(' paren_identifier ')' // redundant parenthesis 2086 { $$ = $2; } 2087 ; 2095 2088 2096 2089 variable_ptr: 2097 '*' variable_declarator2098 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2099 | '*' type_qualifier_list variable_declarator2100 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2101 | '(' variable_ptr ')'2102 { $$ = $2; }2103 ;2090 '*' variable_declarator 2091 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2092 | '*' type_qualifier_list variable_declarator 2093 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2094 | '(' variable_ptr ')' 2095 { $$ = $2; } 2096 ; 2104 2097 2105 2098 variable_array: 2106 paren_identifier array_dimension2107 { $$ = $1->addArray( $2 ); }2108 | '(' variable_ptr ')' array_dimension2109 { $$ = $2->addArray( $4 ); }2110 | '(' variable_array ')' multi_array_dimension// redundant parenthesis2111 { $$ = $2->addArray( $4 ); }2112 | '(' variable_array ')'// redundant parenthesis2113 { $$ = $2; }2114 ;2099 paren_identifier array_dimension 2100 { $$ = $1->addArray( $2 ); } 2101 | '(' variable_ptr ')' array_dimension 2102 { $$ = $2->addArray( $4 ); } 2103 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 2104 { $$ = $2->addArray( $4 ); } 2105 | '(' variable_array ')' // redundant parenthesis 2106 { $$ = $2; } 2107 ; 2115 2108 2116 2109 variable_function: 2117 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2118 { $$ = $2->addParamList( $6 ); }2119 | '(' variable_function ')'// redundant parenthesis2120 { $$ = $2; }2121 ;2110 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2111 { $$ = $2->addParamList( $6 ); } 2112 | '(' variable_function ')' // redundant parenthesis 2113 { $$ = $2; } 2114 ; 2122 2115 2123 2116 // This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot … … 2127 2120 2128 2121 function_declarator: 2129 function_no_ptr attribute_list_opt2130 | function_ptr2131 | function_array attribute_list_opt2132 ;2122 function_no_ptr attribute_list_opt 2123 | function_ptr 2124 | function_array attribute_list_opt 2125 ; 2133 2126 2134 2127 function_no_ptr: 2135 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2136 { $$ = $1->addParamList( $4 ); }2137 | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'2138 { $$ = $2->addParamList( $6 ); }2139 | '(' function_no_ptr ')'// redundant parenthesis2140 { $$ = $2; }2141 ;2128 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2129 { $$ = $1->addParamList( $4 ); } 2130 | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')' 2131 { $$ = $2->addParamList( $6 ); } 2132 | '(' function_no_ptr ')' // redundant parenthesis 2133 { $$ = $2; } 2134 ; 2142 2135 2143 2136 function_ptr: 2144 '*' function_declarator2145 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2146 | '*' type_qualifier_list function_declarator2147 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2148 | '(' function_ptr ')'2149 { $$ = $2; }2150 ;2137 '*' function_declarator 2138 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2139 | '*' type_qualifier_list function_declarator 2140 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2141 | '(' function_ptr ')' 2142 { $$ = $2; } 2143 ; 2151 2144 2152 2145 function_array: 2153 '(' function_ptr ')' array_dimension2154 { $$ = $2->addArray( $4 ); }2155 | '(' function_array ')' multi_array_dimension// redundant parenthesis2156 { $$ = $2->addArray( $4 ); }2157 | '(' function_array ')'// redundant parenthesis2158 { $$ = $2; }2159 ;2146 '(' function_ptr ')' array_dimension 2147 { $$ = $2->addArray( $4 ); } 2148 | '(' function_array ')' multi_array_dimension // redundant parenthesis 2149 { $$ = $2->addArray( $4 ); } 2150 | '(' function_array ')' // redundant parenthesis 2151 { $$ = $2; } 2152 ; 2160 2153 2161 2154 // This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a … … 2164 2157 2165 2158 old_function_declarator: 2166 old_function_no_ptr2167 | old_function_ptr2168 | old_function_array2169 ;2159 old_function_no_ptr 2160 | old_function_ptr 2161 | old_function_array 2162 ; 2170 2163 2171 2164 old_function_no_ptr: 2172 paren_identifier '(' identifier_list ')'// function_declarator handles empty parameter2173 { $$ = $1->addIdList( $3 ); }2174 | '(' old_function_ptr ')' '(' identifier_list ')'2175 { $$ = $2->addIdList( $5 ); }2176 | '(' old_function_no_ptr ')'// redundant parenthesis2177 { $$ = $2; }2178 ;2165 paren_identifier '(' identifier_list ')' // function_declarator handles empty parameter 2166 { $$ = $1->addIdList( $3 ); } 2167 | '(' old_function_ptr ')' '(' identifier_list ')' 2168 { $$ = $2->addIdList( $5 ); } 2169 | '(' old_function_no_ptr ')' // redundant parenthesis 2170 { $$ = $2; } 2171 ; 2179 2172 2180 2173 old_function_ptr: 2181 '*' old_function_declarator2182 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2183 | '*' type_qualifier_list old_function_declarator2184 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2185 | '(' old_function_ptr ')'2186 { $$ = $2; }2187 ;2174 '*' old_function_declarator 2175 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2176 | '*' type_qualifier_list old_function_declarator 2177 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2178 | '(' old_function_ptr ')' 2179 { $$ = $2; } 2180 ; 2188 2181 2189 2182 old_function_array: 2190 '(' old_function_ptr ')' array_dimension2191 { $$ = $2->addArray( $4 ); }2192 | '(' old_function_array ')' multi_array_dimension// redundant parenthesis2193 { $$ = $2->addArray( $4 ); }2194 | '(' old_function_array ')'// redundant parenthesis2195 { $$ = $2; }2196 ;2183 '(' old_function_ptr ')' array_dimension 2184 { $$ = $2->addArray( $4 ); } 2185 | '(' old_function_array ')' multi_array_dimension // redundant parenthesis 2186 { $$ = $2->addArray( $4 ); } 2187 | '(' old_function_array ')' // redundant parenthesis 2188 { $$ = $2; } 2189 ; 2197 2190 2198 2191 // This pattern parses a declaration for a variable or function prototype that redefines a typedef name, e.g.: … … 2207 2200 2208 2201 typedef_redeclarator: 2209 paren_typedef attribute_list_opt2210 | typedef_ptr2211 | typedef_array attribute_list_opt2212 | typedef_function attribute_list_opt2213 ;2202 paren_typedef attribute_list_opt 2203 | typedef_ptr 2204 | typedef_array attribute_list_opt 2205 | typedef_function attribute_list_opt 2206 ; 2214 2207 2215 2208 paren_typedef: 2216 TYPEDEFname2217 {2218 typedefTable.setNextIdentifier( *($1) );2219 $$ = DeclarationNode::newName( $1 );2220 }2221 | '(' paren_typedef ')'2222 { $$ = $2; }2223 ;2209 TYPEDEFname 2210 { 2211 typedefTable.setNextIdentifier( *($1) ); 2212 $$ = DeclarationNode::newName( $1 ); 2213 } 2214 | '(' paren_typedef ')' 2215 { $$ = $2; } 2216 ; 2224 2217 2225 2218 typedef_ptr: 2226 '*' typedef_redeclarator2227 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2228 | '*' type_qualifier_list typedef_redeclarator2229 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2230 | '(' typedef_ptr ')'2231 { $$ = $2; }2232 ;2219 '*' typedef_redeclarator 2220 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2221 | '*' type_qualifier_list typedef_redeclarator 2222 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2223 | '(' typedef_ptr ')' 2224 { $$ = $2; } 2225 ; 2233 2226 2234 2227 typedef_array: 2235 paren_typedef array_dimension2236 { $$ = $1->addArray( $2 ); }2237 | '(' typedef_ptr ')' array_dimension2238 { $$ = $2->addArray( $4 ); }2239 | '(' typedef_array ')' multi_array_dimension// redundant parenthesis2240 { $$ = $2->addArray( $4 ); }2241 | '(' typedef_array ')'// redundant parenthesis2242 { $$ = $2; }2243 ;2228 paren_typedef array_dimension 2229 { $$ = $1->addArray( $2 ); } 2230 | '(' typedef_ptr ')' array_dimension 2231 { $$ = $2->addArray( $4 ); } 2232 | '(' typedef_array ')' multi_array_dimension // redundant parenthesis 2233 { $$ = $2->addArray( $4 ); } 2234 | '(' typedef_array ')' // redundant parenthesis 2235 { $$ = $2; } 2236 ; 2244 2237 2245 2238 typedef_function: 2246 paren_typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2247 { $$ = $1->addParamList( $4 ); }2248 | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2249 { $$ = $2->addParamList( $6 ); }2250 | '(' typedef_function ')'// redundant parenthesis2251 { $$ = $2; }2252 ;2239 paren_typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2240 { $$ = $1->addParamList( $4 ); } 2241 | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2242 { $$ = $2->addParamList( $6 ); } 2243 | '(' typedef_function ')' // redundant parenthesis 2244 { $$ = $2; } 2245 ; 2253 2246 2254 2247 // This pattern parses a declaration for a parameter variable or function prototype that is not redefining a … … 2258 2251 2259 2252 identifier_parameter_declarator: 2260 paren_identifier attribute_list_opt2261 | identifier_parameter_ptr2262 | identifier_parameter_array attribute_list_opt2263 | identifier_parameter_function attribute_list_opt2264 ;2253 paren_identifier attribute_list_opt 2254 | identifier_parameter_ptr 2255 | identifier_parameter_array attribute_list_opt 2256 | identifier_parameter_function attribute_list_opt 2257 ; 2265 2258 2266 2259 identifier_parameter_ptr: 2267 '*' identifier_parameter_declarator2268 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2269 | '*' type_qualifier_list identifier_parameter_declarator2270 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2271 | '(' identifier_parameter_ptr ')'2272 { $$ = $2; }2273 ;2260 '*' identifier_parameter_declarator 2261 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2262 | '*' type_qualifier_list identifier_parameter_declarator 2263 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2264 | '(' identifier_parameter_ptr ')' 2265 { $$ = $2; } 2266 ; 2274 2267 2275 2268 identifier_parameter_array: 2276 paren_identifier array_parameter_dimension2277 { $$ = $1->addArray( $2 ); }2278 | '(' identifier_parameter_ptr ')' array_dimension2279 { $$ = $2->addArray( $4 ); }2280 | '(' identifier_parameter_array ')' multi_array_dimension // redundant parenthesis2281 { $$ = $2->addArray( $4 ); }2282 | '(' identifier_parameter_array ')'// redundant parenthesis2283 { $$ = $2; }2284 ;2269 paren_identifier array_parameter_dimension 2270 { $$ = $1->addArray( $2 ); } 2271 | '(' identifier_parameter_ptr ')' array_dimension 2272 { $$ = $2->addArray( $4 ); } 2273 | '(' identifier_parameter_array ')' multi_array_dimension // redundant parenthesis 2274 { $$ = $2->addArray( $4 ); } 2275 | '(' identifier_parameter_array ')' // redundant parenthesis 2276 { $$ = $2; } 2277 ; 2285 2278 2286 2279 identifier_parameter_function: 2287 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2288 { $$ = $1->addParamList( $4 ); }2289 | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2290 { $$ = $2->addParamList( $6 ); }2291 | '(' identifier_parameter_function ')'// redundant parenthesis2292 { $$ = $2; }2293 ;2280 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2281 { $$ = $1->addParamList( $4 ); } 2282 | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2283 { $$ = $2->addParamList( $6 ); } 2284 | '(' identifier_parameter_function ')' // redundant parenthesis 2285 { $$ = $2; } 2286 ; 2294 2287 2295 2288 // This pattern parses a declaration for a parameter variable or function prototype that is redefining a … … 2309 2302 // 2310 2303 // typedef float T; 2311 // int f( int ( T [5] ) ); // see abstract_parameter_declarator2304 // int f( int ( T [5] ) ); // see abstract_parameter_declarator 2312 2305 // int g( int ( T ( int ) ) ); // see abstract_parameter_declarator 2313 2306 // int f( int f1( T a[5] ) ); // see identifier_parameter_declarator … … 2320 2313 2321 2314 typedef_parameter_redeclarator: 2322 typedef attribute_list_opt2323 | typedef_parameter_ptr2324 | typedef_parameter_array attribute_list_opt2325 | typedef_parameter_function attribute_list_opt2326 ;2315 typedef attribute_list_opt 2316 | typedef_parameter_ptr 2317 | typedef_parameter_array attribute_list_opt 2318 | typedef_parameter_function attribute_list_opt 2319 ; 2327 2320 2328 2321 typedef: 2329 TYPEDEFname2330 {2331 typedefTable.setNextIdentifier( *($1) );2332 $$ = DeclarationNode::newName( $1 );2333 }2334 ;2322 TYPEDEFname 2323 { 2324 typedefTable.setNextIdentifier( *($1) ); 2325 $$ = DeclarationNode::newName( $1 ); 2326 } 2327 ; 2335 2328 2336 2329 typedef_parameter_ptr: 2337 '*' typedef_parameter_redeclarator2338 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2339 | '*' type_qualifier_list typedef_parameter_redeclarator2340 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2341 | '(' typedef_parameter_ptr ')'2342 { $$ = $2; }2343 ;2330 '*' typedef_parameter_redeclarator 2331 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2332 | '*' type_qualifier_list typedef_parameter_redeclarator 2333 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2334 | '(' typedef_parameter_ptr ')' 2335 { $$ = $2; } 2336 ; 2344 2337 2345 2338 typedef_parameter_array: 2346 typedef array_parameter_dimension2347 { $$ = $1->addArray( $2 ); }2348 | '(' typedef_parameter_ptr ')' array_parameter_dimension2349 { $$ = $2->addArray( $4 ); }2350 ;2339 typedef array_parameter_dimension 2340 { $$ = $1->addArray( $2 ); } 2341 | '(' typedef_parameter_ptr ')' array_parameter_dimension 2342 { $$ = $2->addArray( $4 ); } 2343 ; 2351 2344 2352 2345 typedef_parameter_function: 2353 typedef '(' push parameter_type_list_opt pop ')'// empty parameter list OBSOLESCENT (see 3)2354 { $$ = $1->addParamList( $4 ); }2355 | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2356 { $$ = $2->addParamList( $6 ); }2357 ;2346 typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2347 { $$ = $1->addParamList( $4 ); } 2348 | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2349 { $$ = $2->addParamList( $6 ); } 2350 ; 2358 2351 2359 2352 // This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no … … 2367 2360 2368 2361 abstract_declarator: 2369 abstract_ptr2370 | abstract_array attribute_list_opt2371 | abstract_function attribute_list_opt2372 ;2362 abstract_ptr 2363 | abstract_array attribute_list_opt 2364 | abstract_function attribute_list_opt 2365 ; 2373 2366 2374 2367 abstract_ptr: 2375 '*'2376 { $$ = DeclarationNode::newPointer( 0 ); }2377 | '*' type_qualifier_list2378 { $$ = DeclarationNode::newPointer( $2 ); }2379 | '*' abstract_declarator2380 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2381 | '*' type_qualifier_list abstract_declarator2382 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2383 | '(' abstract_ptr ')'2384 { $$ = $2; }2385 ;2368 '*' 2369 { $$ = DeclarationNode::newPointer( 0 ); } 2370 | '*' type_qualifier_list 2371 { $$ = DeclarationNode::newPointer( $2 ); } 2372 | '*' abstract_declarator 2373 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2374 | '*' type_qualifier_list abstract_declarator 2375 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2376 | '(' abstract_ptr ')' 2377 { $$ = $2; } 2378 ; 2386 2379 2387 2380 abstract_array: 2388 array_dimension2389 | '(' abstract_ptr ')' array_dimension2390 { $$ = $2->addArray( $4 ); }2391 | '(' abstract_array ')' multi_array_dimension// redundant parenthesis2392 { $$ = $2->addArray( $4 ); }2393 | '(' abstract_array ')'// redundant parenthesis2394 { $$ = $2; }2395 ;2381 array_dimension 2382 | '(' abstract_ptr ')' array_dimension 2383 { $$ = $2->addArray( $4 ); } 2384 | '(' abstract_array ')' multi_array_dimension // redundant parenthesis 2385 { $$ = $2->addArray( $4 ); } 2386 | '(' abstract_array ')' // redundant parenthesis 2387 { $$ = $2; } 2388 ; 2396 2389 2397 2390 abstract_function: 2398 '(' push parameter_type_list_opt pop ')'// empty parameter list OBSOLESCENT (see 3)2399 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }2400 | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2401 { $$ = $2->addParamList( $6 ); }2402 | '(' abstract_function ')'// redundant parenthesis2403 { $$ = $2; }2404 ;2391 '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2392 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); } 2393 | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2394 { $$ = $2->addParamList( $6 ); } 2395 | '(' abstract_function ')' // redundant parenthesis 2396 { $$ = $2; } 2397 ; 2405 2398 2406 2399 array_dimension: 2407 // Only the first dimension can be empty.2408 '[' push pop ']'2409 { $$ = DeclarationNode::newArray( 0, 0, false ); }2410 | '[' push pop ']' multi_array_dimension2411 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $5 ); }2412 | multi_array_dimension2413 ;2400 // Only the first dimension can be empty. 2401 '[' push pop ']' 2402 { $$ = DeclarationNode::newArray( 0, 0, false ); } 2403 | '[' push pop ']' multi_array_dimension 2404 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $5 ); } 2405 | multi_array_dimension 2406 ; 2414 2407 2415 2408 multi_array_dimension: 2416 '[' push assignment_expression pop ']'2417 { $$ = DeclarationNode::newArray( $3, 0, false ); }2418 | '[' push '*' pop ']' // C992419 { $$ = DeclarationNode::newVarArray( 0 ); }2420 | multi_array_dimension '[' push assignment_expression pop ']'2421 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }2422 | multi_array_dimension '[' push '*' pop ']' // C992423 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }2424 ;2409 '[' push assignment_expression pop ']' 2410 { $$ = DeclarationNode::newArray( $3, 0, false ); } 2411 | '[' push '*' pop ']' // C99 2412 { $$ = DeclarationNode::newVarArray( 0 ); } 2413 | multi_array_dimension '[' push assignment_expression pop ']' 2414 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); } 2415 | multi_array_dimension '[' push '*' pop ']' // C99 2416 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } 2417 ; 2425 2418 2426 2419 // This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no … … 2434 2427 2435 2428 abstract_parameter_declarator: 2436 abstract_parameter_ptr2437 | abstract_parameter_array attribute_list_opt2438 | abstract_parameter_function attribute_list_opt2439 ;2429 abstract_parameter_ptr 2430 | abstract_parameter_array attribute_list_opt 2431 | abstract_parameter_function attribute_list_opt 2432 ; 2440 2433 2441 2434 abstract_parameter_ptr: 2442 '*'2443 { $$ = DeclarationNode::newPointer( 0 ); }2444 | '*' type_qualifier_list2445 { $$ = DeclarationNode::newPointer( $2 ); }2446 | '*' abstract_parameter_declarator2447 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2448 | '*' type_qualifier_list abstract_parameter_declarator2449 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2450 | '(' abstract_parameter_ptr ')'2451 { $$ = $2; }2452 ;2435 '*' 2436 { $$ = DeclarationNode::newPointer( 0 ); } 2437 | '*' type_qualifier_list 2438 { $$ = DeclarationNode::newPointer( $2 ); } 2439 | '*' abstract_parameter_declarator 2440 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2441 | '*' type_qualifier_list abstract_parameter_declarator 2442 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2443 | '(' abstract_parameter_ptr ')' 2444 { $$ = $2; } 2445 ; 2453 2446 2454 2447 abstract_parameter_array: 2455 array_parameter_dimension2456 | '(' abstract_parameter_ptr ')' array_parameter_dimension2457 { $$ = $2->addArray( $4 ); }2458 | '(' abstract_parameter_array ')' multi_array_dimension // redundant parenthesis2459 { $$ = $2->addArray( $4 ); }2460 | '(' abstract_parameter_array ')'// redundant parenthesis2461 { $$ = $2; }2462 ;2448 array_parameter_dimension 2449 | '(' abstract_parameter_ptr ')' array_parameter_dimension 2450 { $$ = $2->addArray( $4 ); } 2451 | '(' abstract_parameter_array ')' multi_array_dimension // redundant parenthesis 2452 { $$ = $2->addArray( $4 ); } 2453 | '(' abstract_parameter_array ')' // redundant parenthesis 2454 { $$ = $2; } 2455 ; 2463 2456 2464 2457 abstract_parameter_function: 2465 '(' push parameter_type_list_opt pop ')'// empty parameter list OBSOLESCENT (see 3)2466 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }2467 | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2468 { $$ = $2->addParamList( $6 ); }2469 | '(' abstract_parameter_function ')'// redundant parenthesis2470 { $$ = $2; }2471 ;2458 '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2459 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); } 2460 | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2461 { $$ = $2->addParamList( $6 ); } 2462 | '(' abstract_parameter_function ')' // redundant parenthesis 2463 { $$ = $2; } 2464 ; 2472 2465 2473 2466 array_parameter_dimension: 2474 // Only the first dimension can be empty or have qualifiers.2475 array_parameter_1st_dimension2476 | array_parameter_1st_dimension multi_array_dimension2477 { $$ = $1->addArray( $2 ); }2478 | multi_array_dimension2479 ;2467 // Only the first dimension can be empty or have qualifiers. 2468 array_parameter_1st_dimension 2469 | array_parameter_1st_dimension multi_array_dimension 2470 { $$ = $1->addArray( $2 ); } 2471 | multi_array_dimension 2472 ; 2480 2473 2481 2474 // The declaration of an array parameter has additional syntax over arrays in normal variable declarations: … … 2486 2479 2487 2480 array_parameter_1st_dimension: 2488 '[' push pop ']'2489 { $$ = DeclarationNode::newArray( 0, 0, false ); }2490 // multi_array_dimension handles the '[' '*' ']' case2491 | '[' push type_qualifier_list '*' pop ']'// remaining C992492 { $$ = DeclarationNode::newVarArray( $3 ); }2493 | '[' push type_qualifier_list pop ']'2494 { $$ = DeclarationNode::newArray( 0, $3, false ); }2495 // multi_array_dimension handles the '[' assignment_expression ']' case2496 | '[' push type_qualifier_list assignment_expression pop ']'2497 { $$ = DeclarationNode::newArray( $4, $3, false ); }2498 | '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'2499 { $$ = DeclarationNode::newArray( $5, $4, true ); }2500 | '[' push type_qualifier_list STATIC assignment_expression pop ']'2501 { $$ = DeclarationNode::newArray( $5, $3, true ); }2502 ;2481 '[' push pop ']' 2482 { $$ = DeclarationNode::newArray( 0, 0, false ); } 2483 // multi_array_dimension handles the '[' '*' ']' case 2484 | '[' push type_qualifier_list '*' pop ']' // remaining C99 2485 { $$ = DeclarationNode::newVarArray( $3 ); } 2486 | '[' push type_qualifier_list pop ']' 2487 { $$ = DeclarationNode::newArray( 0, $3, false ); } 2488 // multi_array_dimension handles the '[' assignment_expression ']' case 2489 | '[' push type_qualifier_list assignment_expression pop ']' 2490 { $$ = DeclarationNode::newArray( $4, $3, false ); } 2491 | '[' push STATIC type_qualifier_list_opt assignment_expression pop ']' 2492 { $$ = DeclarationNode::newArray( $5, $4, true ); } 2493 | '[' push type_qualifier_list STATIC assignment_expression pop ']' 2494 { $$ = DeclarationNode::newArray( $5, $3, true ); } 2495 ; 2503 2496 2504 2497 // This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type … … 2511 2504 2512 2505 variable_abstract_declarator: 2513 variable_abstract_ptr2514 | variable_abstract_array attribute_list_opt2515 | variable_abstract_function attribute_list_opt2516 ;2506 variable_abstract_ptr 2507 | variable_abstract_array attribute_list_opt 2508 | variable_abstract_function attribute_list_opt 2509 ; 2517 2510 2518 2511 variable_abstract_ptr: 2519 '*'2520 { $$ = DeclarationNode::newPointer( 0 ); }2521 | '*' type_qualifier_list2522 { $$ = DeclarationNode::newPointer( $2 ); }2523 | '*' variable_abstract_declarator2524 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }2525 | '*' type_qualifier_list variable_abstract_declarator2526 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }2527 | '(' variable_abstract_ptr ')'2528 { $$ = $2; }2529 ;2512 '*' 2513 { $$ = DeclarationNode::newPointer( 0 ); } 2514 | '*' type_qualifier_list 2515 { $$ = DeclarationNode::newPointer( $2 ); } 2516 | '*' variable_abstract_declarator 2517 { $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); } 2518 | '*' type_qualifier_list variable_abstract_declarator 2519 { $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); } 2520 | '(' variable_abstract_ptr ')' 2521 { $$ = $2; } 2522 ; 2530 2523 2531 2524 variable_abstract_array: 2532 array_dimension2533 | '(' variable_abstract_ptr ')' array_dimension2534 { $$ = $2->addArray( $4 ); }2535 | '(' variable_abstract_array ')' multi_array_dimension // redundant parenthesis2536 { $$ = $2->addArray( $4 ); }2537 | '(' variable_abstract_array ')'// redundant parenthesis2538 { $$ = $2; }2539 ;2525 array_dimension 2526 | '(' variable_abstract_ptr ')' array_dimension 2527 { $$ = $2->addArray( $4 ); } 2528 | '(' variable_abstract_array ')' multi_array_dimension // redundant parenthesis 2529 { $$ = $2->addArray( $4 ); } 2530 | '(' variable_abstract_array ')' // redundant parenthesis 2531 { $$ = $2; } 2532 ; 2540 2533 2541 2534 variable_abstract_function: 2542 '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)2543 { $$ = $2->addParamList( $6 ); }2544 | '(' variable_abstract_function ')'// redundant parenthesis2545 { $$ = $2; }2546 ;2535 '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2536 { $$ = $2->addParamList( $6 ); } 2537 | '(' variable_abstract_function ')' // redundant parenthesis 2538 { $$ = $2; } 2539 ; 2547 2540 2548 2541 // This pattern parses a new-style declaration for a parameter variable or function prototype that is either … … 2550 2543 2551 2544 new_identifier_parameter_declarator_tuple: // CFA 2552 new_identifier_parameter_declarator_no_tuple2553 | new_abstract_tuple2554 | type_qualifier_list new_abstract_tuple2555 { $$ = $2->addQualifiers( $1 ); }2556 ;2545 new_identifier_parameter_declarator_no_tuple 2546 | new_abstract_tuple 2547 | type_qualifier_list new_abstract_tuple 2548 { $$ = $2->addQualifiers( $1 ); } 2549 ; 2557 2550 2558 2551 new_identifier_parameter_declarator_no_tuple: // CFA 2559 new_identifier_parameter_ptr2560 | new_identifier_parameter_array2561 ;2552 new_identifier_parameter_ptr 2553 | new_identifier_parameter_array 2554 ; 2562 2555 2563 2556 new_identifier_parameter_ptr: // CFA 2564 '*' type_specifier2565 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }2566 | type_qualifier_list '*' type_specifier2567 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }2568 | '*' new_abstract_function2569 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }2570 | type_qualifier_list '*' new_abstract_function2571 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }2572 | '*' new_identifier_parameter_declarator_tuple2573 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }2574 | type_qualifier_list '*' new_identifier_parameter_declarator_tuple2575 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }2576 ;2557 '*' type_specifier 2558 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 2559 | type_qualifier_list '*' type_specifier 2560 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); } 2561 | '*' new_abstract_function 2562 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 2563 | type_qualifier_list '*' new_abstract_function 2564 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); } 2565 | '*' new_identifier_parameter_declarator_tuple 2566 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 2567 | type_qualifier_list '*' new_identifier_parameter_declarator_tuple 2568 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); } 2569 ; 2577 2570 2578 2571 new_identifier_parameter_array: // CFA 2579 // Only the first dimension can be empty or have qualifiers. Empty dimension must be factored2580 // out dueto shift/reduce conflict with new-style empty (void) function return type.2581 '[' push pop ']' type_specifier2582 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2583 | new_array_parameter_1st_dimension type_specifier2584 { $$ = $2->addNewArray( $1 ); }2585 | '[' push pop ']' multi_array_dimension type_specifier2586 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2587 | new_array_parameter_1st_dimension multi_array_dimension type_specifier2588 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }2589 | multi_array_dimension type_specifier2590 { $$ = $2->addNewArray( $1 ); }2591 | '[' push pop ']' new_identifier_parameter_ptr2592 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2593 | new_array_parameter_1st_dimension new_identifier_parameter_ptr2594 { $$ = $2->addNewArray( $1 ); }2595 | '[' push pop ']' multi_array_dimension new_identifier_parameter_ptr2596 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2597 | new_array_parameter_1st_dimension multi_array_dimension new_identifier_parameter_ptr2598 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }2599 | multi_array_dimension new_identifier_parameter_ptr2600 { $$ = $2->addNewArray( $1 ); }2601 ;2572 // Only the first dimension can be empty or have qualifiers. Empty dimension must be factored out due 2573 // to shift/reduce conflict with new-style empty (void) function return type. 2574 '[' push pop ']' type_specifier 2575 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2576 | new_array_parameter_1st_dimension type_specifier 2577 { $$ = $2->addNewArray( $1 ); } 2578 | '[' push pop ']' multi_array_dimension type_specifier 2579 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2580 | new_array_parameter_1st_dimension multi_array_dimension type_specifier 2581 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } 2582 | multi_array_dimension type_specifier 2583 { $$ = $2->addNewArray( $1 ); } 2584 | '[' push pop ']' new_identifier_parameter_ptr 2585 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2586 | new_array_parameter_1st_dimension new_identifier_parameter_ptr 2587 { $$ = $2->addNewArray( $1 ); } 2588 | '[' push pop ']' multi_array_dimension new_identifier_parameter_ptr 2589 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2590 | new_array_parameter_1st_dimension multi_array_dimension new_identifier_parameter_ptr 2591 { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); } 2592 | multi_array_dimension new_identifier_parameter_ptr 2593 { $$ = $2->addNewArray( $1 ); } 2594 ; 2602 2595 2603 2596 new_array_parameter_1st_dimension: 2604 '[' push type_qualifier_list '*' pop ']'// remaining C992605 { $$ = DeclarationNode::newVarArray( $3 ); }2606 | '[' push type_qualifier_list assignment_expression pop ']'2607 { $$ = DeclarationNode::newArray( $4, $3, false ); }2608 | '[' push declaration_qualifier_list assignment_expression pop ']'2609 // declaration_qualifier_list must be used because of shift/reduce conflict with2610 // assignment_expression, so a semantic check is necessary to preclude them as a2611 // type_qualifier cannotappear in this context.2612 { $$ = DeclarationNode::newArray( $4, $3, true ); }2613 | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'2614 { $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }2615 ;2597 '[' push type_qualifier_list '*' pop ']' // remaining C99 2598 { $$ = DeclarationNode::newVarArray( $3 ); } 2599 | '[' push type_qualifier_list assignment_expression pop ']' 2600 { $$ = DeclarationNode::newArray( $4, $3, false ); } 2601 | '[' push declaration_qualifier_list assignment_expression pop ']' 2602 // declaration_qualifier_list must be used because of shift/reduce conflict with 2603 // assignment_expression, so a semantic check is necessary to preclude them as a type_qualifier cannot 2604 // appear in this context. 2605 { $$ = DeclarationNode::newArray( $4, $3, true ); } 2606 | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']' 2607 { $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); } 2608 ; 2616 2609 2617 2610 // This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is … … 2637 2630 2638 2631 new_abstract_declarator_tuple: // CFA 2639 new_abstract_tuple2640 | type_qualifier_list new_abstract_tuple2641 { $$ = $2->addQualifiers( $1 ); }2642 | new_abstract_declarator_no_tuple2643 ;2632 new_abstract_tuple 2633 | type_qualifier_list new_abstract_tuple 2634 { $$ = $2->addQualifiers( $1 ); } 2635 | new_abstract_declarator_no_tuple 2636 ; 2644 2637 2645 2638 new_abstract_declarator_no_tuple: // CFA 2646 new_abstract_ptr2647 | new_abstract_array2648 ;2639 new_abstract_ptr 2640 | new_abstract_array 2641 ; 2649 2642 2650 2643 new_abstract_ptr: // CFA 2651 '*' type_specifier2652 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }2653 | type_qualifier_list '*' type_specifier2654 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }2655 | '*' new_abstract_function2656 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }2657 | type_qualifier_list '*' new_abstract_function2658 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }2659 | '*' new_abstract_declarator_tuple2660 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }2661 | type_qualifier_list '*' new_abstract_declarator_tuple2662 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }2663 ;2644 '*' type_specifier 2645 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 2646 | type_qualifier_list '*' type_specifier 2647 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); } 2648 | '*' new_abstract_function 2649 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 2650 | type_qualifier_list '*' new_abstract_function 2651 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); } 2652 | '*' new_abstract_declarator_tuple 2653 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } 2654 | type_qualifier_list '*' new_abstract_declarator_tuple 2655 { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); } 2656 ; 2664 2657 2665 2658 new_abstract_array: // CFA 2666 // Only the first dimension can be empty. Empty dimension must be factored out due to2667 // shift/reduceconflict with empty (void) function return type.2668 '[' push pop ']' type_specifier2669 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2670 | '[' push pop ']' multi_array_dimension type_specifier2671 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2672 | multi_array_dimension type_specifier2673 { $$ = $2->addNewArray( $1 ); }2674 | '[' push pop ']' new_abstract_ptr2675 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2676 | '[' push pop ']' multi_array_dimension new_abstract_ptr2677 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }2678 | multi_array_dimension new_abstract_ptr2679 { $$ = $2->addNewArray( $1 ); }2680 ;2659 // Only the first dimension can be empty. Empty dimension must be factored out due to shift/reduce 2660 // conflict with empty (void) function return type. 2661 '[' push pop ']' type_specifier 2662 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2663 | '[' push pop ']' multi_array_dimension type_specifier 2664 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2665 | multi_array_dimension type_specifier 2666 { $$ = $2->addNewArray( $1 ); } 2667 | '[' push pop ']' new_abstract_ptr 2668 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2669 | '[' push pop ']' multi_array_dimension new_abstract_ptr 2670 { $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } 2671 | multi_array_dimension new_abstract_ptr 2672 { $$ = $2->addNewArray( $1 ); } 2673 ; 2681 2674 2682 2675 new_abstract_tuple: // CFA 2683 '[' push new_abstract_parameter_list pop ']'2684 { $$ = DeclarationNode::newTuple( $3 ); }2685 ;2676 '[' push new_abstract_parameter_list pop ']' 2677 { $$ = DeclarationNode::newTuple( $3 ); } 2678 ; 2686 2679 2687 2680 new_abstract_function: // CFA 2688 '[' push pop ']' '(' new_parameter_type_list_opt ')'2689 { $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); }2690 | new_abstract_tuple '(' push new_parameter_type_list_opt pop ')'2691 { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }2692 | new_function_return '(' push new_parameter_type_list_opt pop ')'2693 { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }2694 ;2681 '[' push pop ']' '(' new_parameter_type_list_opt ')' 2682 { $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); } 2683 | new_abstract_tuple '(' push new_parameter_type_list_opt pop ')' 2684 { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); } 2685 | new_function_return '(' push new_parameter_type_list_opt pop ')' 2686 { $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); } 2687 ; 2695 2688 2696 2689 // 1) ISO/IEC 9899:1999 Section 6.7.2(2) : "At least one type specifier shall be given in the declaration … … 2711 2704 2712 2705 comma_opt: // redundant comma 2713 // empty2714 | ','2715 ;2706 // empty 2707 | ',' 2708 ; 2716 2709 2717 2710 assignment_opt: 2718 // empty2719 { $$ = 0; }2720 | '=' assignment_expression2721 { $$ = $2; }2722 ;2711 // empty 2712 { $$ = 0; } 2713 | '=' assignment_expression 2714 { $$ = $2; } 2715 ; 2723 2716 2724 2717 %%
Note:
See TracChangeset
for help on using the changeset viewer.