modernc.org/cc@v1.0.1/parser.y (about) 1 // Code generated by yy. DO NOT EDIT. 2 3 %{ 4 // Copyright 2016 The CC Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 // Based on [0], 6.10. Substantial portions of expression AST size 9 // optimizations are from [2], license of which follows. 10 11 // ---------------------------------------------------------------------------- 12 13 // Copyright 2013 The Go Authors. All rights reserved. 14 // Use of this source code is governed by a BSD-style 15 // license that can be found in the LICENSE file. 16 17 // This grammar is derived from the C grammar in the 'ansitize' 18 // program, which carried this notice: 19 // 20 // Copyright (c) 2006 Russ Cox, 21 // Massachusetts Institute of Technology 22 // 23 // Permission is hereby granted, free of charge, to any person 24 // obtaining a copy of this software and associated 25 // documentation files (the "Software"), to deal in the 26 // Software without restriction, including without limitation 27 // the rights to use, copy, modify, merge, publish, distribute, 28 // sublicense, and/or sell copies of the Software, and to 29 // permit persons to whom the Software is furnished to do so, 30 // subject to the following conditions: 31 // 32 // The above copyright notice and this permission notice shall 33 // be included in all copies or substantial portions of the 34 // Software. 35 // 36 // The software is provided "as is", without warranty of any 37 // kind, express or implied, including but not limited to the 38 // warranties of merchantability, fitness for a particular 39 // purpose and noninfringement. In no event shall the authors 40 // or copyright holders be liable for any claim, damages or 41 // other liability, whether in an action of contract, tort or 42 // otherwise, arising from, out of or in connection with the 43 // software or the use or other dealings in the software. 44 45 package cc 46 47 import ( 48 "fmt" 49 50 "modernc.org/xc" 51 "modernc.org/golex/lex" 52 ) 53 %} 54 55 %union { 56 Token xc.Token 57 groupPart Node 58 node Node 59 toks PPTokenList 60 } 61 62 %token <Token> 63 '!' 64 '%' 65 '&' 66 '(' 67 ')' 68 '*' 69 '+' 70 ',' 71 '-' 72 '.' 73 '/' 74 ':' 75 ';' 76 '<' 77 '=' 78 '>' 79 '?' 80 '[' 81 '\n' 82 ']' 83 '^' 84 '{' 85 '|' 86 '}' 87 '~' 88 ADDASSIGN "+=" 89 ALIGNOF "_Alignof" 90 ANDAND "&&" 91 ANDASSIGN "&=" 92 ARROW "->" 93 ASM "asm" 94 AUTO "auto" 95 BOOL "_Bool" 96 BREAK "break" 97 CASE "case" 98 CAST 99 CHAR "char" 100 CHARCONST "character constant" 101 COMPLEX "_Complex" 102 CONST "const" 103 CONSTANT_EXPRESSION 1048577 "constant expression prefix" 104 CONTINUE "continue" 105 DDD "..." 106 DEC "--" 107 DEFAULT "default" 108 DIVASSIGN "/=" 109 DO "do" 110 DOUBLE "double" 111 ELSE "else" 112 ENUM "enum" 113 EQ "==" 114 EXTERN "extern" 115 FLOAT "float" 116 FLOATCONST "floating-point constant" 117 FOR "for" 118 GEQ ">=" 119 GOTO "goto" 120 IDENTIFIER "identifier" 121 IDENTIFIER_LPAREN "identifier immediatelly followed by '('" 122 IDENTIFIER_NONREPL "non replaceable identifier" 123 IF "if" 124 INC "++" 125 INLINE "inline" 126 INT "int" 127 INTCONST "integer constant" 128 LEQ "<=" 129 LONG "long" 130 LONGCHARCONST "long character constant" 131 LONGSTRINGLITERAL "long string constant" 132 LSH "<<" 133 LSHASSIGN "<<=" 134 MODASSIGN "%=" 135 MULASSIGN "*=" 136 NEQ "!=" 137 NOELSE 138 NORETURN "_Noreturn" 139 NOSEMI 140 ORASSIGN "|=" 141 OROR "||" 142 PPDEFINE "#define" 143 PPELIF "#elif" 144 PPELSE "#else" 145 PPENDIF "#endif" 146 PPERROR "#error" 147 PPHASH_NL "#" 148 PPHEADER_NAME "header name" 149 PPIF "#if" 150 PPIFDEF "#ifdef" 151 PPIFNDEF "#ifndef" 152 PPINCLUDE "#include" 153 PPINCLUDE_NEXT "#include_next" 154 PPLINE "#line" 155 PPNONDIRECTIVE "#foo" 156 PPNUMBER "preprocessing number" 157 PPOTHER "ppother" 158 PPPASTE "##" 159 PPPRAGMA "#pragma" 160 PPUNDEF "#undef" 161 PREPROCESSING_FILE 1048576 "preprocessing file prefix" 162 REGISTER "register" 163 RESTRICT "restrict" 164 RETURN "return" 165 RSH ">>" 166 RSHASSIGN ">>=" 167 SHORT "short" 168 SIGNED "signed" 169 SIZEOF "sizeof" 170 STATIC "static" 171 STATIC_ASSERT "_Static_assert" 172 STRINGLITERAL "string literal" 173 STRUCT "struct" 174 SUBASSIGN "-=" 175 SWITCH "switch" 176 TRANSLATION_UNIT 1048578 "translation unit prefix" 177 TYPEDEF "typedef" 178 TYPEDEFNAME "typedefname" 179 TYPEOF "typeof" 180 UNARY 181 UNION "union" 182 UNSIGNED "unsigned" 183 VOID "void" 184 VOLATILE "volatile" 185 WHILE "while" 186 XORASSIGN "^=" 187 188 %type <groupPart> 189 GroupPart "group part" 190 191 %type <node> 192 AbstractDeclarator "abstract declarator" 193 AbstractDeclaratorOpt "optional abstract declarator" 194 ArgumentExpressionList "argument expression list" 195 ArgumentExpressionListOpt "optional argument expression list" 196 AssemblerInstructions "assembler instructions" 197 AssemblerOperand "assembler operand" 198 AssemblerOperands "assembler operands" 199 AssemblerStatement "assembler statement" 200 AssemblerSymbolicNameOpt "optional assembler symbolic name" 201 BasicAssemblerStatement "basic assembler statement" 202 BlockItem "block item" 203 BlockItemList "block item list" 204 BlockItemListOpt "optional block item list" 205 Clobbers "clobbers" 206 CommaOpt "optional comma" 207 CompoundStatement "compound statement" 208 ConstantExpression "constant expression" 209 ControlLine "control line" 210 Declaration "declaration" 211 DeclarationList "declaration list" 212 DeclarationListOpt "optional declaration list" 213 DeclarationSpecifiers "declaration specifiers" 214 DeclarationSpecifiersOpt "optional declaration specifiers" 215 Declarator "declarator" 216 DeclaratorOpt "optional declarator" 217 Designation "designation" 218 DesignationOpt "optional designation" 219 Designator "designator" 220 DesignatorList "designator list" 221 DirectAbstractDeclarator "direct abstract declarator" 222 DirectAbstractDeclaratorOpt "optional direct abstract declarator" 223 DirectDeclarator "direct declarator" 224 ElifGroup "elif group" 225 ElifGroupList "elif group list" 226 ElifGroupListOpt "optional elif group list" 227 ElseGroup "else group" 228 ElseGroupOpt "optional else group" 229 EndifLine "endif line" 230 EnumSpecifier "enum specifier" 231 EnumerationConstant "enumearation constant" 232 Enumerator "enumerator" 233 EnumeratorList "enumerator list" 234 Expression "expression" 235 ExpressionList "expression list" 236 ExpressionListOpt "optional expression list" 237 ExpressionOpt "optional expression" 238 ExpressionStatement "expression statement" 239 ExternalDeclaration "external declaration" 240 FunctionBody "function body" 241 FunctionDefinition "function definition" 242 FunctionSpecifier "function specifier" 243 GroupList "group list" 244 GroupListOpt "optional group list" 245 IdentifierList "identifier list" 246 IdentifierListOpt "optional identifier list" 247 IdentifierOpt "optional identifier" 248 IfGroup "if group" 249 IfSection "if section" 250 InitDeclarator "init declarator" 251 InitDeclaratorList "init declarator list" 252 InitDeclaratorListOpt "optional init declarator list" 253 Initializer "initializer" 254 InitializerList "initializer list" 255 IterationStatement "iteration statement" 256 JumpStatement "jump statement" 257 LabeledStatement "labeled statement" 258 PPTokens 259 ParameterDeclaration "parameter declaration" 260 ParameterList "parameter list" 261 ParameterTypeList "parameter type list" 262 ParameterTypeListOpt "optional parameter type list" 263 Pointer "pointer" 264 PointerOpt "optional pointer" 265 PreprocessingFile "preprocessing file" 266 SelectionStatement "selection statement" 267 SpecifierQualifierList "specifier qualifier list" 268 SpecifierQualifierListOpt "optional specifier qualifier list" 269 Start 270 Statement "statement" 271 StaticAssertDeclaration "static assert declaration" 272 StorageClassSpecifier "storage class specifier" 273 StructDeclaration "struct declaration" 274 StructDeclarationList "struct declaration list" 275 StructDeclarator "struct declarator" 276 StructDeclaratorList "struct declarator list" 277 StructOrUnion "struct-or-union" 278 StructOrUnionSpecifier "struct-or-union specifier" 279 TranslationUnit "translation unit" 280 TypeName "type name" 281 TypeQualifier "type qualifier" 282 TypeQualifierList "type qualifier list" 283 TypeQualifierListOpt "optional type qualifier list" 284 TypeSpecifier "type specifier" 285 VolatileOpt "optional volatile" 286 287 %type <toks> 288 PPTokenList "token list" 289 PPTokenListOpt "optional token list" 290 ReplacementList "replacement list" 291 TextLine "text line" 292 293 %precedence NOSEMI 294 %precedence ';' 295 %precedence NOELSE 296 %precedence ELSE 297 %right '=' ADDASSIGN ANDASSIGN DIVASSIGN LSHASSIGN MODASSIGN MULASSIGN ORASSIGN RSHASSIGN SUBASSIGN XORASSIGN 298 %right ':' '?' 299 %left OROR 300 %left ANDAND 301 %left '|' 302 %left '^' 303 %left '&' 304 %left EQ NEQ 305 %left '<' '>' GEQ LEQ 306 %left LSH RSH 307 %left '+' '-' 308 %left '%' '*' '/' 309 %precedence CAST 310 %left '!' '~' SIZEOF UNARY 311 %right '(' '.' '[' ARROW DEC INC 312 313 %start Start 314 315 %% 316 317 Start: 318 PREPROCESSING_FILE 319 { 320 lx := yylex.(*lexer) 321 lx.preprocessingFile = nil 322 } 323 PreprocessingFile 324 { 325 lx := yylex.(*lexer) 326 lx.preprocessingFile = $3.(*PreprocessingFile) 327 } 328 | CONSTANT_EXPRESSION 329 { 330 lx := yylex.(*lexer) 331 lx.constantExpression = nil 332 } 333 ConstantExpression 334 { 335 lx := yylex.(*lexer) 336 lx.constantExpression = $3.(*ConstantExpression) 337 } 338 | TRANSLATION_UNIT 339 { 340 lx := yylex.(*lexer) 341 lx.translationUnit = nil 342 } 343 TranslationUnit 344 { 345 lx := yylex.(*lexer) 346 if lx.report.Errors(false) == nil && lx.scope.kind != ScopeFile { 347 panic("internal error") 348 } 349 350 lx.translationUnit = $3.(*TranslationUnit).reverse() 351 lx.translationUnit.Declarations = lx.scope 352 } 353 354 EnumerationConstant: 355 IDENTIFIER 356 { 357 $$ = &EnumerationConstant{ 358 Token: $1, 359 } 360 } 361 362 ArgumentExpressionList: 363 Expression 364 { 365 $$ = &ArgumentExpressionList{ 366 Expression: $1.(*Expression), 367 } 368 } 369 | ArgumentExpressionList ',' Expression 370 { 371 $$ = &ArgumentExpressionList{ 372 Case: 1, 373 ArgumentExpressionList: $1.(*ArgumentExpressionList), 374 Token: $2, 375 Expression: $3.(*Expression), 376 } 377 } 378 379 ArgumentExpressionListOpt: 380 /* empty */ 381 { 382 $$ = (*ArgumentExpressionListOpt)(nil) 383 } 384 | ArgumentExpressionList 385 { 386 $$ = &ArgumentExpressionListOpt{ 387 ArgumentExpressionList: $1.(*ArgumentExpressionList).reverse(), 388 } 389 } 390 391 Expression: 392 IDENTIFIER %prec NOSEMI 393 { 394 lx := yylex.(*lexer) 395 lhs := &Expression{ 396 Token: $1, 397 } 398 $$ = lhs 399 lhs.scope = lx.scope 400 } 401 | CHARCONST 402 { 403 $$ = &Expression{ 404 Case: 1, 405 Token: $1, 406 } 407 } 408 | FLOATCONST 409 { 410 $$ = &Expression{ 411 Case: 2, 412 Token: $1, 413 } 414 } 415 | INTCONST 416 { 417 $$ = &Expression{ 418 Case: 3, 419 Token: $1, 420 } 421 } 422 | LONGCHARCONST 423 { 424 $$ = &Expression{ 425 Case: 4, 426 Token: $1, 427 } 428 } 429 | LONGSTRINGLITERAL 430 { 431 $$ = &Expression{ 432 Case: 5, 433 Token: $1, 434 } 435 } 436 | STRINGLITERAL 437 { 438 $$ = &Expression{ 439 Case: 6, 440 Token: $1, 441 } 442 } 443 | '(' ExpressionList ')' 444 { 445 $$ = &Expression{ 446 Case: 7, 447 Token: $1, 448 ExpressionList: $2.(*ExpressionList).reverse(), 449 Token2: $3, 450 } 451 } 452 | Expression '[' ExpressionList ']' 453 { 454 $$ = &Expression{ 455 Case: 8, 456 Expression: $1.(*Expression), 457 Token: $2, 458 ExpressionList: $3.(*ExpressionList).reverse(), 459 Token2: $4, 460 } 461 } 462 | Expression '(' ArgumentExpressionListOpt ')' 463 { 464 lx := yylex.(*lexer) 465 lhs := &Expression{ 466 Case: 9, 467 Expression: $1.(*Expression), 468 Token: $2, 469 ArgumentExpressionListOpt: $3.(*ArgumentExpressionListOpt), 470 Token2: $4, 471 } 472 $$ = lhs 473 o := lhs.ArgumentExpressionListOpt 474 if o == nil { 475 break 476 } 477 478 if lhs.Expression.Case == 0 { // IDENTIFIER 479 if lx.tweaks.enableBuiltinConstantP &&lhs.Expression.Token.Val == idBuiltinConstantP { 480 break 481 } 482 483 b := lhs.Expression.scope.Lookup(NSIdentifiers, lhs.Expression.Token.Val) 484 if b.Node == nil && lx.tweaks.enableImplicitFuncDef { 485 for l := o.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList { 486 l.Expression.eval(lx) 487 } 488 break 489 } 490 } 491 492 lhs.Expression.eval(lx) 493 for l := o.ArgumentExpressionList; l != nil; l = l.ArgumentExpressionList { 494 l.Expression.eval(lx) 495 } 496 } 497 | Expression '.' IDENTIFIER 498 { 499 $$ = &Expression{ 500 Case: 10, 501 Expression: $1.(*Expression), 502 Token: $2, 503 Token2: $3, 504 } 505 } 506 | Expression "->" IDENTIFIER 507 { 508 $$ = &Expression{ 509 Case: 11, 510 Expression: $1.(*Expression), 511 Token: $2, 512 Token2: $3, 513 } 514 } 515 | Expression "++" 516 { 517 $$ = &Expression{ 518 Case: 12, 519 Expression: $1.(*Expression), 520 Token: $2, 521 } 522 } 523 | Expression "--" 524 { 525 $$ = &Expression{ 526 Case: 13, 527 Expression: $1.(*Expression), 528 Token: $2, 529 } 530 } 531 | '(' TypeName ')' '{' InitializerList CommaOpt '}' 532 { 533 $$ = &Expression{ 534 Case: 14, 535 Token: $1, 536 TypeName: $2.(*TypeName), 537 Token2: $3, 538 Token3: $4, 539 InitializerList: $5.(*InitializerList).reverse(), 540 CommaOpt: $6.(*CommaOpt), 541 Token4: $7, 542 } 543 } 544 | "++" Expression 545 { 546 $$ = &Expression{ 547 Case: 15, 548 Token: $1, 549 Expression: $2.(*Expression), 550 } 551 } 552 | "--" Expression 553 { 554 $$ = &Expression{ 555 Case: 16, 556 Token: $1, 557 Expression: $2.(*Expression), 558 } 559 } 560 | '&' Expression %prec UNARY 561 { 562 $$ = &Expression{ 563 Case: 17, 564 Token: $1, 565 Expression: $2.(*Expression), 566 } 567 } 568 | '*' Expression %prec UNARY 569 { 570 $$ = &Expression{ 571 Case: 18, 572 Token: $1, 573 Expression: $2.(*Expression), 574 } 575 } 576 | '+' Expression %prec UNARY 577 { 578 $$ = &Expression{ 579 Case: 19, 580 Token: $1, 581 Expression: $2.(*Expression), 582 } 583 } 584 | '-' Expression %prec UNARY 585 { 586 $$ = &Expression{ 587 Case: 20, 588 Token: $1, 589 Expression: $2.(*Expression), 590 } 591 } 592 | '~' Expression 593 { 594 $$ = &Expression{ 595 Case: 21, 596 Token: $1, 597 Expression: $2.(*Expression), 598 } 599 } 600 | '!' Expression 601 { 602 $$ = &Expression{ 603 Case: 22, 604 Token: $1, 605 Expression: $2.(*Expression), 606 } 607 } 608 | "sizeof" Expression 609 { 610 $$ = &Expression{ 611 Case: 23, 612 Token: $1, 613 Expression: $2.(*Expression), 614 } 615 } 616 | "sizeof" '(' TypeName ')' %prec SIZEOF 617 { 618 $$ = &Expression{ 619 Case: 24, 620 Token: $1, 621 Token2: $2, 622 TypeName: $3.(*TypeName), 623 Token3: $4, 624 } 625 } 626 | '(' TypeName ')' Expression %prec CAST 627 { 628 $$ = &Expression{ 629 Case: 25, 630 Token: $1, 631 TypeName: $2.(*TypeName), 632 Token2: $3, 633 Expression: $4.(*Expression), 634 } 635 } 636 | Expression '*' Expression 637 { 638 $$ = &Expression{ 639 Case: 26, 640 Expression: $1.(*Expression), 641 Token: $2, 642 Expression2: $3.(*Expression), 643 } 644 } 645 | Expression '/' Expression 646 { 647 $$ = &Expression{ 648 Case: 27, 649 Expression: $1.(*Expression), 650 Token: $2, 651 Expression2: $3.(*Expression), 652 } 653 } 654 | Expression '%' Expression 655 { 656 $$ = &Expression{ 657 Case: 28, 658 Expression: $1.(*Expression), 659 Token: $2, 660 Expression2: $3.(*Expression), 661 } 662 } 663 | Expression '+' Expression 664 { 665 $$ = &Expression{ 666 Case: 29, 667 Expression: $1.(*Expression), 668 Token: $2, 669 Expression2: $3.(*Expression), 670 } 671 } 672 | Expression '-' Expression 673 { 674 $$ = &Expression{ 675 Case: 30, 676 Expression: $1.(*Expression), 677 Token: $2, 678 Expression2: $3.(*Expression), 679 } 680 } 681 | Expression "<<" Expression 682 { 683 $$ = &Expression{ 684 Case: 31, 685 Expression: $1.(*Expression), 686 Token: $2, 687 Expression2: $3.(*Expression), 688 } 689 } 690 | Expression ">>" Expression 691 { 692 $$ = &Expression{ 693 Case: 32, 694 Expression: $1.(*Expression), 695 Token: $2, 696 Expression2: $3.(*Expression), 697 } 698 } 699 | Expression '<' Expression 700 { 701 $$ = &Expression{ 702 Case: 33, 703 Expression: $1.(*Expression), 704 Token: $2, 705 Expression2: $3.(*Expression), 706 } 707 } 708 | Expression '>' Expression 709 { 710 $$ = &Expression{ 711 Case: 34, 712 Expression: $1.(*Expression), 713 Token: $2, 714 Expression2: $3.(*Expression), 715 } 716 } 717 | Expression "<=" Expression 718 { 719 $$ = &Expression{ 720 Case: 35, 721 Expression: $1.(*Expression), 722 Token: $2, 723 Expression2: $3.(*Expression), 724 } 725 } 726 | Expression ">=" Expression 727 { 728 $$ = &Expression{ 729 Case: 36, 730 Expression: $1.(*Expression), 731 Token: $2, 732 Expression2: $3.(*Expression), 733 } 734 } 735 | Expression "==" Expression 736 { 737 $$ = &Expression{ 738 Case: 37, 739 Expression: $1.(*Expression), 740 Token: $2, 741 Expression2: $3.(*Expression), 742 } 743 } 744 | Expression "!=" Expression 745 { 746 $$ = &Expression{ 747 Case: 38, 748 Expression: $1.(*Expression), 749 Token: $2, 750 Expression2: $3.(*Expression), 751 } 752 } 753 | Expression '&' Expression 754 { 755 $$ = &Expression{ 756 Case: 39, 757 Expression: $1.(*Expression), 758 Token: $2, 759 Expression2: $3.(*Expression), 760 } 761 } 762 | Expression '^' Expression 763 { 764 $$ = &Expression{ 765 Case: 40, 766 Expression: $1.(*Expression), 767 Token: $2, 768 Expression2: $3.(*Expression), 769 } 770 } 771 | Expression '|' Expression 772 { 773 $$ = &Expression{ 774 Case: 41, 775 Expression: $1.(*Expression), 776 Token: $2, 777 Expression2: $3.(*Expression), 778 } 779 } 780 | Expression "&&" Expression 781 { 782 $$ = &Expression{ 783 Case: 42, 784 Expression: $1.(*Expression), 785 Token: $2, 786 Expression2: $3.(*Expression), 787 } 788 } 789 | Expression "||" Expression 790 { 791 $$ = &Expression{ 792 Case: 43, 793 Expression: $1.(*Expression), 794 Token: $2, 795 Expression2: $3.(*Expression), 796 } 797 } 798 | Expression '?' ExpressionList ':' Expression 799 { 800 $$ = &Expression{ 801 Case: 44, 802 Expression: $1.(*Expression), 803 Token: $2, 804 ExpressionList: $3.(*ExpressionList).reverse(), 805 Token2: $4, 806 Expression2: $5.(*Expression), 807 } 808 } 809 | Expression '=' Expression 810 { 811 $$ = &Expression{ 812 Case: 45, 813 Expression: $1.(*Expression), 814 Token: $2, 815 Expression2: $3.(*Expression), 816 } 817 } 818 | Expression "*=" Expression 819 { 820 $$ = &Expression{ 821 Case: 46, 822 Expression: $1.(*Expression), 823 Token: $2, 824 Expression2: $3.(*Expression), 825 } 826 } 827 | Expression "/=" Expression 828 { 829 $$ = &Expression{ 830 Case: 47, 831 Expression: $1.(*Expression), 832 Token: $2, 833 Expression2: $3.(*Expression), 834 } 835 } 836 | Expression "%=" Expression 837 { 838 $$ = &Expression{ 839 Case: 48, 840 Expression: $1.(*Expression), 841 Token: $2, 842 Expression2: $3.(*Expression), 843 } 844 } 845 | Expression "+=" Expression 846 { 847 $$ = &Expression{ 848 Case: 49, 849 Expression: $1.(*Expression), 850 Token: $2, 851 Expression2: $3.(*Expression), 852 } 853 } 854 | Expression "-=" Expression 855 { 856 $$ = &Expression{ 857 Case: 50, 858 Expression: $1.(*Expression), 859 Token: $2, 860 Expression2: $3.(*Expression), 861 } 862 } 863 | Expression "<<=" Expression 864 { 865 $$ = &Expression{ 866 Case: 51, 867 Expression: $1.(*Expression), 868 Token: $2, 869 Expression2: $3.(*Expression), 870 } 871 } 872 | Expression ">>=" Expression 873 { 874 $$ = &Expression{ 875 Case: 52, 876 Expression: $1.(*Expression), 877 Token: $2, 878 Expression2: $3.(*Expression), 879 } 880 } 881 | Expression "&=" Expression 882 { 883 $$ = &Expression{ 884 Case: 53, 885 Expression: $1.(*Expression), 886 Token: $2, 887 Expression2: $3.(*Expression), 888 } 889 } 890 | Expression "^=" Expression 891 { 892 $$ = &Expression{ 893 Case: 54, 894 Expression: $1.(*Expression), 895 Token: $2, 896 Expression2: $3.(*Expression), 897 } 898 } 899 | Expression "|=" Expression 900 { 901 $$ = &Expression{ 902 Case: 55, 903 Expression: $1.(*Expression), 904 Token: $2, 905 Expression2: $3.(*Expression), 906 } 907 } 908 | "_Alignof" '(' TypeName ')' 909 { 910 $$ = &Expression{ 911 Case: 56, 912 Token: $1, 913 Token2: $2, 914 TypeName: $3.(*TypeName), 915 Token3: $4, 916 } 917 } 918 | '(' CompoundStatement ')' 919 { 920 $$ = &Expression{ 921 Case: 57, 922 Token: $1, 923 CompoundStatement: $2.(*CompoundStatement), 924 Token2: $3, 925 } 926 } 927 | "&&" IDENTIFIER 928 { 929 lx := yylex.(*lexer) 930 lhs := &Expression{ 931 Case: 58, 932 Token: $1, 933 Token2: $2, 934 } 935 $$ = lhs 936 if !lx.tweaks.enableComputedGotos { 937 lx.report.Err(lhs.Pos(), "computed gotos not enabled") 938 } 939 } 940 | Expression '?' ':' Expression 941 { 942 lx := yylex.(*lexer) 943 lhs := &Expression{ 944 Case: 59, 945 Expression: $1.(*Expression), 946 Token: $2, 947 Token2: $3, 948 Expression2: $4.(*Expression), 949 } 950 $$ = lhs 951 if !lx.tweaks.enableOmitConditionalOperand { 952 lx.report.Err(lhs.Pos(), "omitting conditional operand not enabled") 953 } 954 } 955 956 ExpressionOpt: 957 /* empty */ 958 { 959 $$ = (*ExpressionOpt)(nil) 960 } 961 | Expression 962 { 963 lx := yylex.(*lexer) 964 lhs := &ExpressionOpt{ 965 Expression: $1.(*Expression), 966 } 967 $$ = lhs 968 lhs.Expression.eval(lx) 969 } 970 971 ExpressionList: 972 Expression 973 { 974 $$ = &ExpressionList{ 975 Expression: $1.(*Expression), 976 } 977 } 978 | ExpressionList ',' Expression 979 { 980 $$ = &ExpressionList{ 981 Case: 1, 982 ExpressionList: $1.(*ExpressionList), 983 Token: $2, 984 Expression: $3.(*Expression), 985 } 986 } 987 988 ExpressionListOpt: 989 /* empty */ 990 { 991 $$ = (*ExpressionListOpt)(nil) 992 } 993 | ExpressionList 994 { 995 lx := yylex.(*lexer) 996 lhs := &ExpressionListOpt{ 997 ExpressionList: $1.(*ExpressionList).reverse(), 998 } 999 $$ = lhs 1000 lhs.ExpressionList.eval(lx) 1001 } 1002 1003 ConstantExpression: 1004 { 1005 lx := yylex.(*lexer) 1006 lx.constExprToks = []xc.Token{lx.last} 1007 } 1008 Expression 1009 { 1010 lx := yylex.(*lexer) 1011 lhs := &ConstantExpression{ 1012 Expression: $2.(*Expression), 1013 } 1014 $$ = lhs 1015 lhs.Value, lhs.Type = lhs.Expression.eval(lx) 1016 if lhs.Value == nil { 1017 lx.report.Err(lhs.Pos(), "not a constant expression") 1018 } 1019 l := lx.constExprToks 1020 lhs.toks = l[:len(l)-1] 1021 lx.constExprToks = nil 1022 } 1023 1024 Declaration: 1025 DeclarationSpecifiers InitDeclaratorListOpt ';' 1026 { 1027 lx := yylex.(*lexer) 1028 lhs := &Declaration{ 1029 DeclarationSpecifiers: $1.(*DeclarationSpecifiers), 1030 InitDeclaratorListOpt: $2.(*InitDeclaratorListOpt), 1031 Token: $3, 1032 } 1033 $$ = lhs 1034 ts0 := lhs.DeclarationSpecifiers.typeSpecifiers() 1035 if ts0 == 0 && lx.tweaks.enableImplicitIntType { 1036 lhs.DeclarationSpecifiers.typeSpecifier = tsEncode(tsInt) 1037 } 1038 ts := tsDecode(lhs.DeclarationSpecifiers.typeSpecifiers()) 1039 ok := false 1040 for _, v := range ts { 1041 if v == tsStructSpecifier || v == tsUnionSpecifier { 1042 ok = true 1043 break 1044 } 1045 } 1046 if ok { 1047 s := lhs.DeclarationSpecifiers 1048 d := &Declarator{specifier: s} 1049 dd := &DirectDeclarator{ 1050 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 1051 declarator: d, 1052 idScope: lx.scope, 1053 specifier: s, 1054 } 1055 d.DirectDeclarator = dd 1056 d.setFull(lx) 1057 for l := lhs.DeclarationSpecifiers; l != nil; { 1058 ts := l.TypeSpecifier 1059 if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}' 1060 ts.StructOrUnionSpecifier.declarator = d 1061 break 1062 } 1063 1064 if o := l.DeclarationSpecifiersOpt; o != nil { 1065 l = o.DeclarationSpecifiers 1066 continue 1067 } 1068 1069 break 1070 } 1071 } 1072 1073 o := lhs.InitDeclaratorListOpt 1074 if o != nil { 1075 break 1076 } 1077 1078 s := lhs.DeclarationSpecifiers 1079 d := &Declarator{specifier: s} 1080 dd := &DirectDeclarator{ 1081 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 1082 declarator: d, 1083 idScope: lx.scope, 1084 specifier: s, 1085 } 1086 d.DirectDeclarator = dd 1087 d.setFull(lx) 1088 lhs.declarator = d 1089 } 1090 | StaticAssertDeclaration 1091 { 1092 $$ = &Declaration{ 1093 Case: 1, 1094 StaticAssertDeclaration: $1.(*StaticAssertDeclaration), 1095 } 1096 } 1097 1098 DeclarationSpecifiers: 1099 StorageClassSpecifier DeclarationSpecifiersOpt 1100 { 1101 lx := yylex.(*lexer) 1102 lhs := &DeclarationSpecifiers{ 1103 StorageClassSpecifier: $1.(*StorageClassSpecifier), 1104 DeclarationSpecifiersOpt: $2.(*DeclarationSpecifiersOpt), 1105 } 1106 $$ = lhs 1107 lx.scope.specifier = lhs 1108 a := lhs.StorageClassSpecifier 1109 b := lhs.DeclarationSpecifiersOpt 1110 if b == nil { 1111 lhs.attr = a.attr 1112 break 1113 } 1114 1115 if a.attr&b.attr != 0 { 1116 lx.report.Err(a.Pos(), "invalid storage class specifier") 1117 break 1118 } 1119 1120 lhs.attr = a.attr|b.attr 1121 lhs.typeSpecifier = b.typeSpecifier 1122 if lhs.StorageClassSpecifier.Case != 0 /* "typedef" */ && lhs.IsTypedef() { 1123 lx.report.Err(a.Pos(), "invalid storage class specifier") 1124 } 1125 } 1126 | TypeSpecifier DeclarationSpecifiersOpt 1127 { 1128 lx := yylex.(*lexer) 1129 lhs := &DeclarationSpecifiers{ 1130 Case: 1, 1131 TypeSpecifier: $1.(*TypeSpecifier), 1132 DeclarationSpecifiersOpt: $2.(*DeclarationSpecifiersOpt), 1133 } 1134 $$ = lhs 1135 lx.scope.specifier = lhs 1136 a := lhs.TypeSpecifier 1137 b := lhs.DeclarationSpecifiersOpt 1138 if b == nil { 1139 lhs.typeSpecifier = a.typeSpecifier 1140 break 1141 } 1142 1143 lhs.attr = b.attr 1144 tsb := tsDecode(b.typeSpecifier) 1145 if len(tsb) == 1 && tsb[0] == tsTypedefName && lx.tweaks.allowCompatibleTypedefRedefinitions { 1146 tsb[0] = 0 1147 } 1148 ts := tsEncode(append(tsDecode(a.typeSpecifier), tsb...)...) 1149 if _, ok := tsValid[ts]; !ok { 1150 ts = tsEncode(tsInt) 1151 lx.report.Err(a.Pos(), "invalid type specifier") 1152 } 1153 lhs.typeSpecifier = ts 1154 } 1155 | TypeQualifier DeclarationSpecifiersOpt 1156 { 1157 lx := yylex.(*lexer) 1158 lhs := &DeclarationSpecifiers{ 1159 Case: 2, 1160 TypeQualifier: $1.(*TypeQualifier), 1161 DeclarationSpecifiersOpt: $2.(*DeclarationSpecifiersOpt), 1162 } 1163 $$ = lhs 1164 lx.scope.specifier = lhs 1165 a := lhs.TypeQualifier 1166 b := lhs.DeclarationSpecifiersOpt 1167 if b == nil { 1168 lhs.attr = a.attr 1169 break 1170 } 1171 1172 if a.attr&b.attr != 0 { 1173 lx.report.Err(a.Pos(), "invalid type qualifier") 1174 break 1175 } 1176 1177 lhs.attr = a.attr|b.attr 1178 lhs.typeSpecifier = b.typeSpecifier 1179 if lhs.IsTypedef() { 1180 lx.report.Err(a.Pos(), "invalid type qualifier") 1181 } 1182 } 1183 | FunctionSpecifier DeclarationSpecifiersOpt 1184 { 1185 lx := yylex.(*lexer) 1186 lhs := &DeclarationSpecifiers{ 1187 Case: 3, 1188 FunctionSpecifier: $1.(*FunctionSpecifier), 1189 DeclarationSpecifiersOpt: $2.(*DeclarationSpecifiersOpt), 1190 } 1191 $$ = lhs 1192 lx.scope.specifier = lhs 1193 a := lhs.FunctionSpecifier 1194 b := lhs.DeclarationSpecifiersOpt 1195 if b == nil { 1196 lhs.attr = a.attr 1197 break 1198 } 1199 1200 if a.attr&b.attr != 0 { 1201 lx.report.Err(a.Pos(), "invalid function specifier") 1202 break 1203 } 1204 1205 lhs.attr = a.attr|b.attr 1206 lhs.typeSpecifier = b.typeSpecifier 1207 if lhs.IsTypedef() { 1208 lx.report.Err(a.Pos(), "invalid function specifier") 1209 } 1210 } 1211 1212 DeclarationSpecifiersOpt: 1213 /* empty */ 1214 { 1215 $$ = (*DeclarationSpecifiersOpt)(nil) 1216 } 1217 | DeclarationSpecifiers 1218 { 1219 lhs := &DeclarationSpecifiersOpt{ 1220 DeclarationSpecifiers: $1.(*DeclarationSpecifiers), 1221 } 1222 $$ = lhs 1223 lhs.attr = lhs.DeclarationSpecifiers.attr 1224 lhs.typeSpecifier = lhs.DeclarationSpecifiers.typeSpecifier 1225 } 1226 1227 InitDeclaratorList: 1228 InitDeclarator 1229 { 1230 $$ = &InitDeclaratorList{ 1231 InitDeclarator: $1.(*InitDeclarator), 1232 } 1233 } 1234 | InitDeclaratorList ',' InitDeclarator 1235 { 1236 $$ = &InitDeclaratorList{ 1237 Case: 1, 1238 InitDeclaratorList: $1.(*InitDeclaratorList), 1239 Token: $2, 1240 InitDeclarator: $3.(*InitDeclarator), 1241 } 1242 } 1243 1244 InitDeclaratorListOpt: 1245 /* empty */ 1246 { 1247 $$ = (*InitDeclaratorListOpt)(nil) 1248 } 1249 | InitDeclaratorList 1250 { 1251 $$ = &InitDeclaratorListOpt{ 1252 InitDeclaratorList: $1.(*InitDeclaratorList).reverse(), 1253 } 1254 } 1255 1256 InitDeclarator: 1257 Declarator 1258 { 1259 lx := yylex.(*lexer) 1260 lhs := &InitDeclarator{ 1261 Declarator: $1.(*Declarator), 1262 } 1263 $$ = lhs 1264 lhs.Declarator.setFull(lx) 1265 } 1266 | Declarator 1267 { 1268 lx := yylex.(*lexer) 1269 d := $1.(*Declarator) 1270 d.setFull(lx) 1271 } 1272 '=' Initializer 1273 { 1274 lx := yylex.(*lexer) 1275 lhs := &InitDeclarator{ 1276 Case: 1, 1277 Declarator: $1.(*Declarator), 1278 Token: $3, 1279 Initializer: $4.(*Initializer), 1280 } 1281 $$ = lhs 1282 d := lhs.Declarator 1283 lhs.Initializer.typeCheck(&d.Type, d.Type, lhs.Declarator.specifier.IsStatic(), lx) 1284 if d.Type.Specifier().IsExtern() { 1285 id, _ := d.Identifier() 1286 lx.report.Err(d.Pos(), "'%s' initialized and declared 'extern'", dict.S(id)) 1287 } 1288 } 1289 1290 StorageClassSpecifier: 1291 "typedef" 1292 { 1293 lhs := &StorageClassSpecifier{ 1294 Token: $1, 1295 } 1296 $$ = lhs 1297 lhs.attr = saTypedef 1298 } 1299 | "extern" 1300 { 1301 lhs := &StorageClassSpecifier{ 1302 Case: 1, 1303 Token: $1, 1304 } 1305 $$ = lhs 1306 lhs.attr = saExtern 1307 } 1308 | "static" 1309 { 1310 lhs := &StorageClassSpecifier{ 1311 Case: 2, 1312 Token: $1, 1313 } 1314 $$ = lhs 1315 lhs.attr = saStatic 1316 } 1317 | "auto" 1318 { 1319 lhs := &StorageClassSpecifier{ 1320 Case: 3, 1321 Token: $1, 1322 } 1323 $$ = lhs 1324 lhs.attr = saAuto 1325 } 1326 | "register" 1327 { 1328 lhs := &StorageClassSpecifier{ 1329 Case: 4, 1330 Token: $1, 1331 } 1332 $$ = lhs 1333 lhs.attr = saRegister 1334 } 1335 1336 TypeSpecifier: 1337 "void" 1338 { 1339 lhs := &TypeSpecifier{ 1340 Token: $1, 1341 } 1342 $$ = lhs 1343 lhs.typeSpecifier = tsEncode(tsVoid) 1344 } 1345 | "char" 1346 { 1347 lhs := &TypeSpecifier{ 1348 Case: 1, 1349 Token: $1, 1350 } 1351 $$ = lhs 1352 lhs.typeSpecifier = tsEncode(tsChar) 1353 } 1354 | "short" 1355 { 1356 lhs := &TypeSpecifier{ 1357 Case: 2, 1358 Token: $1, 1359 } 1360 $$ = lhs 1361 lhs.typeSpecifier = tsEncode(tsShort) 1362 } 1363 | "int" 1364 { 1365 lhs := &TypeSpecifier{ 1366 Case: 3, 1367 Token: $1, 1368 } 1369 $$ = lhs 1370 lhs.typeSpecifier = tsEncode(tsInt) 1371 } 1372 | "long" 1373 { 1374 lhs := &TypeSpecifier{ 1375 Case: 4, 1376 Token: $1, 1377 } 1378 $$ = lhs 1379 lhs.typeSpecifier = tsEncode(tsLong) 1380 } 1381 | "float" 1382 { 1383 lhs := &TypeSpecifier{ 1384 Case: 5, 1385 Token: $1, 1386 } 1387 $$ = lhs 1388 lhs.typeSpecifier = tsEncode(tsFloat) 1389 } 1390 | "double" 1391 { 1392 lhs := &TypeSpecifier{ 1393 Case: 6, 1394 Token: $1, 1395 } 1396 $$ = lhs 1397 lhs.typeSpecifier = tsEncode(tsDouble) 1398 } 1399 | "signed" 1400 { 1401 lhs := &TypeSpecifier{ 1402 Case: 7, 1403 Token: $1, 1404 } 1405 $$ = lhs 1406 lhs.typeSpecifier = tsEncode(tsSigned) 1407 } 1408 | "unsigned" 1409 { 1410 lhs := &TypeSpecifier{ 1411 Case: 8, 1412 Token: $1, 1413 } 1414 $$ = lhs 1415 lhs.typeSpecifier = tsEncode(tsUnsigned) 1416 } 1417 | "_Bool" 1418 { 1419 lhs := &TypeSpecifier{ 1420 Case: 9, 1421 Token: $1, 1422 } 1423 $$ = lhs 1424 lhs.typeSpecifier = tsEncode(tsBool) 1425 } 1426 | "_Complex" 1427 { 1428 lhs := &TypeSpecifier{ 1429 Case: 10, 1430 Token: $1, 1431 } 1432 $$ = lhs 1433 lhs.typeSpecifier = tsEncode(tsComplex) 1434 } 1435 | StructOrUnionSpecifier 1436 { 1437 lhs := &TypeSpecifier{ 1438 Case: 11, 1439 StructOrUnionSpecifier: $1.(*StructOrUnionSpecifier), 1440 } 1441 $$ = lhs 1442 lhs.typeSpecifier = tsEncode(lhs.StructOrUnionSpecifier.typeSpecifiers()) 1443 } 1444 | EnumSpecifier 1445 { 1446 lhs := &TypeSpecifier{ 1447 Case: 12, 1448 EnumSpecifier: $1.(*EnumSpecifier), 1449 } 1450 $$ = lhs 1451 lhs.typeSpecifier = tsEncode(tsEnumSpecifier) 1452 } 1453 | TYPEDEFNAME 1454 { 1455 lx := yylex.(*lexer) 1456 lhs := &TypeSpecifier{ 1457 Case: 13, 1458 Token: $1, 1459 } 1460 $$ = lhs 1461 lhs.typeSpecifier = tsEncode(tsTypedefName) 1462 _, lhs.scope = lx.scope.Lookup2(NSIdentifiers, lhs.Token.Val) 1463 } 1464 | "typeof" '(' Expression ')' 1465 { 1466 lx := yylex.(*lexer) 1467 lhs := &TypeSpecifier{ 1468 Case: 14, 1469 Token: $1, 1470 Token2: $2, 1471 Expression: $3.(*Expression), 1472 Token3: $4, 1473 } 1474 $$ = lhs 1475 lhs.typeSpecifier = tsEncode(tsTypeof) 1476 _, lhs.Type = lhs.Expression.eval(lx) 1477 } 1478 | "typeof" '(' TypeName ')' 1479 { 1480 lhs := &TypeSpecifier{ 1481 Case: 15, 1482 Token: $1, 1483 Token2: $2, 1484 TypeName: $3.(*TypeName), 1485 Token3: $4, 1486 } 1487 $$ = lhs 1488 lhs.typeSpecifier = tsEncode(tsTypeof) 1489 lhs.Type = undefined 1490 if t := lhs.TypeName.Type; t != nil { 1491 lhs.Type = t 1492 } 1493 } 1494 1495 StructOrUnionSpecifier: 1496 StructOrUnion IdentifierOpt '{' 1497 { 1498 lx := yylex.(*lexer) 1499 if o := $2.(*IdentifierOpt); o != nil { 1500 lx.scope.declareStructTag(o.Token, lx.report) 1501 } 1502 lx.pushScope(ScopeMembers) 1503 lx.scope.isUnion = $1.(*StructOrUnion).Case == 1 // "union" 1504 lx.scope.prevStructDeclarator = nil 1505 } 1506 StructDeclarationList '}' 1507 { 1508 lx := yylex.(*lexer) 1509 lhs := &StructOrUnionSpecifier{ 1510 StructOrUnion: $1.(*StructOrUnion), 1511 IdentifierOpt: $2.(*IdentifierOpt), 1512 Token: $3, 1513 StructDeclarationList: $5.(*StructDeclarationList).reverse(), 1514 Token2: $6, 1515 } 1516 $$ = lhs 1517 sc := lx.scope 1518 lhs.scope = sc 1519 if sc.bitOffset != 0 { 1520 finishBitField(lhs, lx) 1521 } 1522 1523 i := 0 1524 var bt Type 1525 var d *Declarator 1526 for l := lhs.StructDeclarationList; l != nil; l = l.StructDeclarationList { 1527 for l := l.StructDeclaration.StructDeclaratorList; l != nil; l = l.StructDeclaratorList { 1528 switch sd := l.StructDeclarator; sd.Case { 1529 case 0: // Declarator 1530 d = sd.Declarator 1531 case 1: // DeclaratorOpt ':' ConstantExpression 1532 if o := sd.DeclaratorOpt; o != nil { 1533 x := o.Declarator 1534 if x.bitOffset == 0 { 1535 d = x 1536 bt = lx.scope.bitFieldTypes[i] 1537 i++ 1538 } 1539 x.bitFieldType = bt 1540 } 1541 } 1542 } 1543 } 1544 lx.scope.bitFieldTypes = nil 1545 1546 lhs.alignOf = sc.maxAlign 1547 switch { 1548 case sc.isUnion: 1549 lhs.sizeOf = align(sc.maxSize, sc.maxAlign) 1550 default: 1551 off := sc.offset 1552 lhs.sizeOf = align(sc.offset, sc.maxAlign) 1553 if d != nil { 1554 d.padding = lhs.sizeOf-off 1555 } 1556 } 1557 1558 lx.popScope(lhs.Token2) 1559 if o := lhs.IdentifierOpt; o != nil { 1560 lx.scope.defineStructTag(o.Token, lhs, lx.report) 1561 } 1562 } 1563 | StructOrUnion IDENTIFIER 1564 { 1565 lx := yylex.(*lexer) 1566 lhs := &StructOrUnionSpecifier{ 1567 Case: 1, 1568 StructOrUnion: $1.(*StructOrUnion), 1569 Token: $2, 1570 } 1571 $$ = lhs 1572 lx.scope.declareStructTag(lhs.Token, lx.report) 1573 lhs.scope = lx.scope 1574 } 1575 | StructOrUnion IdentifierOpt '{' '}' 1576 { 1577 lx := yylex.(*lexer) 1578 lhs := &StructOrUnionSpecifier{ 1579 Case: 2, 1580 StructOrUnion: $1.(*StructOrUnion), 1581 IdentifierOpt: $2.(*IdentifierOpt), 1582 Token: $3, 1583 Token2: $4, 1584 } 1585 $$ = lhs 1586 if !lx.tweaks.enableEmptyStructs { 1587 lx.report.Err(lhs.Token.Pos(), "empty structs/unions not allowed") 1588 } 1589 if o := $2.(*IdentifierOpt); o != nil { 1590 lx.scope.declareStructTag(o.Token, lx.report) 1591 } 1592 lx.scope.isUnion = $1.(*StructOrUnion).Case == 1 // "union" 1593 lx.scope.prevStructDeclarator = nil 1594 lhs.alignOf = 1 1595 lhs.sizeOf = 0 1596 if o := lhs.IdentifierOpt; o != nil { 1597 lx.scope.defineStructTag(o.Token, lhs, lx.report) 1598 } 1599 } 1600 1601 StructOrUnion: 1602 "struct" 1603 { 1604 $$ = &StructOrUnion{ 1605 Token: $1, 1606 } 1607 } 1608 | "union" 1609 { 1610 $$ = &StructOrUnion{ 1611 Case: 1, 1612 Token: $1, 1613 } 1614 } 1615 1616 StructDeclarationList: 1617 StructDeclaration 1618 { 1619 $$ = &StructDeclarationList{ 1620 StructDeclaration: $1.(*StructDeclaration), 1621 } 1622 } 1623 | StructDeclarationList StructDeclaration 1624 { 1625 $$ = &StructDeclarationList{ 1626 Case: 1, 1627 StructDeclarationList: $1.(*StructDeclarationList), 1628 StructDeclaration: $2.(*StructDeclaration), 1629 } 1630 } 1631 1632 StructDeclaration: 1633 SpecifierQualifierList StructDeclaratorList ';' 1634 { 1635 lx := yylex.(*lexer) 1636 lhs := &StructDeclaration{ 1637 SpecifierQualifierList: $1.(*SpecifierQualifierList), 1638 StructDeclaratorList: $2.(*StructDeclaratorList).reverse(), 1639 Token: $3, 1640 } 1641 $$ = lhs 1642 s := lhs.SpecifierQualifierList 1643 if k := s.kind(); k != Struct && k != Union { 1644 break 1645 } 1646 1647 d := &Declarator{specifier: s} 1648 dd := &DirectDeclarator{ 1649 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 1650 declarator: d, 1651 idScope: lx.scope, 1652 specifier: s, 1653 } 1654 d.DirectDeclarator = dd 1655 d.setFull(lx) 1656 for l := lhs.SpecifierQualifierList; l != nil; { 1657 ts := l.TypeSpecifier 1658 if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}' 1659 ts.StructOrUnionSpecifier.declarator = d 1660 break 1661 } 1662 1663 if o := l.SpecifierQualifierListOpt; o != nil { 1664 l = o.SpecifierQualifierList 1665 continue 1666 } 1667 1668 break 1669 } 1670 } 1671 | SpecifierQualifierList ';' 1672 { 1673 lx := yylex.(*lexer) 1674 lhs := &StructDeclaration{ 1675 Case: 1, 1676 SpecifierQualifierList: $1.(*SpecifierQualifierList), 1677 Token: $2, 1678 } 1679 $$ = lhs 1680 s := lhs.SpecifierQualifierList 1681 if !lx.tweaks.enableAnonymousStructFields { 1682 lx.report.Err(lhs.Token.Pos(), "unnamed fields not allowed") 1683 } else if k := s.kind(); k != Struct && k != Union { 1684 lx.report.Err(lhs.Token.Pos(), "only unnamed structs and unions are allowed") 1685 break 1686 } 1687 1688 d := &Declarator{specifier: s} 1689 dd := &DirectDeclarator{ 1690 Token: xc.Token{Char: lex.NewChar(lhs.Pos(), 0)}, 1691 declarator: d, 1692 idScope: lx.scope, 1693 specifier: s, 1694 } 1695 d.DirectDeclarator = dd 1696 d.setFull(lx) 1697 1698 // we have no struct declarators to parse, so we have to create the case of one implicit declarator 1699 // because else the size of anonymous members is not included in the struct size! 1700 dummy := &StructDeclarator{Declarator: d} 1701 dummy.post(lx) 1702 1703 for l := lhs.SpecifierQualifierList; l != nil; { 1704 ts := l.TypeSpecifier 1705 if ts != nil && ts.Case == 11 && ts.StructOrUnionSpecifier.Case == 0 { // StructOrUnion IdentifierOpt '{' StructDeclarationList '}' 1706 ts.StructOrUnionSpecifier.declarator = d 1707 break 1708 } 1709 1710 if o := l.SpecifierQualifierListOpt; o != nil { 1711 l = o.SpecifierQualifierList 1712 continue 1713 } 1714 1715 break 1716 } 1717 } 1718 | StaticAssertDeclaration 1719 { 1720 $$ = &StructDeclaration{ 1721 Case: 2, 1722 StaticAssertDeclaration: $1.(*StaticAssertDeclaration), 1723 } 1724 } 1725 1726 SpecifierQualifierList: 1727 TypeSpecifier SpecifierQualifierListOpt 1728 { 1729 lx := yylex.(*lexer) 1730 lhs := &SpecifierQualifierList{ 1731 TypeSpecifier: $1.(*TypeSpecifier), 1732 SpecifierQualifierListOpt: $2.(*SpecifierQualifierListOpt), 1733 } 1734 $$ = lhs 1735 lx.scope.specifier = lhs 1736 a := lhs.TypeSpecifier 1737 b := lhs.SpecifierQualifierListOpt 1738 if b == nil { 1739 lhs.typeSpecifier = a.typeSpecifier 1740 break 1741 } 1742 1743 lhs.attr = b.attr 1744 ts := tsEncode(append(tsDecode(a.typeSpecifier), tsDecode(b.typeSpecifier)...)...) 1745 if _, ok := tsValid[ts]; !ok { 1746 lx.report.Err(a.Pos(), "invalid type specifier") 1747 break 1748 } 1749 1750 lhs.typeSpecifier = ts 1751 } 1752 | TypeQualifier SpecifierQualifierListOpt 1753 { 1754 lx := yylex.(*lexer) 1755 lhs := &SpecifierQualifierList{ 1756 Case: 1, 1757 TypeQualifier: $1.(*TypeQualifier), 1758 SpecifierQualifierListOpt: $2.(*SpecifierQualifierListOpt), 1759 } 1760 $$ = lhs 1761 lx.scope.specifier = lhs 1762 a := lhs.TypeQualifier 1763 b := lhs.SpecifierQualifierListOpt 1764 if b == nil { 1765 lhs.attr = a.attr 1766 break 1767 } 1768 1769 if a.attr&b.attr != 0 { 1770 lx.report.Err(a.Pos(), "invalid type qualifier") 1771 break 1772 } 1773 1774 lhs.attr = a.attr|b.attr 1775 lhs.typeSpecifier = b.typeSpecifier 1776 } 1777 1778 SpecifierQualifierListOpt: 1779 /* empty */ 1780 { 1781 $$ = (*SpecifierQualifierListOpt)(nil) 1782 } 1783 | SpecifierQualifierList 1784 { 1785 lhs := &SpecifierQualifierListOpt{ 1786 SpecifierQualifierList: $1.(*SpecifierQualifierList), 1787 } 1788 $$ = lhs 1789 lhs.attr = lhs.SpecifierQualifierList.attr 1790 lhs.typeSpecifier = lhs.SpecifierQualifierList.typeSpecifier 1791 } 1792 1793 StructDeclaratorList: 1794 StructDeclarator 1795 { 1796 $$ = &StructDeclaratorList{ 1797 StructDeclarator: $1.(*StructDeclarator), 1798 } 1799 } 1800 | StructDeclaratorList ',' StructDeclarator 1801 { 1802 $$ = &StructDeclaratorList{ 1803 Case: 1, 1804 StructDeclaratorList: $1.(*StructDeclaratorList), 1805 Token: $2, 1806 StructDeclarator: $3.(*StructDeclarator), 1807 } 1808 } 1809 1810 StructDeclarator: 1811 Declarator 1812 { 1813 lx := yylex.(*lexer) 1814 lhs := &StructDeclarator{ 1815 Declarator: $1.(*Declarator), 1816 } 1817 $$ = lhs 1818 lhs.Declarator.setFull(lx) 1819 lhs.post(lx) 1820 } 1821 | DeclaratorOpt ':' ConstantExpression 1822 { 1823 lx := yylex.(*lexer) 1824 lhs := &StructDeclarator{ 1825 Case: 1, 1826 DeclaratorOpt: $1.(*DeclaratorOpt), 1827 Token: $2, 1828 ConstantExpression: $3.(*ConstantExpression), 1829 } 1830 $$ = lhs 1831 m := lx.model 1832 e := lhs.ConstantExpression 1833 if e.Value == nil { 1834 e.Value, e.Type = m.value2(1, m.IntType) 1835 } 1836 if !IsIntType(e.Type) { 1837 lx.report.Err(e.Pos(), "bit field width not an integer (have '%s')", e.Type) 1838 e.Value, e.Type = m.value2(1, m.IntType) 1839 } 1840 if o := lhs.DeclaratorOpt; o != nil { 1841 o.Declarator.setFull(lx) 1842 } 1843 lhs.post(lx) 1844 } 1845 1846 CommaOpt: 1847 /* empty */ 1848 { 1849 $$ = (*CommaOpt)(nil) 1850 } 1851 | ',' 1852 { 1853 $$ = &CommaOpt{ 1854 Token: $1, 1855 } 1856 } 1857 1858 EnumSpecifier: 1859 "enum" IdentifierOpt 1860 { 1861 lx := yylex.(*lexer) 1862 if o := $2.(*IdentifierOpt); o != nil { 1863 lx.scope.declareEnumTag(o.Token, lx.report) 1864 } 1865 lx.iota = 0 1866 } 1867 '{' EnumeratorList CommaOpt '}' 1868 { 1869 lx := yylex.(*lexer) 1870 lhs := &EnumSpecifier{ 1871 Token: $1, 1872 IdentifierOpt: $2.(*IdentifierOpt), 1873 Token2: $4, 1874 EnumeratorList: $5.(*EnumeratorList).reverse(), 1875 CommaOpt: $6.(*CommaOpt), 1876 Token3: $7, 1877 } 1878 $$ = lhs 1879 if o := lhs.IdentifierOpt; o != nil { 1880 lx.scope.defineEnumTag(o.Token, lhs, lx.report) 1881 } 1882 if !lx.tweaks.enableUnsignedEnums { 1883 break 1884 } 1885 1886 lhs.unsigned = true 1887 loop: 1888 for l := lhs.EnumeratorList; l != nil; l = l.EnumeratorList { 1889 switch e := l.Enumerator; x := e.Value.(type) { 1890 case int32: 1891 if x < 0 { 1892 lhs.unsigned = false 1893 break loop 1894 } 1895 case int64: 1896 if x < 0 { 1897 lhs.unsigned = false 1898 break loop 1899 } 1900 default: 1901 panic(fmt.Errorf("%s: TODO Enumerator.Value type %T", position(e.Pos()), x)) 1902 } 1903 } 1904 } 1905 | "enum" IDENTIFIER 1906 { 1907 lx := yylex.(*lexer) 1908 lhs := &EnumSpecifier{ 1909 Case: 1, 1910 Token: $1, 1911 Token2: $2, 1912 } 1913 $$ = lhs 1914 lx.scope.declareEnumTag(lhs.Token2, lx.report) 1915 } 1916 1917 EnumeratorList: 1918 Enumerator 1919 { 1920 $$ = &EnumeratorList{ 1921 Enumerator: $1.(*Enumerator), 1922 } 1923 } 1924 | EnumeratorList ',' Enumerator 1925 { 1926 $$ = &EnumeratorList{ 1927 Case: 1, 1928 EnumeratorList: $1.(*EnumeratorList), 1929 Token: $2, 1930 Enumerator: $3.(*Enumerator), 1931 } 1932 } 1933 1934 Enumerator: 1935 EnumerationConstant 1936 { 1937 lx := yylex.(*lexer) 1938 lhs := &Enumerator{ 1939 EnumerationConstant: $1.(*EnumerationConstant), 1940 } 1941 $$ = lhs 1942 m := lx.model 1943 v := m.MustConvert(lx.iota, m.IntType) 1944 lhs.Value = v 1945 lx.scope.defineEnumConst(lx, lhs.EnumerationConstant.Token, v) 1946 } 1947 | EnumerationConstant '=' ConstantExpression 1948 { 1949 lx := yylex.(*lexer) 1950 lhs := &Enumerator{ 1951 Case: 1, 1952 EnumerationConstant: $1.(*EnumerationConstant), 1953 Token: $2, 1954 ConstantExpression: $3.(*ConstantExpression), 1955 } 1956 $$ = lhs 1957 m := lx.model 1958 e := lhs.ConstantExpression 1959 var v interface{} 1960 // [0], 6.7.2.2 1961 // The expression that defines the value of an enumeration 1962 // constant shall be an integer constant expression that has a 1963 // value representable as an int. 1964 switch { 1965 case !IsIntType(e.Type): 1966 lx.report.Err(e.Pos(), "not an integer constant expression (have '%s')", e.Type) 1967 v = m.MustConvert(int32(0), m.IntType) 1968 default: 1969 var ok bool 1970 if v, ok = m.enumValueToInt(e.Value); !ok { 1971 lx.report.Err(e.Pos(), "overflow in enumeration value: %v", e.Value) 1972 } 1973 } 1974 1975 lhs.Value = v 1976 lx.scope.defineEnumConst(lx, lhs.EnumerationConstant.Token, v) 1977 } 1978 1979 TypeQualifier: 1980 "const" 1981 { 1982 lhs := &TypeQualifier{ 1983 Token: $1, 1984 } 1985 $$ = lhs 1986 lhs.attr = saConst 1987 } 1988 | "restrict" 1989 { 1990 lhs := &TypeQualifier{ 1991 Case: 1, 1992 Token: $1, 1993 } 1994 $$ = lhs 1995 lhs.attr = saRestrict 1996 } 1997 | "volatile" 1998 { 1999 lhs := &TypeQualifier{ 2000 Case: 2, 2001 Token: $1, 2002 } 2003 $$ = lhs 2004 lhs.attr = saVolatile 2005 } 2006 2007 FunctionSpecifier: 2008 "inline" 2009 { 2010 lhs := &FunctionSpecifier{ 2011 Token: $1, 2012 } 2013 $$ = lhs 2014 lhs.attr = saInline 2015 } 2016 | "_Noreturn" 2017 { 2018 lhs := &FunctionSpecifier{ 2019 Case: 1, 2020 Token: $1, 2021 } 2022 $$ = lhs 2023 lhs.attr = saNoreturn 2024 } 2025 2026 Declarator: 2027 PointerOpt DirectDeclarator 2028 { 2029 lx := yylex.(*lexer) 2030 lhs := &Declarator{ 2031 PointerOpt: $1.(*PointerOpt), 2032 DirectDeclarator: $2.(*DirectDeclarator), 2033 } 2034 $$ = lhs 2035 lhs.specifier = lx.scope.specifier 2036 lhs.DirectDeclarator.declarator = lhs 2037 } 2038 2039 DeclaratorOpt: 2040 /* empty */ 2041 { 2042 $$ = (*DeclaratorOpt)(nil) 2043 } 2044 | Declarator 2045 { 2046 $$ = &DeclaratorOpt{ 2047 Declarator: $1.(*Declarator), 2048 } 2049 } 2050 2051 DirectDeclarator: 2052 IDENTIFIER 2053 { 2054 lx := yylex.(*lexer) 2055 lhs := &DirectDeclarator{ 2056 Token: $1, 2057 } 2058 $$ = lhs 2059 lhs.specifier = lx.scope.specifier 2060 lx.scope.declareIdentifier(lhs.Token, lhs, lx.report) 2061 lhs.idScope = lx.scope 2062 } 2063 | '(' Declarator ')' 2064 { 2065 lhs := &DirectDeclarator{ 2066 Case: 1, 2067 Token: $1, 2068 Declarator: $2.(*Declarator), 2069 Token2: $3, 2070 } 2071 $$ = lhs 2072 lhs.Declarator.specifier = nil 2073 lhs.Declarator.DirectDeclarator.parent = lhs 2074 } 2075 | DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']' 2076 { 2077 lx := yylex.(*lexer) 2078 lhs := &DirectDeclarator{ 2079 Case: 2, 2080 DirectDeclarator: $1.(*DirectDeclarator), 2081 Token: $2, 2082 TypeQualifierListOpt: $3.(*TypeQualifierListOpt), 2083 ExpressionOpt: $4.(*ExpressionOpt), 2084 Token2: $5, 2085 } 2086 $$ = lhs 2087 lhs.elements = -1 2088 if o := lhs.ExpressionOpt; o != nil { 2089 var err error 2090 if lhs.elements, err = elements(o.Expression.eval(lx)); err != nil { 2091 lx.report.Err(o.Expression.Pos(), "%s", err) 2092 } 2093 2094 } 2095 lhs.DirectDeclarator.parent = lhs 2096 } 2097 | DirectDeclarator '[' "static" TypeQualifierListOpt Expression ']' 2098 { 2099 lx := yylex.(*lexer) 2100 lhs := &DirectDeclarator{ 2101 Case: 3, 2102 DirectDeclarator: $1.(*DirectDeclarator), 2103 Token: $2, 2104 Token2: $3, 2105 TypeQualifierListOpt: $4.(*TypeQualifierListOpt), 2106 Expression: $5.(*Expression), 2107 Token3: $6, 2108 } 2109 $$ = lhs 2110 var err error 2111 if lhs.elements, err = elements(lhs.Expression.eval(lx)); err != nil { 2112 lx.report.Err(lhs.Expression.Pos(), "%s", err) 2113 } 2114 lhs.DirectDeclarator.parent = lhs 2115 } 2116 | DirectDeclarator '[' TypeQualifierList "static" Expression ']' 2117 { 2118 lx := yylex.(*lexer) 2119 lhs := &DirectDeclarator{ 2120 Case: 4, 2121 DirectDeclarator: $1.(*DirectDeclarator), 2122 Token: $2, 2123 TypeQualifierList: $3.(*TypeQualifierList).reverse(), 2124 Token2: $4, 2125 Expression: $5.(*Expression), 2126 Token3: $6, 2127 } 2128 $$ = lhs 2129 var err error 2130 if lhs.elements, err = elements(lhs.Expression.eval(lx)); err != nil { 2131 lx.report.Err(lhs.Expression.Pos(), "%s", err) 2132 } 2133 lhs.DirectDeclarator.parent = lhs 2134 } 2135 | DirectDeclarator '[' TypeQualifierListOpt '*' ']' 2136 { 2137 lhs := &DirectDeclarator{ 2138 Case: 5, 2139 DirectDeclarator: $1.(*DirectDeclarator), 2140 Token: $2, 2141 TypeQualifierListOpt: $3.(*TypeQualifierListOpt), 2142 Token2: $4, 2143 Token3: $5, 2144 } 2145 $$ = lhs 2146 lhs.DirectDeclarator.parent = lhs 2147 lhs.elements = -1 2148 } 2149 | DirectDeclarator '(' 2150 { 2151 lx := yylex.(*lexer) 2152 lx.pushScope(ScopeParams) 2153 } 2154 ParameterTypeList ')' 2155 { 2156 lx := yylex.(*lexer) 2157 lhs := &DirectDeclarator{ 2158 Case: 6, 2159 DirectDeclarator: $1.(*DirectDeclarator), 2160 Token: $2, 2161 ParameterTypeList: $4.(*ParameterTypeList), 2162 Token2: $5, 2163 } 2164 $$ = lhs 2165 lhs.paramsScope, _ = lx.popScope(lhs.Token2) 2166 lhs.DirectDeclarator.parent = lhs 2167 } 2168 | DirectDeclarator '(' IdentifierListOpt ')' 2169 { 2170 lhs := &DirectDeclarator{ 2171 Case: 7, 2172 DirectDeclarator: $1.(*DirectDeclarator), 2173 Token: $2, 2174 IdentifierListOpt: $3.(*IdentifierListOpt), 2175 Token2: $4, 2176 } 2177 $$ = lhs 2178 lhs.DirectDeclarator.parent = lhs 2179 } 2180 2181 Pointer: 2182 '*' TypeQualifierListOpt 2183 { 2184 $$ = &Pointer{ 2185 Token: $1, 2186 TypeQualifierListOpt: $2.(*TypeQualifierListOpt), 2187 } 2188 } 2189 | '*' TypeQualifierListOpt Pointer 2190 { 2191 $$ = &Pointer{ 2192 Case: 1, 2193 Token: $1, 2194 TypeQualifierListOpt: $2.(*TypeQualifierListOpt), 2195 Pointer: $3.(*Pointer), 2196 } 2197 } 2198 2199 PointerOpt: 2200 /* empty */ 2201 { 2202 $$ = (*PointerOpt)(nil) 2203 } 2204 | Pointer 2205 { 2206 $$ = &PointerOpt{ 2207 Pointer: $1.(*Pointer), 2208 } 2209 } 2210 2211 TypeQualifierList: 2212 TypeQualifier 2213 { 2214 lhs := &TypeQualifierList{ 2215 TypeQualifier: $1.(*TypeQualifier), 2216 } 2217 $$ = lhs 2218 lhs.attr = lhs.TypeQualifier.attr 2219 } 2220 | TypeQualifierList TypeQualifier 2221 { 2222 lx := yylex.(*lexer) 2223 lhs := &TypeQualifierList{ 2224 Case: 1, 2225 TypeQualifierList: $1.(*TypeQualifierList), 2226 TypeQualifier: $2.(*TypeQualifier), 2227 } 2228 $$ = lhs 2229 a := lhs.TypeQualifierList 2230 b := lhs.TypeQualifier 2231 if a.attr&b.attr != 0 { 2232 lx.report.Err(b.Pos(), "invalid type qualifier") 2233 break 2234 } 2235 2236 lhs.attr = a.attr|b.attr 2237 } 2238 2239 TypeQualifierListOpt: 2240 /* empty */ 2241 { 2242 $$ = (*TypeQualifierListOpt)(nil) 2243 } 2244 | TypeQualifierList 2245 { 2246 $$ = &TypeQualifierListOpt{ 2247 TypeQualifierList: $1.(*TypeQualifierList).reverse(), 2248 } 2249 } 2250 2251 ParameterTypeList: 2252 ParameterList 2253 { 2254 lhs := &ParameterTypeList{ 2255 ParameterList: $1.(*ParameterList).reverse(), 2256 } 2257 $$ = lhs 2258 lhs.post() 2259 } 2260 | ParameterList ',' "..." 2261 { 2262 lhs := &ParameterTypeList{ 2263 Case: 1, 2264 ParameterList: $1.(*ParameterList).reverse(), 2265 Token: $2, 2266 Token2: $3, 2267 } 2268 $$ = lhs 2269 lhs.post() 2270 } 2271 2272 ParameterTypeListOpt: 2273 /* empty */ 2274 { 2275 $$ = (*ParameterTypeListOpt)(nil) 2276 } 2277 | ParameterTypeList 2278 { 2279 $$ = &ParameterTypeListOpt{ 2280 ParameterTypeList: $1.(*ParameterTypeList), 2281 } 2282 } 2283 2284 ParameterList: 2285 ParameterDeclaration 2286 { 2287 $$ = &ParameterList{ 2288 ParameterDeclaration: $1.(*ParameterDeclaration), 2289 } 2290 } 2291 | ParameterList ',' ParameterDeclaration 2292 { 2293 $$ = &ParameterList{ 2294 Case: 1, 2295 ParameterList: $1.(*ParameterList), 2296 Token: $2, 2297 ParameterDeclaration: $3.(*ParameterDeclaration), 2298 } 2299 } 2300 2301 ParameterDeclaration: 2302 DeclarationSpecifiers Declarator 2303 { 2304 lx := yylex.(*lexer) 2305 lhs := &ParameterDeclaration{ 2306 DeclarationSpecifiers: $1.(*DeclarationSpecifiers), 2307 Declarator: $2.(*Declarator), 2308 } 2309 $$ = lhs 2310 lhs.Declarator.setFull(lx) 2311 lhs.declarator = lhs.Declarator 2312 } 2313 | DeclarationSpecifiers AbstractDeclaratorOpt 2314 { 2315 lx := yylex.(*lexer) 2316 lhs := &ParameterDeclaration{ 2317 Case: 1, 2318 DeclarationSpecifiers: $1.(*DeclarationSpecifiers), 2319 AbstractDeclaratorOpt: $2.(*AbstractDeclaratorOpt), 2320 } 2321 $$ = lhs 2322 if o := lhs.AbstractDeclaratorOpt; o != nil { 2323 lhs.declarator = o.AbstractDeclarator.declarator 2324 lhs.declarator.setFull(lx) 2325 break 2326 } 2327 2328 d := &Declarator{ 2329 specifier: lx.scope.specifier, 2330 DirectDeclarator: &DirectDeclarator{ 2331 Case: 0, // IDENTIFIER 2332 }, 2333 } 2334 d.DirectDeclarator.declarator = d 2335 lhs.declarator = d 2336 d.setFull(lx) 2337 } 2338 2339 IdentifierList: 2340 IDENTIFIER 2341 { 2342 $$ = &IdentifierList{ 2343 Token: $1, 2344 } 2345 } 2346 | IdentifierList ',' IDENTIFIER 2347 { 2348 $$ = &IdentifierList{ 2349 Case: 1, 2350 IdentifierList: $1.(*IdentifierList), 2351 Token: $2, 2352 Token2: $3, 2353 } 2354 } 2355 2356 IdentifierListOpt: 2357 /* empty */ 2358 { 2359 $$ = (*IdentifierListOpt)(nil) 2360 } 2361 | IdentifierList 2362 { 2363 $$ = &IdentifierListOpt{ 2364 IdentifierList: $1.(*IdentifierList).reverse(), 2365 } 2366 } 2367 2368 IdentifierOpt: 2369 /* empty */ 2370 { 2371 $$ = (*IdentifierOpt)(nil) 2372 } 2373 | IDENTIFIER 2374 { 2375 $$ = &IdentifierOpt{ 2376 Token: $1, 2377 } 2378 } 2379 2380 TypeName: 2381 { 2382 lx := yylex.(*lexer) 2383 lx.pushScope(ScopeBlock) 2384 } 2385 SpecifierQualifierList AbstractDeclaratorOpt 2386 { 2387 lx := yylex.(*lexer) 2388 lhs := &TypeName{ 2389 SpecifierQualifierList: $2.(*SpecifierQualifierList), 2390 AbstractDeclaratorOpt: $3.(*AbstractDeclaratorOpt), 2391 } 2392 $$ = lhs 2393 if o := lhs.AbstractDeclaratorOpt; o != nil { 2394 lhs.declarator = o.AbstractDeclarator.declarator 2395 } else { 2396 d := &Declarator{ 2397 specifier: lhs.SpecifierQualifierList, 2398 DirectDeclarator: &DirectDeclarator{ 2399 Case: 0, // IDENTIFIER 2400 idScope: lx.scope, 2401 }, 2402 } 2403 d.DirectDeclarator.declarator = d 2404 lhs.declarator = d 2405 } 2406 lhs.Type = lhs.declarator.setFull(lx) 2407 lhs.scope = lx.scope 2408 lx.popScope(xc.Token{}) 2409 } 2410 2411 AbstractDeclarator: 2412 Pointer 2413 { 2414 lx := yylex.(*lexer) 2415 lhs := &AbstractDeclarator{ 2416 Pointer: $1.(*Pointer), 2417 } 2418 $$ = lhs 2419 d := &Declarator{ 2420 specifier: lx.scope.specifier, 2421 PointerOpt: &PointerOpt { 2422 Pointer: lhs.Pointer, 2423 }, 2424 DirectDeclarator: &DirectDeclarator{ 2425 Case: 0, // IDENTIFIER 2426 idScope: lx.scope, 2427 }, 2428 } 2429 d.DirectDeclarator.declarator = d 2430 lhs.declarator = d 2431 } 2432 | PointerOpt DirectAbstractDeclarator 2433 { 2434 lx := yylex.(*lexer) 2435 lhs := &AbstractDeclarator{ 2436 Case: 1, 2437 PointerOpt: $1.(*PointerOpt), 2438 DirectAbstractDeclarator: $2.(*DirectAbstractDeclarator), 2439 } 2440 $$ = lhs 2441 d := &Declarator{ 2442 specifier: lx.scope.specifier, 2443 PointerOpt: lhs.PointerOpt, 2444 DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator, 2445 } 2446 d.DirectDeclarator.declarator = d 2447 lhs.declarator = d 2448 } 2449 2450 AbstractDeclaratorOpt: 2451 /* empty */ 2452 { 2453 $$ = (*AbstractDeclaratorOpt)(nil) 2454 } 2455 | AbstractDeclarator 2456 { 2457 $$ = &AbstractDeclaratorOpt{ 2458 AbstractDeclarator: $1.(*AbstractDeclarator), 2459 } 2460 } 2461 2462 DirectAbstractDeclarator: 2463 '(' AbstractDeclarator ')' 2464 { 2465 lhs := &DirectAbstractDeclarator{ 2466 Token: $1, 2467 AbstractDeclarator: $2.(*AbstractDeclarator), 2468 Token2: $3, 2469 } 2470 $$ = lhs 2471 lhs.AbstractDeclarator.declarator.specifier = nil 2472 lhs.directDeclarator = &DirectDeclarator{ 2473 Case: 1, // '(' Declarator ')' 2474 Declarator: lhs.AbstractDeclarator.declarator, 2475 } 2476 lhs.AbstractDeclarator.declarator.DirectDeclarator.parent = lhs.directDeclarator 2477 } 2478 | DirectAbstractDeclaratorOpt '[' ExpressionOpt ']' 2479 { 2480 lx := yylex.(*lexer) 2481 lhs := &DirectAbstractDeclarator{ 2482 Case: 1, 2483 DirectAbstractDeclaratorOpt: $1.(*DirectAbstractDeclaratorOpt), 2484 Token: $2, 2485 ExpressionOpt: $3.(*ExpressionOpt), 2486 Token2: $4, 2487 } 2488 $$ = lhs 2489 nElements := -1 2490 if o := lhs.ExpressionOpt; o != nil { 2491 var err error 2492 if nElements, err = elements(o.Expression.eval(lx)); err != nil { 2493 lx.report.Err(o.Expression.Pos(), "%s", err) 2494 } 2495 } 2496 var dd *DirectDeclarator 2497 switch o := lhs.DirectAbstractDeclaratorOpt; { 2498 case o == nil: 2499 dd = &DirectDeclarator{ 2500 Case: 0, // IDENTIFIER 2501 } 2502 default: 2503 dd = o.DirectAbstractDeclarator.directDeclarator 2504 } 2505 lhs.directDeclarator = &DirectDeclarator{ 2506 Case: 2, // DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']' 2507 DirectDeclarator: dd, 2508 ExpressionOpt: lhs.ExpressionOpt, 2509 elements: nElements, 2510 } 2511 dd.parent = lhs.directDeclarator 2512 } 2513 | DirectAbstractDeclaratorOpt '[' TypeQualifierList ExpressionOpt ']' 2514 { 2515 lx := yylex.(*lexer) 2516 lhs := &DirectAbstractDeclarator{ 2517 Case: 2, 2518 DirectAbstractDeclaratorOpt: $1.(*DirectAbstractDeclaratorOpt), 2519 Token: $2, 2520 TypeQualifierList: $3.(*TypeQualifierList).reverse(), 2521 ExpressionOpt: $4.(*ExpressionOpt), 2522 Token2: $5, 2523 } 2524 $$ = lhs 2525 if o := lhs.ExpressionOpt; o != nil { 2526 o.Expression.eval(lx) 2527 } 2528 var dd *DirectDeclarator 2529 switch o := lhs.DirectAbstractDeclaratorOpt; { 2530 case o == nil: 2531 dd = &DirectDeclarator{ 2532 Case: 0, // IDENTIFIER 2533 } 2534 default: 2535 dd = o.DirectAbstractDeclarator.directDeclarator 2536 } 2537 lhs.directDeclarator = &DirectDeclarator{ 2538 Case: 2, // DirectDeclarator '[' TypeQualifierListOpt ExpressionOpt ']' 2539 DirectDeclarator: dd, 2540 TypeQualifierListOpt: &TypeQualifierListOpt{ lhs.TypeQualifierList }, 2541 ExpressionOpt: lhs.ExpressionOpt, 2542 } 2543 dd.parent = lhs.directDeclarator 2544 } 2545 | DirectAbstractDeclaratorOpt '[' "static" TypeQualifierListOpt Expression ']' 2546 { 2547 lx := yylex.(*lexer) 2548 lhs := &DirectAbstractDeclarator{ 2549 Case: 3, 2550 DirectAbstractDeclaratorOpt: $1.(*DirectAbstractDeclaratorOpt), 2551 Token: $2, 2552 Token2: $3, 2553 TypeQualifierListOpt: $4.(*TypeQualifierListOpt), 2554 Expression: $5.(*Expression), 2555 Token3: $6, 2556 } 2557 $$ = lhs 2558 lhs.Expression.eval(lx) 2559 var dd *DirectDeclarator 2560 switch o := lhs.DirectAbstractDeclaratorOpt; { 2561 case o == nil: 2562 dd = &DirectDeclarator{ 2563 Case: 0, // IDENTIFIER 2564 } 2565 default: 2566 dd = o.DirectAbstractDeclarator.directDeclarator 2567 } 2568 lhs.directDeclarator = &DirectDeclarator{ 2569 Case: 2, // DirectDeclarator '[' "static" TypeQualifierListOpt Expression ']' 2570 DirectDeclarator: dd, 2571 TypeQualifierListOpt: lhs.TypeQualifierListOpt, 2572 Expression: lhs.Expression, 2573 } 2574 dd.parent = lhs.directDeclarator 2575 } 2576 | DirectAbstractDeclaratorOpt '[' TypeQualifierList "static" Expression ']' 2577 { 2578 lx := yylex.(*lexer) 2579 lhs := &DirectAbstractDeclarator{ 2580 Case: 4, 2581 DirectAbstractDeclaratorOpt: $1.(*DirectAbstractDeclaratorOpt), 2582 Token: $2, 2583 TypeQualifierList: $3.(*TypeQualifierList).reverse(), 2584 Token2: $4, 2585 Expression: $5.(*Expression), 2586 Token3: $6, 2587 } 2588 $$ = lhs 2589 lhs.Expression.eval(lx) 2590 var dd *DirectDeclarator 2591 switch o := lhs.DirectAbstractDeclaratorOpt; { 2592 case o == nil: 2593 dd = &DirectDeclarator{ 2594 Case: 0, // IDENTIFIER 2595 } 2596 default: 2597 dd = o.DirectAbstractDeclarator.directDeclarator 2598 } 2599 lhs.directDeclarator = &DirectDeclarator{ 2600 Case: 4, // DirectDeclarator '[' TypeQualifierList "static" Expression ']' 2601 DirectDeclarator: dd, 2602 TypeQualifierList: lhs.TypeQualifierList, 2603 Expression: lhs.Expression, 2604 } 2605 dd.parent = lhs.directDeclarator 2606 } 2607 | DirectAbstractDeclaratorOpt '[' '*' ']' 2608 { 2609 lhs := &DirectAbstractDeclarator{ 2610 Case: 5, 2611 DirectAbstractDeclaratorOpt: $1.(*DirectAbstractDeclaratorOpt), 2612 Token: $2, 2613 Token2: $3, 2614 Token3: $4, 2615 } 2616 $$ = lhs 2617 var dd *DirectDeclarator 2618 switch o := lhs.DirectAbstractDeclaratorOpt; { 2619 case o == nil: 2620 dd = &DirectDeclarator{ 2621 Case: 0, // IDENTIFIER 2622 } 2623 default: 2624 dd = o.DirectAbstractDeclarator.directDeclarator 2625 } 2626 lhs.directDeclarator = &DirectDeclarator{ 2627 Case: 5, // DirectDeclarator '[' TypeQualifierListOpt '*' ']' 2628 DirectDeclarator: dd, 2629 } 2630 dd.parent = lhs.directDeclarator 2631 } 2632 | '(' 2633 { 2634 lx := yylex.(*lexer) 2635 lx.pushScope(ScopeParams) 2636 } 2637 ParameterTypeListOpt ')' 2638 { 2639 lx := yylex.(*lexer) 2640 lhs := &DirectAbstractDeclarator{ 2641 Case: 6, 2642 Token: $1, 2643 ParameterTypeListOpt: $3.(*ParameterTypeListOpt), 2644 Token2: $4, 2645 } 2646 $$ = lhs 2647 lhs.paramsScope, _ = lx.popScope(lhs.Token2) 2648 switch o := lhs.ParameterTypeListOpt; { 2649 case o != nil: 2650 lhs.directDeclarator = &DirectDeclarator{ 2651 Case: 6, // DirectDeclarator '(' ParameterTypeList ')' 2652 DirectDeclarator: &DirectDeclarator{ 2653 Case: 0, // IDENTIFIER 2654 }, 2655 ParameterTypeList: o.ParameterTypeList, 2656 } 2657 default: 2658 lhs.directDeclarator = &DirectDeclarator{ 2659 Case: 7, // DirectDeclarator '(' IdentifierListOpt ')' 2660 DirectDeclarator: &DirectDeclarator{ 2661 Case: 0, // IDENTIFIER 2662 }, 2663 } 2664 } 2665 lhs.directDeclarator.DirectDeclarator.parent = lhs.directDeclarator 2666 } 2667 | DirectAbstractDeclarator '(' 2668 { 2669 lx := yylex.(*lexer) 2670 lx.pushScope(ScopeParams) 2671 } 2672 ParameterTypeListOpt ')' 2673 { 2674 lx := yylex.(*lexer) 2675 lhs := &DirectAbstractDeclarator{ 2676 Case: 7, 2677 DirectAbstractDeclarator: $1.(*DirectAbstractDeclarator), 2678 Token: $2, 2679 ParameterTypeListOpt: $4.(*ParameterTypeListOpt), 2680 Token2: $5, 2681 } 2682 $$ = lhs 2683 lhs.paramsScope, _ = lx.popScope(lhs.Token2) 2684 switch o := lhs.ParameterTypeListOpt; { 2685 case o != nil: 2686 lhs.directDeclarator = &DirectDeclarator{ 2687 Case: 6, // DirectDeclarator '(' ParameterTypeList ')' 2688 DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator, 2689 ParameterTypeList: o.ParameterTypeList, 2690 } 2691 default: 2692 lhs.directDeclarator = &DirectDeclarator{ 2693 Case: 7, // DirectDeclarator '(' IdentifierListOpt ')' 2694 DirectDeclarator: lhs.DirectAbstractDeclarator.directDeclarator, 2695 } 2696 } 2697 lhs.directDeclarator.DirectDeclarator.parent = lhs.directDeclarator 2698 } 2699 2700 DirectAbstractDeclaratorOpt: 2701 /* empty */ 2702 { 2703 $$ = (*DirectAbstractDeclaratorOpt)(nil) 2704 } 2705 | DirectAbstractDeclarator 2706 { 2707 $$ = &DirectAbstractDeclaratorOpt{ 2708 DirectAbstractDeclarator: $1.(*DirectAbstractDeclarator), 2709 } 2710 } 2711 2712 Initializer: 2713 Expression 2714 { 2715 lx := yylex.(*lexer) 2716 lhs := &Initializer{ 2717 Expression: $1.(*Expression), 2718 } 2719 $$ = lhs 2720 lhs.Expression.eval(lx) 2721 } 2722 | '{' InitializerList CommaOpt '}' 2723 { 2724 $$ = &Initializer{ 2725 Case: 1, 2726 Token: $1, 2727 InitializerList: $2.(*InitializerList).reverse(), 2728 CommaOpt: $3.(*CommaOpt), 2729 Token2: $4, 2730 } 2731 } 2732 | IDENTIFIER ':' Initializer 2733 { 2734 lx := yylex.(*lexer) 2735 lhs := &Initializer{ 2736 Case: 2, 2737 Token: $1, 2738 Token2: $2, 2739 Initializer: $3.(*Initializer), 2740 } 2741 $$ = lhs 2742 if !lx.tweaks.enableLegacyDesignators { 2743 lx.report.Err(lhs.Pos(), "legacy designators not enabled") 2744 } 2745 } 2746 2747 InitializerList: 2748 DesignationOpt Initializer 2749 { 2750 $$ = &InitializerList{ 2751 DesignationOpt: $1.(*DesignationOpt), 2752 Initializer: $2.(*Initializer), 2753 } 2754 } 2755 | InitializerList ',' DesignationOpt Initializer 2756 { 2757 $$ = &InitializerList{ 2758 Case: 1, 2759 InitializerList: $1.(*InitializerList), 2760 Token: $2, 2761 DesignationOpt: $3.(*DesignationOpt), 2762 Initializer: $4.(*Initializer), 2763 } 2764 } 2765 | /* empty */ 2766 { 2767 $$ = (*InitializerList)(nil) 2768 } 2769 2770 Designation: 2771 DesignatorList '=' 2772 { 2773 $$ = &Designation{ 2774 DesignatorList: $1.(*DesignatorList).reverse(), 2775 Token: $2, 2776 } 2777 } 2778 2779 DesignationOpt: 2780 /* empty */ 2781 { 2782 $$ = (*DesignationOpt)(nil) 2783 } 2784 | Designation 2785 { 2786 $$ = &DesignationOpt{ 2787 Designation: $1.(*Designation), 2788 } 2789 } 2790 2791 DesignatorList: 2792 Designator 2793 { 2794 $$ = &DesignatorList{ 2795 Designator: $1.(*Designator), 2796 } 2797 } 2798 | DesignatorList Designator 2799 { 2800 $$ = &DesignatorList{ 2801 Case: 1, 2802 DesignatorList: $1.(*DesignatorList), 2803 Designator: $2.(*Designator), 2804 } 2805 } 2806 2807 Designator: 2808 '[' ConstantExpression ']' 2809 { 2810 $$ = &Designator{ 2811 Token: $1, 2812 ConstantExpression: $2.(*ConstantExpression), 2813 Token2: $3, 2814 } 2815 } 2816 | '.' IDENTIFIER 2817 { 2818 $$ = &Designator{ 2819 Case: 1, 2820 Token: $1, 2821 Token2: $2, 2822 } 2823 } 2824 2825 Statement: 2826 LabeledStatement 2827 { 2828 $$ = &Statement{ 2829 LabeledStatement: $1.(*LabeledStatement), 2830 } 2831 } 2832 | CompoundStatement 2833 { 2834 $$ = &Statement{ 2835 Case: 1, 2836 CompoundStatement: $1.(*CompoundStatement), 2837 } 2838 } 2839 | ExpressionStatement 2840 { 2841 $$ = &Statement{ 2842 Case: 2, 2843 ExpressionStatement: $1.(*ExpressionStatement), 2844 } 2845 } 2846 | SelectionStatement 2847 { 2848 $$ = &Statement{ 2849 Case: 3, 2850 SelectionStatement: $1.(*SelectionStatement), 2851 } 2852 } 2853 | IterationStatement 2854 { 2855 $$ = &Statement{ 2856 Case: 4, 2857 IterationStatement: $1.(*IterationStatement), 2858 } 2859 } 2860 | JumpStatement 2861 { 2862 $$ = &Statement{ 2863 Case: 5, 2864 JumpStatement: $1.(*JumpStatement), 2865 } 2866 } 2867 | AssemblerStatement 2868 { 2869 $$ = &Statement{ 2870 Case: 6, 2871 AssemblerStatement: $1.(*AssemblerStatement), 2872 } 2873 } 2874 2875 LabeledStatement: 2876 IDENTIFIER ':' Statement 2877 { 2878 $$ = &LabeledStatement{ 2879 Token: $1, 2880 Token2: $2, 2881 Statement: $3.(*Statement), 2882 } 2883 } 2884 | "case" ConstantExpression ':' Statement 2885 { 2886 $$ = &LabeledStatement{ 2887 Case: 1, 2888 Token: $1, 2889 ConstantExpression: $2.(*ConstantExpression), 2890 Token2: $3, 2891 Statement: $4.(*Statement), 2892 } 2893 } 2894 | "default" ':' Statement 2895 { 2896 $$ = &LabeledStatement{ 2897 Case: 2, 2898 Token: $1, 2899 Token2: $2, 2900 Statement: $3.(*Statement), 2901 } 2902 } 2903 2904 CompoundStatement: 2905 '{' 2906 { 2907 lx := yylex.(*lexer) 2908 m := lx.scope.mergeScope 2909 lx.pushScope(ScopeBlock) 2910 if m != nil { 2911 lx.scope.merge(m) 2912 } 2913 lx.scope.mergeScope = nil 2914 } 2915 BlockItemListOpt '}' 2916 { 2917 lx := yylex.(*lexer) 2918 lhs := &CompoundStatement{ 2919 Token: $1, 2920 BlockItemListOpt: $3.(*BlockItemListOpt), 2921 Token2: $4, 2922 } 2923 $$ = lhs 2924 lhs.scope = lx.scope 2925 lx.popScope(lhs.Token2) 2926 } 2927 2928 BlockItemList: 2929 BlockItem 2930 { 2931 $$ = &BlockItemList{ 2932 BlockItem: $1.(*BlockItem), 2933 } 2934 } 2935 | BlockItemList BlockItem 2936 { 2937 $$ = &BlockItemList{ 2938 Case: 1, 2939 BlockItemList: $1.(*BlockItemList), 2940 BlockItem: $2.(*BlockItem), 2941 } 2942 } 2943 2944 BlockItemListOpt: 2945 /* empty */ 2946 { 2947 $$ = (*BlockItemListOpt)(nil) 2948 } 2949 | BlockItemList 2950 { 2951 $$ = &BlockItemListOpt{ 2952 BlockItemList: $1.(*BlockItemList).reverse(), 2953 } 2954 } 2955 2956 BlockItem: 2957 Declaration 2958 { 2959 $$ = &BlockItem{ 2960 Declaration: $1.(*Declaration), 2961 } 2962 } 2963 | Statement 2964 { 2965 $$ = &BlockItem{ 2966 Case: 1, 2967 Statement: $1.(*Statement), 2968 } 2969 } 2970 2971 ExpressionStatement: 2972 ExpressionListOpt ';' 2973 { 2974 $$ = &ExpressionStatement{ 2975 ExpressionListOpt: $1.(*ExpressionListOpt), 2976 Token: $2, 2977 } 2978 } 2979 2980 SelectionStatement: 2981 "if" '(' ExpressionList ')' Statement %prec NOELSE 2982 { 2983 lx := yylex.(*lexer) 2984 lhs := &SelectionStatement{ 2985 Token: $1, 2986 Token2: $2, 2987 ExpressionList: $3.(*ExpressionList).reverse(), 2988 Token3: $4, 2989 Statement: $5.(*Statement), 2990 } 2991 $$ = lhs 2992 lhs.ExpressionList.eval(lx) 2993 } 2994 | "if" '(' ExpressionList ')' Statement "else" Statement 2995 { 2996 lx := yylex.(*lexer) 2997 lhs := &SelectionStatement{ 2998 Case: 1, 2999 Token: $1, 3000 Token2: $2, 3001 ExpressionList: $3.(*ExpressionList).reverse(), 3002 Token3: $4, 3003 Statement: $5.(*Statement), 3004 Token4: $6, 3005 Statement2: $7.(*Statement), 3006 } 3007 $$ = lhs 3008 lhs.ExpressionList.eval(lx) 3009 } 3010 | "switch" '(' ExpressionList ')' Statement 3011 { 3012 lx := yylex.(*lexer) 3013 lhs := &SelectionStatement{ 3014 Case: 2, 3015 Token: $1, 3016 Token2: $2, 3017 ExpressionList: $3.(*ExpressionList).reverse(), 3018 Token3: $4, 3019 Statement: $5.(*Statement), 3020 } 3021 $$ = lhs 3022 lhs.ExpressionList.eval(lx) 3023 } 3024 3025 IterationStatement: 3026 "while" '(' ExpressionList ')' Statement 3027 { 3028 lx := yylex.(*lexer) 3029 lhs := &IterationStatement{ 3030 Token: $1, 3031 Token2: $2, 3032 ExpressionList: $3.(*ExpressionList).reverse(), 3033 Token3: $4, 3034 Statement: $5.(*Statement), 3035 } 3036 $$ = lhs 3037 lhs.ExpressionList.eval(lx) 3038 } 3039 | "do" Statement "while" '(' ExpressionList ')' ';' 3040 { 3041 lx := yylex.(*lexer) 3042 lhs := &IterationStatement{ 3043 Case: 1, 3044 Token: $1, 3045 Statement: $2.(*Statement), 3046 Token2: $3, 3047 Token3: $4, 3048 ExpressionList: $5.(*ExpressionList).reverse(), 3049 Token4: $6, 3050 Token5: $7, 3051 } 3052 $$ = lhs 3053 lhs.ExpressionList.eval(lx) 3054 } 3055 | "for" '(' ExpressionListOpt ';' ExpressionListOpt ';' ExpressionListOpt ')' Statement 3056 { 3057 $$ = &IterationStatement{ 3058 Case: 2, 3059 Token: $1, 3060 Token2: $2, 3061 ExpressionListOpt: $3.(*ExpressionListOpt), 3062 Token3: $4, 3063 ExpressionListOpt2: $5.(*ExpressionListOpt), 3064 Token4: $6, 3065 ExpressionListOpt3: $7.(*ExpressionListOpt), 3066 Token5: $8, 3067 Statement: $9.(*Statement), 3068 } 3069 } 3070 | "for" '(' Declaration ExpressionListOpt ';' ExpressionListOpt ')' Statement 3071 { 3072 $$ = &IterationStatement{ 3073 Case: 3, 3074 Token: $1, 3075 Token2: $2, 3076 Declaration: $3.(*Declaration), 3077 ExpressionListOpt: $4.(*ExpressionListOpt), 3078 Token3: $5, 3079 ExpressionListOpt2: $6.(*ExpressionListOpt), 3080 Token4: $7, 3081 Statement: $8.(*Statement), 3082 } 3083 } 3084 3085 JumpStatement: 3086 "goto" IDENTIFIER ';' 3087 { 3088 $$ = &JumpStatement{ 3089 Token: $1, 3090 Token2: $2, 3091 Token3: $3, 3092 } 3093 } 3094 | "continue" ';' 3095 { 3096 $$ = &JumpStatement{ 3097 Case: 1, 3098 Token: $1, 3099 Token2: $2, 3100 } 3101 } 3102 | "break" ';' 3103 { 3104 $$ = &JumpStatement{ 3105 Case: 2, 3106 Token: $1, 3107 Token2: $2, 3108 } 3109 } 3110 | "return" ExpressionListOpt ';' 3111 { 3112 $$ = &JumpStatement{ 3113 Case: 3, 3114 Token: $1, 3115 ExpressionListOpt: $2.(*ExpressionListOpt), 3116 Token2: $3, 3117 } 3118 } 3119 | "goto" Expression ';' 3120 { 3121 lx := yylex.(*lexer) 3122 lhs := &JumpStatement{ 3123 Case: 4, 3124 Token: $1, 3125 Expression: $2.(*Expression), 3126 Token2: $3, 3127 } 3128 $$ = lhs 3129 _, t := lhs.Expression.eval(lx) 3130 if t == nil { 3131 break 3132 } 3133 3134 for t != nil && t.Kind() == Ptr { 3135 t = t.Element() 3136 } 3137 3138 if t == nil || t.Kind() != Void { 3139 lx.report.Err(lhs.Pos(), "invalid computed goto argument type, have '%s'", t) 3140 } 3141 3142 if !lx.tweaks.enableComputedGotos { 3143 lx.report.Err(lhs.Pos(), "computed gotos not enabled") 3144 } 3145 } 3146 3147 TranslationUnit: 3148 ExternalDeclaration 3149 { 3150 $$ = &TranslationUnit{ 3151 ExternalDeclaration: $1.(*ExternalDeclaration), 3152 } 3153 } 3154 | TranslationUnit ExternalDeclaration 3155 { 3156 $$ = &TranslationUnit{ 3157 Case: 1, 3158 TranslationUnit: $1.(*TranslationUnit), 3159 ExternalDeclaration: $2.(*ExternalDeclaration), 3160 } 3161 } 3162 3163 ExternalDeclaration: 3164 FunctionDefinition 3165 { 3166 $$ = &ExternalDeclaration{ 3167 FunctionDefinition: $1.(*FunctionDefinition), 3168 } 3169 } 3170 | Declaration 3171 { 3172 $$ = &ExternalDeclaration{ 3173 Case: 1, 3174 Declaration: $1.(*Declaration), 3175 } 3176 } 3177 | BasicAssemblerStatement ';' 3178 { 3179 $$ = &ExternalDeclaration{ 3180 Case: 2, 3181 BasicAssemblerStatement: $1.(*BasicAssemblerStatement), 3182 Token: $2, 3183 } 3184 } 3185 | ';' 3186 { 3187 lx := yylex.(*lexer) 3188 lhs := &ExternalDeclaration{ 3189 Case: 3, 3190 Token: $1, 3191 } 3192 $$ = lhs 3193 if !lx.tweaks.enableEmptyDeclarations { 3194 lx.report.Err(lhs.Pos(), "C++11 empty declarations are illegal in C99.") 3195 } 3196 } 3197 3198 FunctionDefinition: 3199 DeclarationSpecifiers Declarator DeclarationListOpt 3200 { 3201 lx := yylex.(*lexer) 3202 if ds := $1.(*DeclarationSpecifiers); ds.typeSpecifier == 0 { 3203 ds.typeSpecifier = tsEncode(tsInt) 3204 $2.(*Declarator).Type = lx.model.IntType 3205 if !lx.tweaks.enableOmitFuncRetType { 3206 lx.report.Err($2.Pos(), "missing function return type") 3207 } 3208 } 3209 var fd *FunctionDefinition 3210 fd.post(lx, $2.(*Declarator), $3.(*DeclarationListOpt)) 3211 } 3212 FunctionBody 3213 { 3214 $$ = &FunctionDefinition{ 3215 DeclarationSpecifiers: $1.(*DeclarationSpecifiers), 3216 Declarator: $2.(*Declarator), 3217 DeclarationListOpt: $3.(*DeclarationListOpt), 3218 FunctionBody: $5.(*FunctionBody), 3219 } 3220 } 3221 | { 3222 lx := yylex.(*lexer) 3223 lx.scope.specifier = &DeclarationSpecifiers{typeSpecifier: tsEncode(tsInt)} 3224 } 3225 Declarator DeclarationListOpt 3226 { 3227 lx := yylex.(*lexer) 3228 if !lx.tweaks.enableOmitFuncRetType { 3229 lx.report.Err($2.Pos(), "missing function return type") 3230 } 3231 var fd *FunctionDefinition 3232 fd.post(lx, $2.(*Declarator), $3.(*DeclarationListOpt)) 3233 } 3234 FunctionBody 3235 { 3236 $$ = &FunctionDefinition{ 3237 Case: 1, 3238 Declarator: $2.(*Declarator), 3239 DeclarationListOpt: $3.(*DeclarationListOpt), 3240 FunctionBody: $5.(*FunctionBody), 3241 } 3242 } 3243 3244 FunctionBody: 3245 { 3246 lx := yylex.(*lexer) 3247 // Handle __func__, [0], 6.4.2.2. 3248 id, _ := lx.fnDeclarator.Identifier() 3249 lx.injectFunc = []xc.Token{ 3250 {lex.Char{Rune: STATIC}, idStatic}, 3251 {lex.Char{Rune: CONST}, idConst}, 3252 {lex.Char{Rune: CHAR}, idChar}, 3253 {lex.Char{Rune: IDENTIFIER}, idMagicFunc}, 3254 {lex.Char{Rune: '['}, 0}, 3255 {lex.Char{Rune: ']'}, 0}, 3256 {lex.Char{Rune: '='}, 0}, 3257 {lex.Char{Rune: STRINGLITERAL}, xc.Dict.SID(fmt.Sprintf("%q", xc.Dict.S(id)))}, 3258 {lex.Char{Rune: ';'}, 0}, 3259 } 3260 } 3261 CompoundStatement 3262 { 3263 lhs := &FunctionBody{ 3264 CompoundStatement: $2.(*CompoundStatement), 3265 } 3266 $$ = lhs 3267 lhs.scope = lhs.CompoundStatement.scope 3268 } 3269 | { 3270 lx := yylex.(*lexer) 3271 m := lx.scope.mergeScope 3272 lx.pushScope(ScopeBlock) 3273 if m != nil { 3274 lx.scope.merge(m) 3275 } 3276 lx.scope.mergeScope = nil 3277 } 3278 AssemblerStatement ';' 3279 { 3280 lx := yylex.(*lexer) 3281 lhs := &FunctionBody{ 3282 Case: 1, 3283 AssemblerStatement: $2.(*AssemblerStatement), 3284 Token: $3, 3285 } 3286 $$ = lhs 3287 lhs.scope = lx.scope 3288 lx.popScope(lx.tokPrev) 3289 } 3290 3291 DeclarationList: 3292 Declaration 3293 { 3294 $$ = &DeclarationList{ 3295 Declaration: $1.(*Declaration), 3296 } 3297 } 3298 | DeclarationList Declaration 3299 { 3300 $$ = &DeclarationList{ 3301 Case: 1, 3302 DeclarationList: $1.(*DeclarationList), 3303 Declaration: $2.(*Declaration), 3304 } 3305 } 3306 3307 DeclarationListOpt: 3308 /* empty */ 3309 { 3310 $$ = (*DeclarationListOpt)(nil) 3311 } 3312 | { 3313 lx := yylex.(*lexer) 3314 lx.pushScope(ScopeParams) 3315 } 3316 DeclarationList 3317 { 3318 lx := yylex.(*lexer) 3319 lhs := &DeclarationListOpt{ 3320 DeclarationList: $2.(*DeclarationList).reverse(), 3321 } 3322 $$ = lhs 3323 lhs.paramsScope, _ = lx.popScopePos(lhs.Pos()) 3324 } 3325 3326 AssemblerInstructions: 3327 STRINGLITERAL 3328 { 3329 $$ = &AssemblerInstructions{ 3330 Token: $1, 3331 } 3332 } 3333 | AssemblerInstructions STRINGLITERAL 3334 { 3335 $$ = &AssemblerInstructions{ 3336 Case: 1, 3337 AssemblerInstructions: $1.(*AssemblerInstructions), 3338 Token: $2, 3339 } 3340 } 3341 3342 BasicAssemblerStatement: 3343 "asm" VolatileOpt '(' AssemblerInstructions ')' 3344 { 3345 $$ = &BasicAssemblerStatement{ 3346 Token: $1, 3347 VolatileOpt: $2.(*VolatileOpt), 3348 Token2: $3, 3349 AssemblerInstructions: $4.(*AssemblerInstructions).reverse(), 3350 Token3: $5, 3351 } 3352 } 3353 3354 VolatileOpt: 3355 /* empty */ 3356 { 3357 $$ = (*VolatileOpt)(nil) 3358 } 3359 | "volatile" 3360 { 3361 $$ = &VolatileOpt{ 3362 Token: $1, 3363 } 3364 } 3365 3366 AssemblerOperand: 3367 AssemblerSymbolicNameOpt STRINGLITERAL '(' Expression ')' 3368 { 3369 $$ = &AssemblerOperand{ 3370 AssemblerSymbolicNameOpt: $1.(*AssemblerSymbolicNameOpt), 3371 Token: $2, 3372 Token2: $3, 3373 Expression: $4.(*Expression), 3374 Token3: $5, 3375 } 3376 } 3377 3378 AssemblerOperands: 3379 AssemblerOperand 3380 { 3381 $$ = &AssemblerOperands{ 3382 AssemblerOperand: $1.(*AssemblerOperand), 3383 } 3384 } 3385 | AssemblerOperands ',' AssemblerOperand 3386 { 3387 $$ = &AssemblerOperands{ 3388 Case: 1, 3389 AssemblerOperands: $1.(*AssemblerOperands), 3390 Token: $2, 3391 AssemblerOperand: $3.(*AssemblerOperand), 3392 } 3393 } 3394 3395 AssemblerSymbolicNameOpt: 3396 /* empty */ 3397 { 3398 $$ = (*AssemblerSymbolicNameOpt)(nil) 3399 } 3400 | '[' IDENTIFIER ']' 3401 { 3402 $$ = &AssemblerSymbolicNameOpt{ 3403 Token: $1, 3404 Token2: $2, 3405 Token3: $3, 3406 } 3407 } 3408 3409 Clobbers: 3410 STRINGLITERAL 3411 { 3412 $$ = &Clobbers{ 3413 Token: $1, 3414 } 3415 } 3416 | Clobbers ',' STRINGLITERAL 3417 { 3418 $$ = &Clobbers{ 3419 Case: 1, 3420 Clobbers: $1.(*Clobbers), 3421 Token: $2, 3422 Token2: $3, 3423 } 3424 } 3425 3426 AssemblerStatement: 3427 BasicAssemblerStatement 3428 { 3429 $$ = &AssemblerStatement{ 3430 BasicAssemblerStatement: $1.(*BasicAssemblerStatement), 3431 } 3432 } 3433 | "asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ')' 3434 { 3435 $$ = &AssemblerStatement{ 3436 Case: 1, 3437 Token: $1, 3438 VolatileOpt: $2.(*VolatileOpt), 3439 Token2: $3, 3440 AssemblerInstructions: $4.(*AssemblerInstructions).reverse(), 3441 Token3: $5, 3442 AssemblerOperands: $6.(*AssemblerOperands).reverse(), 3443 Token4: $7, 3444 } 3445 } 3446 | "asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ':' AssemblerOperands ')' 3447 { 3448 $$ = &AssemblerStatement{ 3449 Case: 2, 3450 Token: $1, 3451 VolatileOpt: $2.(*VolatileOpt), 3452 Token2: $3, 3453 AssemblerInstructions: $4.(*AssemblerInstructions).reverse(), 3454 Token3: $5, 3455 AssemblerOperands: $6.(*AssemblerOperands).reverse(), 3456 Token4: $7, 3457 AssemblerOperands2: $8.(*AssemblerOperands).reverse(), 3458 Token5: $9, 3459 } 3460 } 3461 | "asm" VolatileOpt '(' AssemblerInstructions ':' AssemblerOperands ':' AssemblerOperands ':' Clobbers ')' 3462 { 3463 $$ = &AssemblerStatement{ 3464 Case: 3, 3465 Token: $1, 3466 VolatileOpt: $2.(*VolatileOpt), 3467 Token2: $3, 3468 AssemblerInstructions: $4.(*AssemblerInstructions).reverse(), 3469 Token3: $5, 3470 AssemblerOperands: $6.(*AssemblerOperands).reverse(), 3471 Token4: $7, 3472 AssemblerOperands2: $8.(*AssemblerOperands).reverse(), 3473 Token5: $9, 3474 Clobbers: $10.(*Clobbers).reverse(), 3475 Token6: $11, 3476 } 3477 } 3478 | "asm" VolatileOpt "goto" '(' AssemblerInstructions ':' ':' AssemblerOperands ':' Clobbers ':' IdentifierList ')' 3479 { 3480 $$ = &AssemblerStatement{ 3481 Case: 4, 3482 Token: $1, 3483 VolatileOpt: $2.(*VolatileOpt), 3484 Token2: $3, 3485 Token3: $4, 3486 AssemblerInstructions: $5.(*AssemblerInstructions).reverse(), 3487 Token4: $6, 3488 Token5: $7, 3489 AssemblerOperands: $8.(*AssemblerOperands).reverse(), 3490 Token6: $9, 3491 Clobbers: $10.(*Clobbers).reverse(), 3492 Token7: $11, 3493 IdentifierList: $12.(*IdentifierList).reverse(), 3494 Token8: $13, 3495 } 3496 } 3497 | "asm" VolatileOpt '(' AssemblerInstructions ':' ')' 3498 { 3499 $$ = &AssemblerStatement{ 3500 Case: 5, 3501 Token: $1, 3502 VolatileOpt: $2.(*VolatileOpt), 3503 Token2: $3, 3504 AssemblerInstructions: $4.(*AssemblerInstructions).reverse(), 3505 Token3: $5, 3506 Token4: $6, 3507 } 3508 } 3509 | "asm" VolatileOpt '(' AssemblerInstructions ':' ':' AssemblerOperands ')' 3510 { 3511 $$ = &AssemblerStatement{ 3512 Case: 6, 3513 Token: $1, 3514 VolatileOpt: $2.(*VolatileOpt), 3515 Token2: $3, 3516 AssemblerInstructions: $4.(*AssemblerInstructions).reverse(), 3517 Token3: $5, 3518 Token4: $6, 3519 AssemblerOperands: $7.(*AssemblerOperands).reverse(), 3520 Token5: $8, 3521 } 3522 } 3523 3524 StaticAssertDeclaration: 3525 "_Static_assert" '(' ConstantExpression ',' STRINGLITERAL ')' ';' 3526 { 3527 lx := yylex.(*lexer) 3528 lhs := &StaticAssertDeclaration{ 3529 Token: $1, 3530 Token2: $2, 3531 ConstantExpression: $3.(*ConstantExpression), 3532 Token3: $4, 3533 Token4: $5, 3534 Token5: $6, 3535 Token6: $7, 3536 } 3537 $$ = lhs 3538 ce := lhs.ConstantExpression 3539 if ce.Type == nil || ce.Type.Kind() == Undefined || ce.Value == nil || !IsIntType(ce.Type) { 3540 lx.report.Err(ce.Pos(), "invalid static assert expression (have '%v')", ce.Type) 3541 break 3542 } 3543 3544 if !isNonZero(ce.Value) { 3545 lx.report.ErrTok(lhs.Token, "%s", lhs.Token4.S()) 3546 } 3547 } 3548 3549 PreprocessingFile: 3550 GroupList 3551 { 3552 lx := yylex.(*lexer) 3553 lhs := &PreprocessingFile{ 3554 GroupList: $1.(*GroupList).reverse(), 3555 } 3556 $$ = lhs 3557 lhs.path = lx.file.Name() 3558 } 3559 3560 GroupList: 3561 GroupPart 3562 { 3563 $$ = &GroupList{ 3564 GroupPart: $1, 3565 } 3566 } 3567 | GroupList GroupPart 3568 { 3569 $$ = &GroupList{ 3570 Case: 1, 3571 GroupList: $1.(*GroupList), 3572 GroupPart: $2, 3573 } 3574 } 3575 3576 GroupListOpt: 3577 /* empty */ 3578 { 3579 $$ = (*GroupListOpt)(nil) 3580 } 3581 | GroupList 3582 { 3583 $$ = &GroupListOpt{ 3584 GroupList: $1.(*GroupList).reverse(), 3585 } 3586 } 3587 3588 GroupPart: 3589 ControlLine 3590 { 3591 $$ = $1.(Node) 3592 } 3593 | IfSection 3594 { 3595 $$ = $1.(Node) 3596 } 3597 | PPNONDIRECTIVE PPTokenList '\n' 3598 { 3599 $$ = $1 3600 } 3601 | TextLine 3602 { 3603 $$ = $1 3604 } 3605 3606 IfSection: 3607 IfGroup ElifGroupListOpt ElseGroupOpt EndifLine 3608 { 3609 $$ = &IfSection{ 3610 IfGroup: $1.(*IfGroup), 3611 ElifGroupListOpt: $2.(*ElifGroupListOpt), 3612 ElseGroupOpt: $3.(*ElseGroupOpt), 3613 EndifLine: $4.(*EndifLine), 3614 } 3615 } 3616 3617 IfGroup: 3618 PPIF PPTokenList '\n' GroupListOpt 3619 { 3620 $$ = &IfGroup{ 3621 Token: $1, 3622 PPTokenList: $2, 3623 Token2: $3, 3624 GroupListOpt: $4.(*GroupListOpt), 3625 } 3626 } 3627 | PPIFDEF IDENTIFIER '\n' GroupListOpt 3628 { 3629 $$ = &IfGroup{ 3630 Case: 1, 3631 Token: $1, 3632 Token2: $2, 3633 Token3: $3, 3634 GroupListOpt: $4.(*GroupListOpt), 3635 } 3636 } 3637 | PPIFNDEF IDENTIFIER '\n' GroupListOpt 3638 { 3639 $$ = &IfGroup{ 3640 Case: 2, 3641 Token: $1, 3642 Token2: $2, 3643 Token3: $3, 3644 GroupListOpt: $4.(*GroupListOpt), 3645 } 3646 } 3647 3648 ElifGroupList: 3649 ElifGroup 3650 { 3651 $$ = &ElifGroupList{ 3652 ElifGroup: $1.(*ElifGroup), 3653 } 3654 } 3655 | ElifGroupList ElifGroup 3656 { 3657 $$ = &ElifGroupList{ 3658 Case: 1, 3659 ElifGroupList: $1.(*ElifGroupList), 3660 ElifGroup: $2.(*ElifGroup), 3661 } 3662 } 3663 3664 ElifGroupListOpt: 3665 /* empty */ 3666 { 3667 $$ = (*ElifGroupListOpt)(nil) 3668 } 3669 | ElifGroupList 3670 { 3671 $$ = &ElifGroupListOpt{ 3672 ElifGroupList: $1.(*ElifGroupList).reverse(), 3673 } 3674 } 3675 3676 ElifGroup: 3677 PPELIF PPTokenList '\n' GroupListOpt 3678 { 3679 $$ = &ElifGroup{ 3680 Token: $1, 3681 PPTokenList: $2, 3682 Token2: $3, 3683 GroupListOpt: $4.(*GroupListOpt), 3684 } 3685 } 3686 3687 ElseGroup: 3688 PPELSE '\n' GroupListOpt 3689 { 3690 $$ = &ElseGroup{ 3691 Token: $1, 3692 Token2: $2, 3693 GroupListOpt: $3.(*GroupListOpt), 3694 } 3695 } 3696 3697 ElseGroupOpt: 3698 /* empty */ 3699 { 3700 $$ = (*ElseGroupOpt)(nil) 3701 } 3702 | ElseGroup 3703 { 3704 $$ = &ElseGroupOpt{ 3705 ElseGroup: $1.(*ElseGroup), 3706 } 3707 } 3708 3709 EndifLine: 3710 PPENDIF 3711 { 3712 $$ = &EndifLine{ 3713 Token: $1, 3714 } 3715 } 3716 3717 ControlLine: 3718 PPDEFINE IDENTIFIER ReplacementList 3719 { 3720 $$ = &ControlLine{ 3721 Token: $1, 3722 Token2: $2, 3723 ReplacementList: $3, 3724 } 3725 } 3726 | PPDEFINE IDENTIFIER_LPAREN "..." ')' ReplacementList 3727 { 3728 $$ = &ControlLine{ 3729 Case: 1, 3730 Token: $1, 3731 Token2: $2, 3732 Token3: $3, 3733 Token4: $4, 3734 ReplacementList: $5, 3735 } 3736 } 3737 | PPDEFINE IDENTIFIER_LPAREN IdentifierList ',' "..." ')' ReplacementList 3738 { 3739 $$ = &ControlLine{ 3740 Case: 2, 3741 Token: $1, 3742 Token2: $2, 3743 IdentifierList: $3.(*IdentifierList).reverse(), 3744 Token3: $4, 3745 Token4: $5, 3746 Token5: $6, 3747 ReplacementList: $7, 3748 } 3749 } 3750 | PPDEFINE IDENTIFIER_LPAREN IdentifierListOpt ')' ReplacementList 3751 { 3752 $$ = &ControlLine{ 3753 Case: 3, 3754 Token: $1, 3755 Token2: $2, 3756 IdentifierListOpt: $3.(*IdentifierListOpt), 3757 Token3: $4, 3758 ReplacementList: $5, 3759 } 3760 } 3761 | PPERROR PPTokenListOpt 3762 { 3763 $$ = &ControlLine{ 3764 Case: 4, 3765 Token: $1, 3766 PPTokenListOpt: $2, 3767 } 3768 } 3769 | PPHASH_NL 3770 { 3771 $$ = &ControlLine{ 3772 Case: 5, 3773 Token: $1, 3774 } 3775 } 3776 | PPINCLUDE PPTokenList '\n' 3777 { 3778 $$ = &ControlLine{ 3779 Case: 6, 3780 Token: $1, 3781 PPTokenList: $2, 3782 Token2: $3, 3783 } 3784 } 3785 | PPLINE PPTokenList '\n' 3786 { 3787 $$ = &ControlLine{ 3788 Case: 7, 3789 Token: $1, 3790 PPTokenList: $2, 3791 Token2: $3, 3792 } 3793 } 3794 | PPPRAGMA PPTokenListOpt 3795 { 3796 $$ = &ControlLine{ 3797 Case: 8, 3798 Token: $1, 3799 PPTokenListOpt: $2, 3800 } 3801 } 3802 | PPUNDEF IDENTIFIER '\n' 3803 { 3804 $$ = &ControlLine{ 3805 Case: 9, 3806 Token: $1, 3807 Token2: $2, 3808 Token3: $3, 3809 } 3810 } 3811 | PPDEFINE IDENTIFIER_LPAREN IdentifierList "..." ')' ReplacementList 3812 { 3813 lx := yylex.(*lexer) 3814 lhs := &ControlLine{ 3815 Case: 10, 3816 Token: $1, 3817 Token2: $2, 3818 IdentifierList: $3.(*IdentifierList).reverse(), 3819 Token3: $4, 3820 Token4: $5, 3821 ReplacementList: $6, 3822 } 3823 $$ = lhs 3824 if !lx.tweaks.enableDefineOmitCommaBeforeDDD { 3825 lx.report.ErrTok(lhs.Token4, "missing comma before \"...\"") 3826 } 3827 } 3828 | PPDEFINE '\n' 3829 { 3830 lx := yylex.(*lexer) 3831 lhs := &ControlLine{ 3832 Case: 11, 3833 Token: $1, 3834 Token2: $2, 3835 } 3836 $$ = lhs 3837 if !lx.tweaks.enableEmptyDefine { 3838 lx.report.ErrTok(lhs.Token2, "expected identifier") 3839 } 3840 } 3841 | PPUNDEF IDENTIFIER PPTokenList '\n' 3842 { 3843 lx := yylex.(*lexer) 3844 lhs := &ControlLine{ 3845 Case: 12, 3846 Token: $1, 3847 Token2: $2, 3848 PPTokenList: $3, 3849 Token3: $4, 3850 } 3851 $$ = lhs 3852 toks := decodeTokens(lhs.PPTokenList, nil, false) 3853 if len(toks) == 0 { 3854 lhs.Case = 9 // PPUNDEF IDENTIFIER '\n' 3855 break 3856 } 3857 3858 lx.report.ErrTok(toks[0], "extra tokens after #undef argument") 3859 } 3860 | PPINCLUDE_NEXT PPTokenList '\n' 3861 { 3862 $$ = &ControlLine{ 3863 Case: 13, 3864 Token: $1, 3865 PPTokenList: $2, 3866 Token2: $3, 3867 } 3868 } 3869 3870 TextLine: 3871 PPTokenListOpt 3872 { 3873 } 3874 3875 ReplacementList: 3876 PPTokenListOpt 3877 { 3878 } 3879 3880 PPTokenList: 3881 PPTokens 3882 { 3883 lx := yylex.(*lexer) 3884 $$ = PPTokenList(dict.ID(lx.encBuf)) 3885 lx.encBuf = lx.encBuf[:0] 3886 lx.encPos = 0 3887 } 3888 3889 PPTokenListOpt: 3890 '\n' 3891 { 3892 $$ = 0 3893 } 3894 | PPTokenList '\n' 3895 { 3896 } 3897 3898 PPTokens: 3899 PPOTHER 3900 { 3901 } 3902 | PPTokens PPOTHER 3903 { 3904 }