github.com/aleksi/cc@v0.0.0-20171021204506-4b6ffb9b7827/parser.yy (about) 1 %{ 2 // Copyright 2016 The CC Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 // Based on [0], 6.10. Substantial portions of expression AST size 7 // optimizations are from [2], license of which follows. 8 9 // ---------------------------------------------------------------------------- 10 11 // Copyright 2013 The Go Authors. All rights reserved. 12 // Use of this source code is governed by a BSD-style 13 // license that can be found in the LICENSE file. 14 15 // This grammar is derived from the C grammar in the 'ansitize' 16 // program, which carried this notice: 17 // 18 // Copyright (c) 2006 Russ Cox, 19 // Massachusetts Institute of Technology 20 // 21 // Permission is hereby granted, free of charge, to any person 22 // obtaining a copy of this software and associated 23 // documentation files (the "Software"), to deal in the 24 // Software without restriction, including without limitation 25 // the rights to use, copy, modify, merge, publish, distribute, 26 // sublicense, and/or sell copies of the Software, and to 27 // permit persons to whom the Software is furnished to do so, 28 // subject to the following conditions: 29 // 30 // The above copyright notice and this permission notice shall 31 // be included in all copies or substantial portions of the 32 // Software. 33 // 34 // The software is provided "as is", without warranty of any 35 // kind, express or implied, including but not limited to the 36 // warranties of merchantability, fitness for a particular 37 // purpose and noninfringement. In no event shall the authors 38 // or copyright holders be liable for any claim, damages or 39 // other liability, whether in an action of contract, tort or 40 // otherwise, arising from, out of or in connection with the 41 // software or the use or other dealings in the software. 42 43 package cc 44 45 import ( 46 "fmt" 47 48 "github.com/cznic/xc" 49 "github.com/cznic/golex/lex" 50 ) 51 %} 52 53 %union { 54 Token xc.Token 55 groupPart Node 56 node Node 57 toks PPTokenList 58 } 59 60 %token 61 /*yy:token "'%c'" */ CHARCONST "character constant" 62 /*yy:token "1.%d" */ FLOATCONST "floating-point constant" 63 /*yy:token "%c" */ IDENTIFIER "identifier" 64 /*yy:token "%c" */ IDENTIFIER_NONREPL "non replaceable identifier" 65 /*yy:token "%c(" */ IDENTIFIER_LPAREN "identifier immediatelly followed by '('" 66 /*yy:token "%d" */ INTCONST "integer constant" 67 /*yy:token "L'%c'" */ LONGCHARCONST "long character constant" 68 /*yy:token "L\"%c\"" */ LONGSTRINGLITERAL "long string constant" 69 /*yy:token "<%c.h>" */ PPHEADER_NAME "header name" 70 /*yy:token "%d" */ PPNUMBER "preprocessing number" 71 /*yy:token "\"%c\"" */ STRINGLITERAL "string literal" 72 73 /*yy:token "\U00100000" */ PREPROCESSING_FILE 1048576 "preprocessing file prefix" // 0x100000 = 1048576 74 /*yy:token "\U00100001" */ CONSTANT_EXPRESSION 1048577 "constant expression prefix" 75 /*yy:token "\U00100002" */ TRANSLATION_UNIT 1048578 "translation unit prefix" 76 77 /*yy:token "\n#define" */ PPDEFINE "#define" 78 /*yy:token "\n#elif" */ PPELIF "#elif" 79 /*yy:token "\n#else" */ PPELSE "#else" 80 /*yy:token "\n#endif" */ PPENDIF "#endif" 81 /*yy:token "\n#error" */ PPERROR "#error" 82 /*yy:token "\n#" */ PPHASH_NL "#" 83 /*yy:token "\n#if" */ PPIF "#if" 84 /*yy:token "\n#ifdef" */ PPIFDEF "#ifdef" 85 /*yy:token "\n#ifndef" */ PPIFNDEF "#ifndef" 86 /*yy:token "\n#include" */ PPINCLUDE "#include" 87 /*yy:token "\n#include_next" */ PPINCLUDE_NEXT "#include_next" 88 /*yy:token "\n#line" */ PPLINE "#line" 89 /*yy:token "\n#foo" */ PPNONDIRECTIVE "#foo" 90 /*yy:token "other_%c" */ PPOTHER "ppother" 91 /*yy:token "\n##" */ PPPASTE "##" 92 /*yy:token "\n#pragma" */ PPPRAGMA "#pragma" 93 /*yy:token "\n#undef" */ PPUNDEF "#undef" 94 95 ADDASSIGN "+=" 96 ALIGNOF "_Alignof" 97 ANDAND "&&" 98 ANDASSIGN "&=" 99 ARROW "->" 100 ASM "asm" 101 AUTO "auto" 102 BOOL "_Bool" 103 BREAK "break" 104 CASE "case" 105 CHAR "char" 106 COMPLEX "_Complex" 107 CONST "const" 108 CONTINUE "continue" 109 DDD "..." 110 DEC "--" 111 DEFAULT "default" 112 DIVASSIGN "/=" 113 DO "do" 114 DOUBLE "double" 115 ELSE "else" 116 ENUM "enum" 117 EQ "==" 118 EXTERN "extern" 119 FLOAT "float" 120 FOR "for" 121 GEQ ">=" 122 GOTO "goto" 123 IF "if" 124 INC "++" 125 INLINE "inline" 126 INT "int" 127 LEQ "<=" 128 LONG "long" 129 LSH "<<" 130 LSHASSIGN "<<=" 131 MODASSIGN "%=" 132 MULASSIGN "*=" 133 NEQ "!=" 134 NORETURN "_Noreturn" 135 ORASSIGN "|=" 136 OROR "||" 137 REGISTER "register" 138 RESTRICT "restrict" 139 RETURN "return" 140 RSH ">>" 141 RSHASSIGN ">>=" 142 SHORT "short" 143 SIGNED "signed" 144 SIZEOF "sizeof" 145 STATIC "static" 146 STATIC_ASSERT "_Static_assert" 147 STRUCT "struct" 148 SUBASSIGN "-=" 149 SWITCH "switch" 150 TYPEDEF "typedef" 151 TYPEDEFNAME "typedefname" 152 TYPEOF "typeof" 153 UNION "union" 154 UNSIGNED "unsigned" 155 VOID "void" 156 VOLATILE "volatile" 157 WHILE "while" 158 XORASSIGN "^=" 159 160 %type <toks> 161 PPTokenList "token list" 162 PPTokenListOpt "optional token list" 163 ReplacementList "replacement list" 164 TextLine "text line" 165 166 %type <groupPart> 167 GroupPart "group part" 168 169 %type <node> 170 AbstractDeclarator "abstract declarator" 171 AbstractDeclaratorOpt "optional abstract declarator" 172 ArgumentExpressionList "argument expression list" 173 ArgumentExpressionListOpt "optional argument expression list" 174 AssemblerInstructions "assembler instructions" 175 AssemblerOperand "assembler operand" 176 AssemblerOperands "assembler operands" 177 AssemblerStatement "assembler statement" 178 AssemblerSymbolicNameOpt "optional assembler symbolic name" 179 BasicAssemblerStatement "basic assembler statement" 180 BlockItem "block item" 181 BlockItemList "block item list" 182 BlockItemListOpt "optional block item list" 183 Clobbers "clobbers" 184 CommaOpt "optional comma" 185 CompoundStatement "compound statement" 186 ConstantExpression "constant expression" 187 ControlLine "control line" 188 Declaration "declaration" 189 DeclarationList "declaration list" 190 DeclarationListOpt "optional declaration list" 191 DeclarationSpecifiers "declaration specifiers" 192 DeclarationSpecifiersOpt "optional declaration specifiers" 193 Declarator "declarator" 194 DeclaratorOpt "optional declarator" 195 Designation "designation" 196 DesignationOpt "optional designation" 197 Designator "designator" 198 DesignatorList "designator list" 199 DirectAbstractDeclarator "direct abstract declarator" 200 DirectAbstractDeclaratorOpt "optional direct abstract declarator" 201 DirectDeclarator "direct declarator" 202 ElifGroup "elif group" 203 ElifGroupList "elif group list" 204 ElifGroupListOpt "optional elif group list" 205 ElseGroup "else group" 206 ElseGroupOpt "optional else group" 207 EndifLine "endif line" 208 EnumSpecifier "enum specifier" 209 EnumerationConstant "enumearation constant" 210 Enumerator "enumerator" 211 EnumeratorList "enumerator list" 212 Expression "expression" 213 ExpressionList "expression list" 214 ExpressionListOpt "optional expression list" 215 ExpressionOpt "optional expression" 216 ExpressionStatement "expression statement" 217 ExternalDeclaration "external declaration" 218 FunctionDefinition "function definition" 219 FunctionBody "function body" 220 FunctionSpecifier "function specifier" 221 GroupList "group list" 222 GroupListOpt "optional group list" 223 IdentifierList "identifier list" 224 IdentifierListOpt "optional identifier list" 225 IdentifierOpt "optional identifier" 226 IfGroup "if group" 227 IfSection "if section" 228 InitDeclarator "init declarator" 229 InitDeclaratorList "init declarator list" 230 InitDeclaratorListOpt "optional init declarator list" 231 Initializer "initializer" 232 InitializerList "initializer list" 233 IterationStatement "iteration statement" 234 JumpStatement "jump statement" 235 LabeledStatement "labeled statement" 236 ParameterDeclaration "parameter declaration" 237 ParameterList "parameter list" 238 ParameterTypeList "parameter type list" 239 ParameterTypeListOpt "optional parameter type list" 240 Pointer "pointer" 241 PointerOpt "optional pointer" 242 PreprocessingFile "preprocessing file" 243 SelectionStatement "selection statement" 244 SpecifierQualifierList "specifier qualifier list" 245 SpecifierQualifierListOpt "optional specifier qualifier list" 246 Statement "statement" 247 StaticAssertDeclaration "static assert declaration" 248 StorageClassSpecifier "storage class specifier" 249 StructDeclaration "struct declaration" 250 StructDeclarationList "struct declaration list" 251 StructDeclarator "struct declarator" 252 StructDeclaratorList "struct declarator list" 253 StructOrUnion "struct-or-union" 254 StructOrUnionSpecifier "struct-or-union specifier" 255 TranslationUnit "translation unit" 256 TypeName "type name" 257 TypeQualifier "type qualifier" 258 TypeQualifierList "type qualifier list" 259 TypeQualifierListOpt "optional type qualifier list" 260 TypeSpecifier "type specifier" 261 VolatileOpt "optional volatile" 262 263 264 %precedence NOSEMI 265 %precedence ';' 266 267 %precedence NOELSE 268 %precedence ELSE 269 270 %right '=' ADDASSIGN ANDASSIGN DIVASSIGN LSHASSIGN MODASSIGN MULASSIGN 271 ORASSIGN RSHASSIGN SUBASSIGN XORASSIGN 272 273 %right ':' '?' 274 %left OROR 275 %left ANDAND 276 %left '|' 277 %left '^' 278 %left '&' 279 %left EQ NEQ 280 %left '<' '>' GEQ LEQ 281 %left LSH RSH 282 %left '+' '-' 283 %left '%' '*' '/' 284 %precedence CAST 285 %left '!' '~' SIZEOF UNARY 286 %right '(' '.' '[' ARROW DEC INC 287 288 %% 289 290 //yy:ignore 291 Start: 292 PREPROCESSING_FILE 293 { 294 lx.preprocessingFile = nil 295 } 296 PreprocessingFile 297 { 298 lx.preprocessingFile = $3.(*PreprocessingFile) 299 } 300 | CONSTANT_EXPRESSION 301 { 302 lx.constantExpression = nil 303 } 304 ConstantExpression 305 { 306 lx.constantExpression = $3.(*ConstantExpression) 307 } 308 | TRANSLATION_UNIT 309 { 310 lx.translationUnit = nil 311 } 312 TranslationUnit 313 { 314 if lx.report.Errors(false) == nil && lx.scope.kind != ScopeFile { 315 panic("internal error") 316 } 317 318 lx.translationUnit = $3.(*TranslationUnit).reverse() 319 lx.translationUnit.Declarations = lx.scope 320 } 321 322 // [0](6.4.4.3) 323 EnumerationConstant: 324 IDENTIFIER 325 326 // [0](6.5.2) 327 ArgumentExpressionList: 328 Expression 329 | ArgumentExpressionList ',' Expression 330 331 ArgumentExpressionListOpt: 332 /* empty */ {} 333 | ArgumentExpressionList 334 335 // [0](6.5.16) 336 //yy:field BinOpType Type // The type operands of binary expression are coerced into, if different from Type. 337 //yy:field Type Type // Type of expression. 338 //yy:field Value interface{} // Non nil for certain constant expressions. 339 //yy:field scope *Bindings // Case 0: IDENTIFIER resolution scope. 340 Expression: 341 IDENTIFIER %prec NOSEMI 342 { 343 lhs.scope = lx.scope 344 } 345 | CHARCONST 346 | FLOATCONST 347 | INTCONST 348 | LONGCHARCONST 349 | LONGSTRINGLITERAL 350 | STRINGLITERAL 351 | '(' ExpressionList ')' 352 | Expression '[' ExpressionList ']' 353 | Expression '(' ArgumentExpressionListOpt ')' 354 { 355 o := lhs.ArgumentExpressionListOpt 356 if o == nil { 357 break 358 } 359 360 if lhs.Expression.Case == 0 { // IDENTIFIER 361 if lx.tweaks.enableBuiltinConstantP &&lhs.Expression.Token.Val == idBuiltinConstantP { 362 break 363 } 364 365 b := lhs.Expression.scope.Lookup(NSIdentifiers, lhs.Expression.Token.Val) 366 if b.Node == nil && lx.tweaks.enableImplicitFuncDef { 367 for l := o.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList { 368 l.Expression.eval(lx) 369 } 370 break 371 } 372 } 373 374 lhs.Expression.eval(lx) 375 for l := o.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList { 376 l.Expression.eval(lx) 377 } 378 } 379 | Expression '.' IDENTIFIER 380 | Expression "->" IDENTIFIER 381 | Expression "++" 382 | Expression "--" 383 | '(' TypeName ')' '{' InitializerList CommaOpt '}' 384 | "++" Expression 385 | "--" Expression 386 | '&' Expression %prec UNARY 387 | '*' Expression %prec UNARY 388 | '+' Expression %prec UNARY 389 | '-' Expression %prec UNARY 390 | '~' Expression 391 | '!' Expression 392 | "sizeof" Expression 393 | "sizeof" '(' TypeName ')' %prec SIZEOF 394 | '(' TypeName ')' Expression %prec CAST 395 | Expression '*' Expression 396 | Expression '/' Expression 397 | Expression '%' Expression 398 | Expression '+' Expression 399 | Expression '-' Expression 400 | Expression "<<" Expression 401 | Expression ">>" Expression 402 | Expression '<' Expression 403 | Expression '>' Expression 404 | Expression "<=" Expression 405 | Expression ">=" Expression 406 | Expression "==" Expression 407 | Expression "!=" Expression 408 | Expression '&' Expression 409 | Expression '^' Expression 410 | Expression '|' Expression 411 | Expression "&&" Expression 412 | Expression "||" Expression 413 | Expression '?' ExpressionList ':' Expression 414 | Expression '=' Expression 415 | Expression "*=" Expression 416 | Expression "/=" Expression 417 | Expression "%=" Expression 418 | Expression "+=" Expression 419 | Expression "-=" Expression 420 | Expression "<<=" Expression 421 | Expression ">>=" Expression 422 | Expression "&=" Expression 423 | Expression "^=" Expression 424 | Expression "|=" Expression 425 | "_Alignof" '(' TypeName ')' 426 | '(' CompoundStatement ')' 427 | "&&" IDENTIFIER 428 { 429 if !lx.tweaks.enableComputedGotos { 430 lx.report.Err(lhs.Pos(), "computed gotos not enabled") 431 } 432 } 433 | Expression '?' ':' Expression 434 { 435 if !lx.tweaks.enableOmitConditionalOperand { 436 lx.report.Err(lhs.Pos(), "omitting conditional operand not enabled") 437 } 438 } 439 440 441 ExpressionOpt: 442 /* empty */ {} 443 | Expression 444 { 445 lhs.Expression.eval(lx) 446 } 447 448 // [0](6.5.17) 449 //yy:field Type Type // Type of expression. 450 //yy:field Value interface{} // Non nil for certain constant expressions. 451 //yy:list 452 ExpressionList: 453 Expression 454 | ExpressionList ',' Expression 455 456 ExpressionListOpt: 457 /* empty */ {} 458 | ExpressionList 459 { 460 lhs.ExpressionList.eval(lx) 461 } 462 463 // [0](6.6) 464 //yy:field Type Type // Type of expression. 465 //yy:field Value interface{} // Non nil for certain constant expressions. 466 //yy:field toks []xc.Token // 467 ConstantExpression: 468 { 469 lx.constExprToks = []xc.Token{lx.last} 470 } 471 Expression 472 { 473 lhs.Value, lhs.Type = lhs.Expression.eval(lx) 474 if lhs.Value == nil { 475 lx.report.Err(lhs.Pos(), "not a constant expression") 476 } 477 l := lx.constExprToks 478 lhs.toks = l[:len(l)-1] 479 lx.constExprToks = nil 480 } 481 482 // [0](6.7) 483 //yy:field declarator *Declarator // Synthetic declarator when InitDeclaratorListOpt is nil. 484 Declaration: 485 DeclarationSpecifiers InitDeclaratorListOpt ';' 486 { 487 ts0 := lhs.DeclarationSpecifiers.typeSpecifiers() 488 if ts0 == 0 && lx.tweaks.enableImplicitIntType { 489 lhs.DeclarationSpecifiers.typeSpecifier = tsEncode(tsInt) 490 } 491 ts := tsDecode(lhs.DeclarationSpecifiers.typeSpecifiers()) 492 ok := false 493 for _, v := range ts { 494 if v == tsStructSpecifier || v == tsUnionSpecifier { 495 ok = true 496 break 497 } 498 } 499 if ok { 500 s := lhs.DeclarationSpecifiers 501 d := &Declarator{specifier: s} 502 dd := &DirectDeclarator{ 503 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 504 declarator: d, 505 idScope: lx.scope, 506 specifier: s, 507 } 508 d.DirectDeclarator = dd 509 d.setFull(lx) 510 for l := lhs.DeclarationSpecifiers; l != nil; { 511 ts := l.TypeSpecifier 512 if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}' 513 ts.StructOrUnionSpecifier.declarator = d 514 break 515 } 516 517 if o := l.DeclarationSpecifiersOpt; o != nil { 518 l = o.DeclarationSpecifiers 519 continue 520 } 521 522 break 523 } 524 } 525 526 o := lhs.InitDeclaratorListOpt 527 if o != nil { 528 break 529 } 530 531 s := lhs.DeclarationSpecifiers 532 d := &Declarator{specifier: s} 533 dd := &DirectDeclarator{ 534 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 535 declarator: d, 536 idScope: lx.scope, 537 specifier: s, 538 } 539 d.DirectDeclarator = dd 540 d.setFull(lx) 541 lhs.declarator = d 542 } 543 | StaticAssertDeclaration 544 545 // [0](6.7) 546 //yy:field attr int // tsInline, tsTypedefName, ... 547 //yy:field typeSpecifier int // Encoded combination of tsVoid, tsInt, ... 548 DeclarationSpecifiers: 549 StorageClassSpecifier DeclarationSpecifiersOpt 550 { 551 lx.scope.specifier = lhs 552 a := lhs.StorageClassSpecifier 553 b := lhs.DeclarationSpecifiersOpt 554 if b == nil { 555 lhs.attr = a.attr 556 break 557 } 558 559 if a.attr&b.attr != 0 { 560 lx.report.Err(a.Pos(), "invalid storage class specifier") 561 break 562 } 563 564 lhs.attr = a.attr|b.attr 565 lhs.typeSpecifier = b.typeSpecifier 566 if lhs.StorageClassSpecifier.Case != 0 /* "typedef" */ && lhs.IsTypedef() { 567 lx.report.Err(a.Pos(), "invalid storage class specifier") 568 } 569 } 570 | TypeSpecifier DeclarationSpecifiersOpt 571 { 572 lx.scope.specifier = lhs 573 a := lhs.TypeSpecifier 574 b := lhs.DeclarationSpecifiersOpt 575 if b == nil { 576 lhs.typeSpecifier = a.typeSpecifier 577 break 578 } 579 580 lhs.attr = b.attr 581 tsb := tsDecode(b.typeSpecifier) 582 if len(tsb) == 1 && tsb[0] == tsTypedefName && lx.tweaks.allowCompatibleTypedefRedefinitions { 583 tsb[0] = 0 584 } 585 ts := tsEncode(append(tsDecode(a.typeSpecifier), tsb...)...) 586 if _, ok := tsValid[ts]; !ok { 587 ts = tsEncode(tsInt) 588 lx.report.Err(a.Pos(), "invalid type specifier") 589 } 590 lhs.typeSpecifier = ts 591 } 592 | TypeQualifier DeclarationSpecifiersOpt 593 { 594 lx.scope.specifier = lhs 595 a := lhs.TypeQualifier 596 b := lhs.DeclarationSpecifiersOpt 597 if b == nil { 598 lhs.attr = a.attr 599 break 600 } 601 602 if a.attr&b.attr != 0 { 603 lx.report.Err(a.Pos(), "invalid type qualifier") 604 break 605 } 606 607 lhs.attr = a.attr|b.attr 608 lhs.typeSpecifier = b.typeSpecifier 609 if lhs.IsTypedef() { 610 lx.report.Err(a.Pos(), "invalid type qualifier") 611 } 612 } 613 | FunctionSpecifier DeclarationSpecifiersOpt 614 { 615 lx.scope.specifier = lhs 616 a := lhs.FunctionSpecifier 617 b := lhs.DeclarationSpecifiersOpt 618 if b == nil { 619 lhs.attr = a.attr 620 break 621 } 622 623 if a.attr&b.attr != 0 { 624 lx.report.Err(a.Pos(), "invalid function specifier") 625 break 626 } 627 628 lhs.attr = a.attr|b.attr 629 lhs.typeSpecifier = b.typeSpecifier 630 if lhs.IsTypedef() { 631 lx.report.Err(a.Pos(), "invalid function specifier") 632 } 633 } 634 635 //yy:field attr int // tsInline, tsTypedefName, ... 636 //yy:field typeSpecifier int // Encoded combination of tsVoid, tsInt, ... 637 DeclarationSpecifiersOpt: 638 /* empty */ {} 639 | DeclarationSpecifiers 640 { 641 lhs.attr = lhs.DeclarationSpecifiers.attr 642 lhs.typeSpecifier = lhs.DeclarationSpecifiers.typeSpecifier 643 } 644 645 // [0](6.7) 646 InitDeclaratorList: 647 InitDeclarator 648 | InitDeclaratorList ',' InitDeclarator 649 650 InitDeclaratorListOpt: 651 /* empty */ {} 652 | InitDeclaratorList 653 654 // [0](6.7) 655 InitDeclarator: 656 Declarator 657 { 658 lhs.Declarator.setFull(lx) 659 } 660 | Declarator 661 { 662 d := $1.(*Declarator) 663 d.setFull(lx) 664 } 665 '=' Initializer 666 { 667 d := lhs.Declarator 668 lhs.Initializer.typeCheck(&d.Type, d.Type, lhs.Declarator.specifier.IsStatic(), lx) 669 if d.Type.Specifier().IsExtern() { 670 id, _ := d.Identifier() 671 lx.report.Err(d.Pos(), "'%s' initialized and declared 'extern'", dict.S(id)) 672 } 673 } 674 675 // [0](6.7.1) 676 //yy:field attr int 677 StorageClassSpecifier: 678 "typedef" 679 { 680 lhs.attr = saTypedef 681 } 682 | "extern" 683 { 684 lhs.attr = saExtern 685 } 686 | "static" 687 { 688 lhs.attr = saStatic 689 } 690 | "auto" 691 { 692 lhs.attr = saAuto 693 } 694 | "register" 695 { 696 lhs.attr = saRegister 697 } 698 699 // [0](6.7.2) 700 //yy:field scope *Bindings // If case TYPEDEFNAME. 701 //yy:field typeSpecifier int // Encoded combination of tsVoid, tsInt, ... 702 //yy:field Type Type // Type of typeof. 703 TypeSpecifier: 704 "void" 705 { 706 lhs.typeSpecifier = tsEncode(tsVoid) 707 } 708 | "char" 709 { 710 lhs.typeSpecifier = tsEncode(tsChar) 711 } 712 | "short" 713 { 714 lhs.typeSpecifier = tsEncode(tsShort) 715 } 716 | "int" 717 { 718 lhs.typeSpecifier = tsEncode(tsInt) 719 } 720 | "long" 721 { 722 lhs.typeSpecifier = tsEncode(tsLong) 723 } 724 | "float" 725 { 726 lhs.typeSpecifier = tsEncode(tsFloat) 727 } 728 | "double" 729 { 730 lhs.typeSpecifier = tsEncode(tsDouble) 731 } 732 | "signed" 733 { 734 lhs.typeSpecifier = tsEncode(tsSigned) 735 } 736 | "unsigned" 737 { 738 lhs.typeSpecifier = tsEncode(tsUnsigned) 739 } 740 | "_Bool" 741 { 742 lhs.typeSpecifier = tsEncode(tsBool) 743 } 744 | "_Complex" 745 { 746 lhs.typeSpecifier = tsEncode(tsComplex) 747 } 748 | StructOrUnionSpecifier 749 { 750 lhs.typeSpecifier = tsEncode(lhs.StructOrUnionSpecifier.typeSpecifiers()) 751 } 752 | EnumSpecifier 753 { 754 lhs.typeSpecifier = tsEncode(tsEnumSpecifier) 755 } 756 /*yy:example "\U00100002 typedef int i; i j;" */ 757 | TYPEDEFNAME 758 { 759 lhs.typeSpecifier = tsEncode(tsTypedefName) 760 _, lhs.scope = lx.scope.Lookup2(NSIdentifiers, lhs.Token.Val) 761 } 762 | "typeof" '(' Expression ')' 763 { 764 lhs.typeSpecifier = tsEncode(tsTypeof) 765 _, lhs.Type = lhs.Expression.eval(lx) 766 } 767 | "typeof" '(' TypeName ')' 768 { 769 lhs.typeSpecifier = tsEncode(tsTypeof) 770 lhs.Type = undefined 771 if t := lhs.TypeName.Type; t != nil { 772 lhs.Type = t 773 } 774 } 775 776 // [0](6.7.2.1) 777 //yy:example "\U00100002 struct { int i; } (" 778 //yy:field alignOf int 779 //yy:field declarator *Declarator // Synthetic declarator when tagged struct/union defined inline. 780 //yy:field scope *Bindings 781 //yy:field sizeOf int 782 StructOrUnionSpecifier: 783 StructOrUnion IdentifierOpt 784 '{' 785 { 786 if o := $2.(*IdentifierOpt); o != nil { 787 lx.scope.declareStructTag(o.Token, lx.report) 788 } 789 lx.pushScope(ScopeMembers) 790 lx.scope.isUnion = $1.(*StructOrUnion).Case == 1 // "union" 791 lx.scope.prevStructDeclarator = nil 792 } 793 StructDeclarationList '}' 794 { 795 sc := lx.scope 796 lhs.scope = sc 797 if sc.bitOffset != 0 { 798 finishBitField(lhs, lx) 799 } 800 801 i := 0 802 var bt Type 803 var d *Declarator 804 for l := lhs.StructDeclarationList; l != nil; l = l.StructDeclarationList { 805 for l := l.StructDeclaration.StructDeclaratorList; l != nil; l = l.StructDeclaratorList { 806 switch sd := l.StructDeclarator; sd.Case { 807 case 0: // Declarator 808 d = sd.Declarator 809 case 1: // DeclaratorOpt ':' ConstantExpression 810 if o := sd.DeclaratorOpt; o != nil { 811 x := o.Declarator 812 if x.bitOffset == 0 { 813 d = x 814 bt = lx.scope.bitFieldTypes[i] 815 i++ 816 } 817 x.bitFieldType = bt 818 } 819 } 820 } 821 } 822 lx.scope.bitFieldTypes = nil 823 824 lhs.alignOf = sc.maxAlign 825 switch { 826 case sc.isUnion: 827 lhs.sizeOf = align(sc.maxSize, sc.maxAlign) 828 default: 829 off := sc.offset 830 lhs.sizeOf = align(sc.offset, sc.maxAlign) 831 if d != nil { 832 d.padding = lhs.sizeOf-off 833 } 834 } 835 836 lx.popScope(lhs.Token2) 837 if o := lhs.IdentifierOpt; o != nil { 838 lx.scope.defineStructTag(o.Token, lhs, lx.report) 839 } 840 } 841 | StructOrUnion IDENTIFIER 842 { 843 lx.scope.declareStructTag(lhs.Token, lx.report) 844 lhs.scope = lx.scope 845 } 846 | StructOrUnion IdentifierOpt '{' '}' 847 { 848 if !lx.tweaks.enableEmptyStructs { 849 lx.report.Err(lhs.Token.Pos(), "empty structs/unions not allowed") 850 } 851 if o := $2.(*IdentifierOpt); o != nil { 852 lx.scope.declareStructTag(o.Token, lx.report) 853 } 854 lx.scope.isUnion = $1.(*StructOrUnion).Case == 1 // "union" 855 lx.scope.prevStructDeclarator = nil 856 lhs.alignOf = 1 857 lhs.sizeOf = 0 858 if o := lhs.IdentifierOpt; o != nil { 859 lx.scope.defineStructTag(o.Token, lhs, lx.report) 860 } 861 } 862 863 // [0](6.7.2.1) 864 StructOrUnion: 865 "struct" 866 | "union" 867 868 // [0](6.7.2.1) 869 StructDeclarationList: 870 StructDeclaration 871 | StructDeclarationList StructDeclaration 872 873 // [0](6.7.2.1) 874 StructDeclaration: 875 SpecifierQualifierList StructDeclaratorList ';' 876 { 877 s := lhs.SpecifierQualifierList 878 if k := s.kind(); k != Struct && k != Union { 879 break 880 } 881 882 d := &Declarator{specifier: s} 883 dd := &DirectDeclarator{ 884 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 885 declarator: d, 886 idScope: lx.scope, 887 specifier: s, 888 } 889 d.DirectDeclarator = dd 890 d.setFull(lx) 891 for l := lhs.SpecifierQualifierList; l != nil; { 892 ts := l.TypeSpecifier 893 if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}' 894 ts.StructOrUnionSpecifier.declarator = d 895 break 896 } 897 898 if o := l.SpecifierQualifierListOpt; o != nil { 899 l = o.SpecifierQualifierList 900 continue 901 } 902 903 break 904 } 905 } 906 | SpecifierQualifierList ';' 907 { 908 s := lhs.SpecifierQualifierList 909 if !lx.tweaks.enableAnonymousStructFields { 910 lx.report.Err(lhs.Token.Pos(), "unnamed fields not allowed") 911 } else if k := s.kind(); k != Struct && k != Union { 912 lx.report.Err(lhs.Token.Pos(), "only unnamed structs and unions are allowed") 913 break 914 } 915 916 d := &Declarator{specifier: s} 917 dd := &DirectDeclarator{ 918 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 919 declarator: d, 920 idScope: lx.scope, 921 specifier: s, 922 } 923 d.DirectDeclarator = dd 924 d.setFull(lx) 925 926 // we have no struct declarators to parse, so we have to create the case of one implicit declarator 927 // because else the size of anonymous members is not included in the struct size! 928 dummy := &StructDeclarator{Declarator: d} 929 dummy.post(lx) 930 931 for l := lhs.SpecifierQualifierList; l != nil; { 932 ts := l.TypeSpecifier 933 if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}' 934 ts.StructOrUnionSpecifier.declarator = d 935 break 936 } 937 938 if o := l.SpecifierQualifierListOpt; o != nil { 939 l = o.SpecifierQualifierList 940 continue 941 } 942 943 break 944 } 945 } 946 | StaticAssertDeclaration 947 948 // [0](6.7.2.1) 949 //yy:field attr int // tsInline, tsTypedefName, ... 950 //yy:field typeSpecifier int // Encoded combination of tsVoid, tsInt, ... 951 SpecifierQualifierList: 952 TypeSpecifier SpecifierQualifierListOpt 953 { 954 lx.scope.specifier = lhs 955 a := lhs.TypeSpecifier 956 b := lhs.SpecifierQualifierListOpt 957 if b == nil { 958 lhs.typeSpecifier = a.typeSpecifier 959 break 960 } 961 962 lhs.attr = b.attr 963 ts := tsEncode(append(tsDecode(a.typeSpecifier), tsDecode(b.typeSpecifier)...)...) 964 if _, ok := tsValid[ts]; !ok { 965 lx.report.Err(a.Pos(), "invalid type specifier") 966 break 967 } 968 969 lhs.typeSpecifier = ts 970 } 971 | TypeQualifier SpecifierQualifierListOpt 972 { 973 lx.scope.specifier = lhs 974 a := lhs.TypeQualifier 975 b := lhs.SpecifierQualifierListOpt 976 if b == nil { 977 lhs.attr = a.attr 978 break 979 } 980 981 if a.attr&b.attr != 0 { 982 lx.report.Err(a.Pos(), "invalid type qualifier") 983 break 984 } 985 986 lhs.attr = a.attr|b.attr 987 lhs.typeSpecifier = b.typeSpecifier 988 } 989 990 //yy:field attr int // tsInline, tsTypedefName, ... 991 //yy:field typeSpecifier int // Encoded combination of tsVoid, tsInt, ... 992 SpecifierQualifierListOpt: 993 /* empty */ {} 994 | SpecifierQualifierList 995 { 996 lhs.attr = lhs.SpecifierQualifierList.attr 997 lhs.typeSpecifier = lhs.SpecifierQualifierList.typeSpecifier 998 } 999 1000 // [0](6.7.2.1) 1001 StructDeclaratorList: 1002 StructDeclarator 1003 | StructDeclaratorList ',' StructDeclarator 1004 1005 // [0](6.7.2.1) 1006 StructDeclarator: 1007 Declarator 1008 { 1009 lhs.Declarator.setFull(lx) 1010 lhs.post(lx) 1011 } 1012 | DeclaratorOpt ':' ConstantExpression 1013 { 1014 m := lx.model 1015 e := lhs.ConstantExpression 1016 if e.Value == nil { 1017 e.Value, e.Type = m.value2(1, m.IntType) 1018 } 1019 if !IsIntType(e.Type) { 1020 lx.report.Err(e.Pos(), "bit field width not an integer (have '%s')", e.Type) 1021 e.Value, e.Type = m.value2(1, m.IntType) 1022 } 1023 if o := lhs.DeclaratorOpt; o != nil { 1024 o.Declarator.setFull(lx) 1025 } 1026 lhs.post(lx) 1027 } 1028 1029 CommaOpt: 1030 /* empty */ {} 1031 | ',' 1032 1033 // [0](6.7.2.2) 1034 //yy:field unsigned bool 1035 EnumSpecifier: 1036 "enum" IdentifierOpt 1037 { 1038 if o := $2.(*IdentifierOpt); o != nil { 1039 lx.scope.declareEnumTag(o.Token, lx.report) 1040 } 1041 lx.iota = 0 1042 } 1043 '{' EnumeratorList CommaOpt '}' 1044 { 1045 if o := lhs.IdentifierOpt; o != nil { 1046 lx.scope.defineEnumTag(o.Token, lhs, lx.report) 1047 } 1048 if !lx.tweaks.enableUnsignedEnums { 1049 break 1050 } 1051 1052 lhs.unsigned = true 1053 loop: 1054 for l := lhs.EnumeratorList; l != nil; l = l.EnumeratorList { 1055 switch e := l.Enumerator; x := e.Value.(type) { 1056 case int32: 1057 if x < 0 { 1058 lhs.unsigned = false 1059 break loop 1060 } 1061 case int64: 1062 if x < 0 { 1063 lhs.unsigned = false 1064 break loop 1065 } 1066 default: 1067 panic(fmt.Errorf("%s: TODO Enumerator.Value type %T", position(e.Pos()), x)) 1068 } 1069 } 1070 } 1071 | "enum" IDENTIFIER 1072 { 1073 lx.scope.declareEnumTag(lhs.Token2, lx.report) 1074 } 1075 1076 // [0](6.7.2.2) 1077 EnumeratorList: 1078 Enumerator 1079 | EnumeratorList ',' Enumerator 1080 1081 // [0](6.7.2.2) 1082 //yy:field Value interface{} // Enumerator's value. 1083 Enumerator: 1084 EnumerationConstant 1085 { 1086 m := lx.model 1087 v := m.MustConvert(lx.iota, m.IntType) 1088 lhs.Value = v 1089 lx.scope.defineEnumConst(lx, lhs.EnumerationConstant.Token, v) 1090 } 1091 | EnumerationConstant '=' ConstantExpression 1092 { 1093 m := lx.model 1094 e := lhs.ConstantExpression 1095 var v interface{} 1096 // [0], 6.7.2.2 1097 // The expression that defines the value of an enumeration 1098 // constant shall be an integer constant expression that has a 1099 // value representable as an int. 1100 switch { 1101 case !IsIntType(e.Type): 1102 lx.report.Err(e.Pos(), "not an integer constant expression (have '%s')", e.Type) 1103 v = m.MustConvert(int32(0), m.IntType) 1104 default: 1105 var ok bool 1106 if v, ok = m.enumValueToInt(e.Value); !ok { 1107 lx.report.Err(e.Pos(), "overflow in enumeration value: %v", e.Value) 1108 } 1109 } 1110 1111 lhs.Value = v 1112 lx.scope.defineEnumConst(lx, lhs.EnumerationConstant.Token, v) 1113 } 1114 1115 // [0](6.7.3) 1116 //yy:field attr int // tsInline, tsTypedefName, ... 1117 TypeQualifier: 1118 "const" 1119 { 1120 lhs.attr = saConst 1121 } 1122 | "restrict" 1123 { 1124 lhs.attr = saRestrict 1125 } 1126 | "volatile" 1127 { 1128 lhs.attr = saVolatile 1129 } 1130 1131 // [0](6.7.4) 1132 //yy:field attr int // tsInline, tsTypedefName, ... 1133 FunctionSpecifier: 1134 "inline" 1135 { 1136 lhs.attr = saInline 1137 } 1138 | "_Noreturn" 1139 { 1140 lhs.attr = saNoreturn 1141 } 1142 1143 // [0](6.7.5) 1144 //yy:field Linkage Linkage 1145 //yy:field Type Type 1146 //yy:field bitFieldType Type 1147 //yy:field bitFieldGroup int 1148 //yy:field bitOffset int 1149 //yy:field bits int 1150 //yy:field offsetOf int 1151 //yy:field padding int 1152 //yy:field specifier Specifier 1153 Declarator: 1154 PointerOpt DirectDeclarator 1155 { 1156 lhs.specifier = lx.scope.specifier 1157 lhs.DirectDeclarator.declarator = lhs 1158 } 1159 1160 DeclaratorOpt: 1161 /* empty */ {} 1162 | Declarator 1163 1164 // [0](6.7.5) 1165 //yy:field EnumVal interface{} // Non nil if DD declares an enumeration constant. 1166 //yy:field declarator *Declarator 1167 //yy:field elements int 1168 //yy:field idScope *Bindings // Of case 0: IDENTIFIER. 1169 //yy:field paramsScope *Bindings 1170 //yy:field parent *DirectDeclarator 1171 //yy:field prev *Binding // Existing declaration in same scope, if any. 1172 //yy:field specifier Specifier 1173 //yy:field visible *Binding // Existing declaration of same ident visible in same scope, if any and this DD has storage class extrn. 1174 DirectDeclarator: 1175 IDENTIFIER 1176 { 1177 lhs.specifier = lx.scope.specifier 1178 lx.scope.declareIdentifier(lhs.Token, lhs, lx.report) 1179 lhs.idScope = lx.scope 1180 } 1181 | '(' Declarator ')' 1182 { 1183 lhs.Declarator.specifier = nil 1184 lhs.Declarator.DirectDeclarator.parent = lhs 1185 } 1186 | DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']' 1187 { 1188 lhs.elements = -1 1189 if o := lhs.ExpressionOpt; o != nil { 1190 var err error 1191 if lhs.elements, err = elements(o.Expression.eval(lx)); err != nil { 1192 lx.report.Err(o.Expression.Pos(), "%s", err) 1193 } 1194 1195 } 1196 lhs.DirectDeclarator.parent = lhs 1197 } 1198 | DirectDeclarator '[' "static" TypeQualifierListOpt Expression ']' 1199 { 1200 var err error 1201 if lhs.elements, err = elements(lhs.Expression.eval(lx)); err != nil { 1202 lx.report.Err(lhs.Expression.Pos(), "%s", err) 1203 } 1204 lhs.DirectDeclarator.parent = lhs 1205 } 1206 | DirectDeclarator '[' TypeQualifierList "static" Expression ']' 1207 { 1208 var err error 1209 if lhs.elements, err = elements(lhs.Expression.eval(lx)); err != nil { 1210 lx.report.Err(lhs.Expression.Pos(), "%s", err) 1211 } 1212 lhs.DirectDeclarator.parent = lhs 1213 } 1214 | DirectDeclarator '[' TypeQualifierListOpt '*' ']' 1215 { 1216 lhs.DirectDeclarator.parent = lhs 1217 lhs.elements = -1 1218 } 1219 | DirectDeclarator '(' 1220 { 1221 lx.pushScope(ScopeParams) 1222 } 1223 ParameterTypeList ')' 1224 { 1225 lhs.paramsScope, _ = lx.popScope(lhs.Token2) 1226 lhs.DirectDeclarator.parent = lhs 1227 } 1228 | DirectDeclarator '(' IdentifierListOpt ')' 1229 { 1230 lhs.DirectDeclarator.parent = lhs 1231 } 1232 1233 // [0](6.7.5) 1234 Pointer: 1235 '*' TypeQualifierListOpt 1236 | '*' TypeQualifierListOpt Pointer 1237 1238 PointerOpt: 1239 /* empty */ {} 1240 | Pointer 1241 1242 // [0](6.7.5) 1243 //yy:field attr int // tsInline, tsTypedefName, ... 1244 TypeQualifierList: 1245 TypeQualifier 1246 { 1247 lhs.attr = lhs.TypeQualifier.attr 1248 } 1249 | TypeQualifierList TypeQualifier 1250 { 1251 a := lhs.TypeQualifierList 1252 b := lhs.TypeQualifier 1253 if a.attr&b.attr != 0 { 1254 lx.report.Err(b.Pos(), "invalid type qualifier") 1255 break 1256 } 1257 1258 lhs.attr = a.attr|b.attr 1259 } 1260 1261 TypeQualifierListOpt: 1262 /* empty */ {} 1263 | TypeQualifierList 1264 1265 // [0](6.7.5) 1266 //yy:field params []Parameter 1267 ParameterTypeList: 1268 ParameterList 1269 { 1270 lhs.post() 1271 } 1272 | ParameterList ',' "..." 1273 { 1274 lhs.post() 1275 } 1276 1277 ParameterTypeListOpt: 1278 /* empty */ {} 1279 | ParameterTypeList 1280 1281 // [0](6.7.5) 1282 ParameterList: 1283 ParameterDeclaration 1284 | ParameterList ',' ParameterDeclaration 1285 1286 // [0](6.7.5) 1287 //yy:field declarator *Declarator 1288 /*TODO 1289 A declaration of a parameter as ‘‘function returning type’’ shall be adjusted 1290 to ‘‘pointer to function returning type’’, as in 6.3.2.1. 1291 */ 1292 ParameterDeclaration: 1293 DeclarationSpecifiers Declarator 1294 { 1295 lhs.Declarator.setFull(lx) 1296 lhs.declarator = lhs.Declarator 1297 } 1298 | DeclarationSpecifiers AbstractDeclaratorOpt 1299 { 1300 if o := lhs.AbstractDeclaratorOpt; o != nil { 1301 lhs.declarator = o.AbstractDeclarator.declarator 1302 lhs.declarator.setFull(lx) 1303 break 1304 } 1305 1306 d := &Declarator{ 1307 specifier: lx.scope.specifier, 1308 DirectDeclarator: &DirectDeclarator{ 1309 Case: 0, // IDENTIFIER 1310 }, 1311 } 1312 d.DirectDeclarator.declarator = d 1313 lhs.declarator = d 1314 d.setFull(lx) 1315 } 1316 1317 // [0](6.7.5) 1318 IdentifierList: 1319 IDENTIFIER 1320 | IdentifierList ',' IDENTIFIER 1321 1322 //yy:field params []Parameter 1323 IdentifierListOpt: 1324 /* empty */ {} 1325 | IdentifierList 1326 1327 IdentifierOpt: 1328 /* empty */ {} 1329 | IDENTIFIER 1330 1331 // [0](6.7.6) 1332 //yy:field Type Type 1333 //yy:field declarator *Declarator 1334 //yy:field scope *Bindings 1335 TypeName: 1336 { 1337 lx.pushScope(ScopeBlock) 1338 } 1339 SpecifierQualifierList AbstractDeclaratorOpt 1340 { 1341 if o := lhs.AbstractDeclaratorOpt; o != nil { 1342 lhs.declarator = o.AbstractDeclarator.declarator 1343 } else { 1344 d := &Declarator{ 1345 specifier: lhs.SpecifierQualifierList, 1346 DirectDeclarator: &DirectDeclarator{ 1347 Case: 0, // IDENTIFIER 1348 idScope: lx.scope, 1349 }, 1350 } 1351 d.DirectDeclarator.declarator = d 1352 lhs.declarator = d 1353 } 1354 lhs.Type = lhs.declarator.setFull(lx) 1355 lhs.scope = lx.scope 1356 lx.popScope(xc.Token{}) 1357 } 1358 1359 // [0](6.7.6) 1360 //yy:field declarator *Declarator 1361 AbstractDeclarator: 1362 Pointer 1363 { 1364 d := &Declarator{ 1365 specifier: lx.scope.specifier, 1366 PointerOpt: &PointerOpt { 1367 Pointer: lhs.Pointer, 1368 }, 1369 DirectDeclarator: &DirectDeclarator{ 1370 Case: 0, // IDENTIFIER 1371 idScope: lx.scope, 1372 }, 1373 } 1374 d.DirectDeclarator.declarator = d 1375 lhs.declarator = d 1376 } 1377 | PointerOpt DirectAbstractDeclarator 1378 { 1379 d := &Declarator{ 1380 specifier: lx.scope.specifier, 1381 PointerOpt: lhs.PointerOpt, 1382 DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator, 1383 } 1384 d.DirectDeclarator.declarator = d 1385 lhs.declarator = d 1386 } 1387 1388 AbstractDeclaratorOpt: 1389 /* empty */ {} 1390 | AbstractDeclarator 1391 1392 // [0](6.7.6) 1393 //yy:field directDeclarator *DirectDeclarator 1394 //yy:field paramsScope *Bindings 1395 DirectAbstractDeclarator: 1396 '(' AbstractDeclarator ')' 1397 { 1398 lhs.AbstractDeclarator.declarator.specifier = nil 1399 lhs.directDeclarator = &DirectDeclarator{ 1400 Case: 1, // '(' Declarator ')' 1401 Declarator: lhs.AbstractDeclarator.declarator, 1402 } 1403 lhs.AbstractDeclarator.declarator.DirectDeclarator.parent = lhs.directDeclarator 1404 } 1405 | DirectAbstractDeclaratorOpt '[' ExpressionOpt ']' 1406 { 1407 nElements := -1 1408 if o := lhs.ExpressionOpt; o != nil { 1409 var err error 1410 if nElements, err = elements(o.Expression.eval(lx)); err != nil { 1411 lx.report.Err(o.Expression.Pos(), "%s", err) 1412 } 1413 } 1414 var dd *DirectDeclarator 1415 switch o := lhs.DirectAbstractDeclaratorOpt; { 1416 case o == nil: 1417 dd = &DirectDeclarator{ 1418 Case: 0, // IDENTIFIER 1419 } 1420 default: 1421 dd = o.DirectAbstractDeclarator.directDeclarator 1422 } 1423 lhs.directDeclarator = &DirectDeclarator{ 1424 Case: 2, // DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']' 1425 DirectDeclarator: dd, 1426 ExpressionOpt: lhs.ExpressionOpt, 1427 elements: nElements, 1428 } 1429 dd.parent = lhs.directDeclarator 1430 } 1431 | DirectAbstractDeclaratorOpt '[' TypeQualifierList ExpressionOpt ']' 1432 { 1433 if o := lhs.ExpressionOpt; o != nil { 1434 o.Expression.eval(lx) 1435 } 1436 var dd *DirectDeclarator 1437 switch o := lhs.DirectAbstractDeclaratorOpt; { 1438 case o == nil: 1439 dd = &DirectDeclarator{ 1440 Case: 0, // IDENTIFIER 1441 } 1442 default: 1443 dd = o.DirectAbstractDeclarator.directDeclarator 1444 } 1445 lhs.directDeclarator = &DirectDeclarator{ 1446 Case: 2, // DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']' 1447 DirectDeclarator: dd, 1448 TypeQualifierListOpt: &TypeQualifierListOpt{ lhs.TypeQualifierList }, 1449 ExpressionOpt: lhs.ExpressionOpt, 1450 } 1451 dd.parent = lhs.directDeclarator 1452 } 1453 | DirectAbstractDeclaratorOpt '[' "static" TypeQualifierListOpt Expression ']' 1454 { 1455 lhs.Expression.eval(lx) 1456 var dd *DirectDeclarator 1457 switch o := lhs.DirectAbstractDeclaratorOpt; { 1458 case o == nil: 1459 dd = &DirectDeclarator{ 1460 Case: 0, // IDENTIFIER 1461 } 1462 default: 1463 dd = o.DirectAbstractDeclarator.directDeclarator 1464 } 1465 lhs.directDeclarator = &DirectDeclarator{ 1466 Case: 2, // DirectDeclarator '[' "static" TypeQualifierListOpt Expression ']' 1467 DirectDeclarator: dd, 1468 TypeQualifierListOpt: lhs.TypeQualifierListOpt, 1469 Expression: lhs.Expression, 1470 } 1471 dd.parent = lhs.directDeclarator 1472 } 1473 | DirectAbstractDeclaratorOpt '[' TypeQualifierList "static" Expression ']' 1474 { 1475 lhs.Expression.eval(lx) 1476 var dd *DirectDeclarator 1477 switch o := lhs.DirectAbstractDeclaratorOpt; { 1478 case o == nil: 1479 dd = &DirectDeclarator{ 1480 Case: 0, // IDENTIFIER 1481 } 1482 default: 1483 dd = o.DirectAbstractDeclarator.directDeclarator 1484 } 1485 lhs.directDeclarator = &DirectDeclarator{ 1486 Case: 4, // DirectDeclarator '[' TypeQualifierList "static" Expression ']' 1487 DirectDeclarator: dd, 1488 TypeQualifierList: lhs.TypeQualifierList, 1489 Expression: lhs.Expression, 1490 } 1491 dd.parent = lhs.directDeclarator 1492 } 1493 | DirectAbstractDeclaratorOpt '[' '*' ']' 1494 { 1495 var dd *DirectDeclarator 1496 switch o := lhs.DirectAbstractDeclaratorOpt; { 1497 case o == nil: 1498 dd = &DirectDeclarator{ 1499 Case: 0, // IDENTIFIER 1500 } 1501 default: 1502 dd = o.DirectAbstractDeclarator.directDeclarator 1503 } 1504 lhs.directDeclarator = &DirectDeclarator{ 1505 Case: 5, // DirectDeclarator '[' TypeQualifierListOpt '*' ']' 1506 DirectDeclarator: dd, 1507 } 1508 dd.parent = lhs.directDeclarator 1509 } 1510 | '(' 1511 { 1512 lx.pushScope(ScopeParams) 1513 } 1514 ParameterTypeListOpt ')' 1515 { 1516 lhs.paramsScope, _ = lx.popScope(lhs.Token2) 1517 switch o := lhs.ParameterTypeListOpt; { 1518 case o != nil: 1519 lhs.directDeclarator = &DirectDeclarator{ 1520 Case: 6, // DirectDeclarator '(' ParameterTypeList ')' 1521 DirectDeclarator: &DirectDeclarator{ 1522 Case: 0, // IDENTIFIER 1523 }, 1524 ParameterTypeList: o.ParameterTypeList, 1525 } 1526 default: 1527 lhs.directDeclarator = &DirectDeclarator{ 1528 Case: 7, // DirectDeclarator '(' IdentifierListOpt ')' 1529 DirectDeclarator: &DirectDeclarator{ 1530 Case: 0, // IDENTIFIER 1531 }, 1532 } 1533 } 1534 lhs.directDeclarator.DirectDeclarator.parent = lhs.directDeclarator 1535 } 1536 | DirectAbstractDeclarator '(' 1537 { 1538 lx.pushScope(ScopeParams) 1539 } 1540 ParameterTypeListOpt ')' 1541 { 1542 lhs.paramsScope, _ = lx.popScope(lhs.Token2) 1543 switch o := lhs.ParameterTypeListOpt; { 1544 case o != nil: 1545 lhs.directDeclarator = &DirectDeclarator{ 1546 Case: 6, // DirectDeclarator '(' ParameterTypeList ')' 1547 DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator, 1548 ParameterTypeList: o.ParameterTypeList, 1549 } 1550 default: 1551 lhs.directDeclarator = &DirectDeclarator{ 1552 Case: 7, // DirectDeclarator '(' IdentifierListOpt ')' 1553 DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator, 1554 } 1555 } 1556 lhs.directDeclarator.DirectDeclarator.parent = lhs.directDeclarator 1557 } 1558 1559 DirectAbstractDeclaratorOpt: 1560 /* empty */ {} 1561 | DirectAbstractDeclarator 1562 1563 // [0](6.7.8) 1564 Initializer: 1565 Expression 1566 { 1567 lhs.Expression.eval(lx) 1568 } 1569 | '{' InitializerList CommaOpt '}' 1570 | IDENTIFIER ':' Initializer 1571 { 1572 if !lx.tweaks.enableLegacyDesignators { 1573 lx.report.Err(lhs.Pos(), "legacy designators not enabled") 1574 } 1575 } 1576 1577 // [0](6.7.8) 1578 InitializerList: 1579 DesignationOpt Initializer 1580 | InitializerList ',' DesignationOpt Initializer 1581 | /* empty */ {} 1582 1583 // [0](6.7.8) 1584 Designation: 1585 DesignatorList '=' 1586 1587 DesignationOpt: 1588 /* empty */ {} 1589 | Designation 1590 1591 // [0](6.7.8) 1592 DesignatorList: 1593 Designator 1594 | DesignatorList Designator 1595 1596 // [0](6.7.8) 1597 Designator: 1598 '[' ConstantExpression ']' 1599 | '.' IDENTIFIER 1600 1601 // [0](6.8) 1602 Statement: 1603 LabeledStatement 1604 | CompoundStatement 1605 | ExpressionStatement 1606 | SelectionStatement 1607 | IterationStatement 1608 | JumpStatement 1609 | AssemblerStatement 1610 1611 // [0](6.8.1) 1612 LabeledStatement: 1613 IDENTIFIER ':' Statement 1614 | "case" ConstantExpression ':' Statement 1615 | "default" ':' Statement 1616 1617 // [0](6.8.2) 1618 //yy:field scope *Bindings // Scope of the CompoundStatement. 1619 CompoundStatement: 1620 '{' 1621 { 1622 m := lx.scope.mergeScope 1623 lx.pushScope(ScopeBlock) 1624 if m != nil { 1625 lx.scope.merge(m) 1626 } 1627 lx.scope.mergeScope = nil 1628 } 1629 BlockItemListOpt '}' 1630 { 1631 lhs.scope = lx.scope 1632 lx.popScope(lhs.Token2) 1633 } 1634 1635 // [0](6.8.2) 1636 BlockItemList: 1637 BlockItem 1638 | BlockItemList BlockItem 1639 1640 BlockItemListOpt: 1641 /* empty */ {} 1642 | BlockItemList 1643 1644 // [0](6.8.2) 1645 BlockItem: 1646 Declaration 1647 | Statement 1648 1649 // [0](6.8.3) 1650 ExpressionStatement: 1651 ExpressionListOpt ';' 1652 1653 // [0](6.8.4) 1654 SelectionStatement: 1655 "if" '(' ExpressionList ')' Statement %prec NOELSE 1656 { 1657 lhs.ExpressionList.eval(lx) 1658 } 1659 | "if" '(' ExpressionList ')' Statement "else" Statement 1660 { 1661 lhs.ExpressionList.eval(lx) 1662 } 1663 | "switch" '(' ExpressionList ')' Statement 1664 { 1665 lhs.ExpressionList.eval(lx) 1666 } 1667 1668 // [0](6.8.5) 1669 IterationStatement: 1670 "while" '(' ExpressionList ')' Statement 1671 { 1672 lhs.ExpressionList.eval(lx) 1673 } 1674 | "do" Statement "while" '(' ExpressionList ')' ';' 1675 { 1676 lhs.ExpressionList.eval(lx) 1677 } 1678 | "for" '(' ExpressionListOpt ';' ExpressionListOpt ';' ExpressionListOpt ')' Statement 1679 | "for" '(' Declaration ExpressionListOpt ';' ExpressionListOpt ')' Statement 1680 1681 // [0](6.8.6) 1682 JumpStatement: 1683 "goto" IDENTIFIER ';' 1684 | "continue" ';' 1685 | "break" ';' 1686 | "return" ExpressionListOpt ';' 1687 | "goto" Expression ';' 1688 { 1689 _, t := lhs.Expression.eval(lx) 1690 if t == nil { 1691 break 1692 } 1693 1694 for t != nil && t.Kind() == Ptr { 1695 t = t.Element() 1696 } 1697 1698 if t == nil || t.Kind() != Void { 1699 lx.report.Err(lhs.Pos(), "invalid computed goto argument type, have '%s'", t) 1700 } 1701 1702 if !lx.tweaks.enableComputedGotos { 1703 lx.report.Err(lhs.Pos(), "computed gotos not enabled") 1704 } 1705 } 1706 1707 // [0](6.9) 1708 //yy:field Comments map[token.Pos]int // Position -> comment ID. Enable using the KeepComments option. 1709 //yy:field Declarations *Bindings 1710 //yy:field Macros map[int]*Macro // Ident ID -> preprocessor macro defined by ident. 1711 //yy:field Model *Model // Model used to parse the TranslationUnit. 1712 //yy:list 1713 TranslationUnit: 1714 ExternalDeclaration 1715 | TranslationUnit ExternalDeclaration 1716 1717 // [0](6.9) 1718 ExternalDeclaration: 1719 FunctionDefinition 1720 | Declaration 1721 | BasicAssemblerStatement ';' 1722 | ';' 1723 { 1724 if !lx.tweaks.enableEmptyDeclarations { 1725 lx.report.Err(lhs.Pos(), "C++11 empty declarations are illegal in C99.") 1726 } 1727 } 1728 1729 // [0](6.9.1) 1730 FunctionDefinition: 1731 DeclarationSpecifiers Declarator DeclarationListOpt 1732 { 1733 if ds := $1.(*DeclarationSpecifiers); ds.typeSpecifier == 0 { 1734 ds.typeSpecifier = tsEncode(tsInt) 1735 $2.(*Declarator).Type = lx.model.IntType 1736 if !lx.tweaks.enableOmitFuncRetType { 1737 lx.report.Err($2.Pos(), "missing function return type") 1738 } 1739 } 1740 var fd *FunctionDefinition 1741 fd.post(lx, $2.(*Declarator), $3.(*DeclarationListOpt)) 1742 } 1743 FunctionBody 1744 | { 1745 lx.scope.specifier = &DeclarationSpecifiers{typeSpecifier: tsEncode(tsInt)} 1746 } 1747 Declarator DeclarationListOpt 1748 { 1749 if !lx.tweaks.enableOmitFuncRetType { 1750 lx.report.Err($2.Pos(), "missing function return type") 1751 } 1752 var fd *FunctionDefinition 1753 fd.post(lx, $2.(*Declarator), $3.(*DeclarationListOpt)) 1754 } 1755 FunctionBody 1756 1757 //yy:field scope *Bindings // Scope of the FunctionBody. 1758 FunctionBody: 1759 { 1760 // Handle __func__, [0], 6.4.2.2. 1761 id, _ := lx.fnDeclarator.Identifier() 1762 lx.injectFunc = []xc.Token{ 1763 {lex.Char{Rune: STATIC}, idStatic}, 1764 {lex.Char{Rune: CONST}, idConst}, 1765 {lex.Char{Rune: CHAR}, idChar}, 1766 {lex.Char{Rune: IDENTIFIER}, idMagicFunc}, 1767 {lex.Char{Rune: '['}, 0}, 1768 {lex.Char{Rune: ']'}, 0}, 1769 {lex.Char{Rune: '='}, 0}, 1770 {lex.Char{Rune: STRINGLITERAL}, xc.Dict.SID(fmt.Sprintf("%q", xc.Dict.S(id)))}, 1771 {lex.Char{Rune: ';'}, 0}, 1772 } 1773 } 1774 CompoundStatement 1775 { 1776 lhs.scope = lhs.CompoundStatement.scope 1777 } 1778 | 1779 { 1780 m := lx.scope.mergeScope 1781 lx.pushScope(ScopeBlock) 1782 if m != nil { 1783 lx.scope.merge(m) 1784 } 1785 lx.scope.mergeScope = nil 1786 } 1787 AssemblerStatement ';' 1788 { 1789 lhs.scope = lx.scope 1790 lx.popScope(lx.tokPrev) 1791 } 1792 1793 // [0](6.9.1) 1794 DeclarationList: 1795 Declaration 1796 | DeclarationList Declaration 1797 1798 //yy:field paramsScope *Bindings 1799 DeclarationListOpt: 1800 /* empty */ {} 1801 | { 1802 lx.pushScope(ScopeParams) 1803 } 1804 DeclarationList 1805 { 1806 lhs.paramsScope, _ = lx.popScopePos(lhs.Pos()) 1807 } 1808 1809 //yy:list 1810 AssemblerInstructions: 1811 STRINGLITERAL 1812 | AssemblerInstructions STRINGLITERAL 1813 1814 BasicAssemblerStatement: 1815 "asm" VolatileOpt '(' AssemblerInstructions ')' 1816 1817 VolatileOpt: 1818 /* empty */ {} 1819 | "volatile" 1820 1821 AssemblerOperand: 1822 AssemblerSymbolicNameOpt STRINGLITERAL '(' Expression ')' 1823 1824 //yy:list 1825 AssemblerOperands: 1826 AssemblerOperand 1827 | AssemblerOperands ',' AssemblerOperand 1828 1829 AssemblerSymbolicNameOpt: 1830 /* empty */ {} 1831 | '[' IDENTIFIER ']' 1832 1833 //yy:list 1834 Clobbers: 1835 STRINGLITERAL 1836 | Clobbers ',' STRINGLITERAL 1837 1838 AssemblerStatement: 1839 BasicAssemblerStatement 1840 | "asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ')' 1841 | "asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ':' AssemblerOperands ')' 1842 | "asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ':' AssemblerOperands ':' Clobbers ')' 1843 | "asm" VolatileOpt "goto" '(' AssemblerInstructions ':' ':' AssemblerOperands ':' Clobbers ':' IdentifierList ')' 1844 | "asm" VolatileOpt '(' AssemblerInstructions ':' ')' // https://github.com/cznic/cc/issues/59 1845 | "asm" VolatileOpt '(' AssemblerInstructions ':' ':' AssemblerOperands ')' 1846 1847 StaticAssertDeclaration: 1848 "_Static_assert" '(' ConstantExpression ',' STRINGLITERAL ')' ';' 1849 { 1850 ce := lhs.ConstantExpression 1851 if ce.Type == nil || ce.Type.Kind() == Undefined || ce.Value == nil || !IsIntType(ce.Type) { 1852 lx.report.Err(ce.Pos(), "invalid static assert expression (have '%v')", ce.Type) 1853 break 1854 } 1855 1856 if !isNonZero(ce.Value) { 1857 lx.report.ErrTok(lhs.Token, "%s", lhs.Token4.S()) 1858 } 1859 } 1860 1861 // ========================================================= PREPROCESSING_FILE 1862 1863 // [0](6.10) 1864 //yy:field path string 1865 PreprocessingFile: 1866 GroupList // No more GroupListOpt due to final '\n' injection. 1867 { 1868 lhs.path = lx.file.Name() 1869 } 1870 1871 // [0](6.10) 1872 GroupList: 1873 GroupPart 1874 //yy:example "\U00100000int\nf() {}" 1875 | GroupList GroupPart 1876 1877 GroupListOpt: 1878 /* empty */ {} 1879 //yy:example "\U00100000 \n#ifndef a\nb\n#elif" 1880 | GroupList 1881 1882 // [0](6.10) 1883 //yy:ignore 1884 GroupPart: 1885 ControlLine 1886 { 1887 $$ = $1.(Node) 1888 } 1889 | IfSection 1890 { 1891 $$ = $1.(Node) 1892 } 1893 | PPNONDIRECTIVE PPTokenList '\n' 1894 { 1895 $$ = $1 1896 } 1897 | TextLine 1898 { 1899 $$ = $1 1900 } 1901 1902 //(6.10) 1903 IfSection: 1904 IfGroup ElifGroupListOpt ElseGroupOpt EndifLine 1905 1906 //(6.10) 1907 IfGroup: 1908 PPIF PPTokenList '\n' GroupListOpt 1909 | PPIFDEF IDENTIFIER '\n' GroupListOpt 1910 | PPIFNDEF IDENTIFIER '\n' GroupListOpt 1911 1912 // [0](6.10) 1913 ElifGroupList: 1914 ElifGroup 1915 | ElifGroupList ElifGroup 1916 1917 ElifGroupListOpt: 1918 /* empty */ {} 1919 | ElifGroupList 1920 1921 // [0](6.10) 1922 ElifGroup: 1923 PPELIF PPTokenList '\n' GroupListOpt 1924 1925 // [0](6.10) 1926 ElseGroup: 1927 PPELSE '\n' GroupListOpt 1928 1929 ElseGroupOpt: 1930 /* empty */ {} 1931 | ElseGroup 1932 1933 // [0](6.10) 1934 EndifLine: 1935 PPENDIF /* PPTokenListOpt */ //TODO Option enabling the non std PPTokenListOpt part. 1936 1937 // [0](6.10) 1938 ControlLine: 1939 PPDEFINE IDENTIFIER ReplacementList 1940 | PPDEFINE IDENTIFIER_LPAREN "..." ')' ReplacementList 1941 | PPDEFINE IDENTIFIER_LPAREN IdentifierList ',' "..." ')' ReplacementList 1942 | PPDEFINE IDENTIFIER_LPAREN IdentifierListOpt ')' ReplacementList 1943 | PPERROR PPTokenListOpt 1944 | PPHASH_NL 1945 | PPINCLUDE PPTokenList '\n' 1946 | PPLINE PPTokenList '\n' 1947 | PPPRAGMA PPTokenListOpt 1948 //yy:example "\U00100000 \n#undef foo" 1949 | PPUNDEF IDENTIFIER '\n' 1950 1951 // Non standard stuff. 1952 1953 | PPDEFINE IDENTIFIER_LPAREN IdentifierList "..." ')' ReplacementList 1954 { 1955 if !lx.tweaks.enableDefineOmitCommaBeforeDDD { 1956 lx.report.ErrTok(lhs.Token4, "missing comma before \"...\"") 1957 } 1958 } 1959 | PPDEFINE '\n' 1960 { 1961 if !lx.tweaks.enableEmptyDefine { 1962 lx.report.ErrTok(lhs.Token2, "expected identifier") 1963 } 1964 } 1965 //yy:example "\U00100000 \n#undef foo(bar)" 1966 | PPUNDEF IDENTIFIER PPTokenList '\n' 1967 { 1968 toks := decodeTokens(lhs.PPTokenList, nil, false) 1969 if len(toks) == 0 { 1970 lhs.Case = 9 // PPUNDEF IDENTIFIER '\n' 1971 break 1972 } 1973 1974 lx.report.ErrTok(toks[0], "extra tokens after #undef argument") 1975 } 1976 | PPINCLUDE_NEXT PPTokenList '\n' 1977 1978 // [0](6.10) 1979 //yy:ignore 1980 TextLine: 1981 PPTokenListOpt 1982 1983 // [0](6.10) 1984 //yy:ignore 1985 ReplacementList: 1986 PPTokenListOpt 1987 1988 // [0](6.10) 1989 //yy:ignore 1990 PPTokenList: 1991 PPTokens 1992 { 1993 $$ = PPTokenList(dict.ID(lx.encBuf)) 1994 lx.encBuf = lx.encBuf[:0] 1995 lx.encPos = 0 1996 } 1997 1998 //yy:ignore 1999 PPTokenListOpt: 2000 '\n' 2001 { 2002 $$ = 0 2003 } 2004 | PPTokenList '\n' 2005 2006 //yy:ignore 2007 PPTokens: 2008 PPOTHER 2009 | PPTokens PPOTHER