
1: /* A YACC grammar to parse a superset of the AT&T linker scripting language. 2: Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3: 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 4: Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com). 5: 6: This file is part of the GNU Binutils. 7: 8: This program is free software; you can redistribute it and/or modify 9: it under the terms of the GNU General Public License as published by 10: the Free Software Foundation; either version 3 of the License, or 11: (at your option) any later version. 12: 13: This program is distributed in the hope that it will be useful, 14: but WITHOUT ANY WARRANTY; without even the implied warranty of 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16: GNU General Public License for more details. 17: 18: You should have received a copy of the GNU General Public License 19: along with this program; if not, write to the Free Software 20: Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21: MA 02110-1301, USA. */ 22: 23: %{ 24: /* 25: 26: */ 27: 28: #define DONTDECLARE_MALLOC 29: 30: #include "sysdep.h" 31: #include "bfd.h" 32: #include "bfdlink.h" 33: #include "ld.h" 34: #include "ldexp.h" 35: #include "ldver.h" 36: #include "ldlang.h" 37: #include "ldfile.h" 38: #include "ldemul.h" 39: #include "ldmisc.h" 40: #include "ldmain.h" 41: #include "mri.h" 42: #include "ldctor.h" 43: #include "ldlex.h" 44: 45: #ifndef YYDEBUG 46: #define YYDEBUG 1 47: #endif 48: 49: static enum section_type sectype; 50: static lang_memory_region_type *region; 51: 52: FILE *saved_script_handle = NULL; 53: bfd_boolean force_make_executable = FALSE; 54: 55: bfd_boolean ldgram_in_script = FALSE; 56: bfd_boolean ldgram_had_equals = FALSE; 57: bfd_boolean ldgram_had_keep = FALSE; 58: char *ldgram_vers_current_lang = NULL; 59: 60: #define ERROR_NAME_MAX 20 61: static char *error_names[ERROR_NAME_MAX]; 62: static int error_index; 63: #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++; 64: #define POP_ERROR() error_index--; 65: %} 66: %union { 67: bfd_vma integer; 68: struct big_int 69: { 70: bfd_vma integer; 71: char *str; 72: } bigint; 73: fill_type *fill; 74: char *name; 75: const char *cname; 76: struct wildcard_spec wildcard; 77: struct wildcard_list *wildcard_list; 78: struct name_list *name_list; 79: int token; 80: union etree_union *etree; 81: struct phdr_info 82: { 83: bfd_boolean filehdr; 84: bfd_boolean phdrs; 85: union etree_union *at; 86: union etree_union *flags; 87: } phdr; 88: struct lang_nocrossref *nocrossref; 89: struct lang_output_section_phdr_list *section_phdr; 90: struct bfd_elf_version_deps *deflist; 91: struct bfd_elf_version_expr *versyms; 92: struct bfd_elf_version_tree *versnode; 93: } 94: 95: %type <etree> exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val 96: %type <etree> opt_exp_without_type opt_subalign opt_align 97: %type <fill> fill_opt fill_exp 98: %type <name_list> exclude_name_list 99: %type <wildcard_list> file_NAME_list 100: %type <name> memspec_opt casesymlist 101: %type <name> memspec_at_opt 102: %type <cname> wildcard_name 103: %type <wildcard> wildcard_spec 104: %token <bigint> INT 105: %token <name> NAME LNAME 106: %type <integer> length 107: %type <phdr> phdr_qualifiers 108: %type <nocrossref> nocrossref_list 109: %type <section_phdr> phdr_opt 110: %type <integer> opt_nocrossrefs 111: 112: %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ 113: %right <token> '?' ':' 114: %left <token> OROR 115: %left <token> ANDAND 116: %left <token> '|' 117: %left <token> '^' 118: %left <token> '&' 119: %left <token> EQ NE 120: %left <token> '<' '>' LE GE 121: %left <token> LSHIFT RSHIFT 122: 123: %left <token> '+' '-' 124: %left <token> '*' '/' '%' 125: 126: %right UNARY 127: %token END 128: %left <token> '(' 129: %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE 130: %token SECTIONS PHDRS DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END 131: %token SORT_BY_NAME SORT_BY_ALIGNMENT 132: %token '{' '}' 133: %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH 134: %token INHIBIT_COMMON_ALLOCATION 135: %token SEGMENT_START 136: %token INCLUDE 137: %token MEMORY 138: %token NOLOAD DSECT COPY INFO OVERLAY 139: %token DEFINED TARGET_K SEARCH_DIR MAP ENTRY 140: %token <integer> NEXT 141: %token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K 142: %token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS 143: %token ORIGIN FILL 144: %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS 145: %token ALIGNMOD AT SUBALIGN PROVIDE PROVIDE_HIDDEN AS_NEEDED 146: %type <token> assign_op atype attributes_opt sect_constraint 147: %type <name> filename 148: %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K 149: %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL 150: %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START 151: %token <name> VERS_TAG VERS_IDENTIFIER 152: %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT 153: %token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL 154: %token EXCLUDE_FILE 155: %token CONSTANT 156: %type <versyms> vers_defns 157: %type <versnode> vers_tag 158: %type <deflist> verdep 159: %token INPUT_DYNAMIC_LIST 160: 161: %% 162: 163: file: 164: INPUT_SCRIPT script_file 165: | INPUT_MRI_SCRIPT mri_script_file 166: | INPUT_VERSION_SCRIPT version_script_file 167: | INPUT_DYNAMIC_LIST dynamic_list_file 168: | INPUT_DEFSYM defsym_expr 169: ; 170: 171: 172: filename: NAME; 173: 174: 175: defsym_expr: 176: { ldlex_defsym(); } 177: NAME '=' exp 178: { 179: ldlex_popstate(); 180: lang_add_assignment(exp_assop($3,$2,$4)); 181: } 182: ; 183: 184: /* SYNTAX WITHIN AN MRI SCRIPT FILE */ 185: mri_script_file: 186: { 187: ldlex_mri_script (); 188: PUSH_ERROR (_("MRI style script")); 189: } 190: mri_script_lines 191: { 192: ldlex_popstate (); 193: mri_draw_tree (); 194: POP_ERROR (); 195: } 196: ; 197: 198: mri_script_lines: 199: mri_script_lines mri_script_command NEWLINE 200: | 201: ; 202: 203: mri_script_command: 204: CHIP exp 205: | CHIP exp ',' exp 206: | NAME { 207: einfo(_("%P%F: unrecognised keyword in MRI style script '%s'\n"),$1); 208: } 209: | LIST { 210: config.map_filename = "-"; 211: } 212: | ORDER ordernamelist 213: | ENDWORD 214: | PUBLIC NAME '=' exp 215: { mri_public($2, $4); } 216: | PUBLIC NAME ',' exp 217: { mri_public($2, $4); } 218: | PUBLIC NAME exp 219: { mri_public($2, $3); } 220: | FORMAT NAME 221: { mri_format($2); } 222: | SECT NAME ',' exp 223: { mri_output_section($2, $4);} 224: | SECT NAME exp 225: { mri_output_section($2, $3);} 226: | SECT NAME '=' exp 227: { mri_output_section($2, $4);} 228: | ALIGN_K NAME '=' exp 229: { mri_align($2,$4); } 230: | ALIGN_K NAME ',' exp 231: { mri_align($2,$4); } 232: | ALIGNMOD NAME '=' exp 233: { mri_alignmod($2,$4); } 234: | ALIGNMOD NAME ',' exp 235: { mri_alignmod($2,$4); } 236: | ABSOLUTE mri_abs_name_list 237: | LOAD mri_load_name_list 238: | NAMEWORD NAME 239: { mri_name($2); } 240: | ALIAS NAME ',' NAME 241: { mri_alias($2,$4,0);} 242: | ALIAS NAME ',' INT 243: { mri_alias ($2, 0, (int) $4.integer); } 244: | BASE exp 245: { mri_base($2); } 246: | TRUNCATE INT 247: { mri_truncate ((unsigned int) $2.integer); } 248: | CASE casesymlist 249: | EXTERN extern_name_list 250: | INCLUDE filename 251: { ldlex_script (); ldfile_open_command_file($2); } 252: mri_script_lines END 253: { ldlex_popstate (); } 254: | START NAME 255: { lang_add_entry ($2, FALSE); } 256: | 257: ; 258: 259: ordernamelist: 260: ordernamelist ',' NAME { mri_order($3); } 261: | ordernamelist NAME { mri_order($2); } 262: | 263: ; 264: 265: mri_load_name_list: 266: NAME 267: { mri_load($1); } 268: | mri_load_name_list ',' NAME { mri_load($3); } 269: ; 270: 271: mri_abs_name_list: 272: NAME 273: { mri_only_load($1); } 274: | mri_abs_name_list ',' NAME 275: { mri_only_load($3); } 276: ; 277: 278: casesymlist: 279: /* empty */ { $$ = NULL; } 280: | NAME 281: | casesymlist ',' NAME 282: ; 283: 284: /* Parsed as expressions so that commas separate entries */ 285: extern_name_list: 286: { ldlex_expression (); } 287: extern_name_list_body 288: { ldlex_popstate (); } 289: 290: extern_name_list_body: 291: NAME 292: { ldlang_add_undef ($1); } 293: | extern_name_list_body NAME 294: { ldlang_add_undef ($2); } 295: | extern_name_list_body ',' NAME 296: { ldlang_add_undef ($3); } 297: ; 298: 299: script_file: 300: { ldlex_both(); } 301: ifile_list 302: { ldlex_popstate(); } 303: ; 304: 305: ifile_list: 306: ifile_list ifile_p1 307: | 308: ; 309: 310: 311: ifile_p1: 312: memory 313: | sections 314: | phdrs 315: | startup 316: | high_level_library 317: | low_level_library 318: | floating_point_support 319: | statement_anywhere 320: | version 321: | ';' 322: | TARGET_K '(' NAME ')' 323: { lang_add_target($3); } 324: | SEARCH_DIR '(' filename ')' 325: { ldfile_add_library_path ($3, FALSE); } 326: | OUTPUT '(' filename ')' 327: { lang_add_output($3, 1); } 328: | OUTPUT_FORMAT '(' NAME ')' 329: { lang_add_output_format ($3, (char *) NULL, 330: (char *) NULL, 1); } 331: | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')' 332: { lang_add_output_format ($3, $5, $7, 1); } 333: | OUTPUT_ARCH '(' NAME ')' 334: { ldfile_set_output_arch ($3, bfd_arch_unknown); } 335: | FORCE_COMMON_ALLOCATION 336: { command_line.force_common_definition = TRUE ; } 337: | INHIBIT_COMMON_ALLOCATION 338: { command_line.inhibit_common_definition = TRUE ; } 339: | INPUT '(' input_list ')' 340: | GROUP 341: { lang_enter_group (); } 342: '(' input_list ')' 343: { lang_leave_group (); } 344: | MAP '(' filename ')' 345: { lang_add_map($3); } 346: | INCLUDE filename 347: { ldlex_script (); ldfile_open_command_file($2); } 348: ifile_list END 349: { ldlex_popstate (); } 350: | NOCROSSREFS '(' nocrossref_list ')' 351: { 352: lang_add_nocrossref ($3); 353: } 354: | EXTERN '(' extern_name_list ')' 355: ; 356: 357: input_list: 358: NAME 359: { lang_add_input_file($1,lang_input_file_is_search_file_enum, 360: (char *)NULL); } 361: | input_list ',' NAME 362: { lang_add_input_file($3,lang_input_file_is_search_file_enum, 363: (char *)NULL); } 364: | input_list NAME 365: { lang_add_input_file($2,lang_input_file_is_search_file_enum, 366: (char *)NULL); } 367: | LNAME 368: { lang_add_input_file($1,lang_input_file_is_l_enum, 369: (char *)NULL); } 370: | input_list ',' LNAME 371: { lang_add_input_file($3,lang_input_file_is_l_enum, 372: (char *)NULL); } 373: | input_list LNAME 374: { lang_add_input_file($2,lang_input_file_is_l_enum, 375: (char *)NULL); } 376: | AS_NEEDED '(' 377: { $<integer>$ = as_needed; as_needed = TRUE; } 378: input_list ')' 379: { as_needed = $<integer>3; } 380: | input_list ',' AS_NEEDED '(' 381: { $<integer>$ = as_needed; as_needed = TRUE; } 382: input_list ')' 383: { as_needed = $<integer>5; } 384: | input_list AS_NEEDED '(' 385: { $<integer>$ = as_needed; as_needed = TRUE; } 386: input_list ')' 387: { as_needed = $<integer>4; } 388: ; 389: 390: sections: 391: SECTIONS '{' sec_or_group_p1 '}' 392: ; 393: 394: sec_or_group_p1: 395: sec_or_group_p1 section 396: | sec_or_group_p1 statement_anywhere 397: | 398: ; 399: 400: statement_anywhere: 401: ENTRY '(' NAME ')' 402: { lang_add_entry ($3, FALSE); } 403: | assignment end 404: | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')' 405: { ldlex_popstate (); 406: lang_add_assignment (exp_assert ($4, $6)); } 407: ; 408: 409: /* The '*' and '?' cases are there because the lexer returns them as 410: separate tokens rather than as NAME. */ 411: wildcard_name: 412: NAME 413: { 414: $$ = $1; 415: } 416: | '*' 417: { 418: $$ = "*"; 419: } 420: | '?' 421: { 422: $$ = "?"; 423: } 424: ; 425: 426: wildcard_spec: 427: wildcard_name 428: { 429: $$.name = $1; 430: $$.sorted = none; 431: $$.exclude_name_list = NULL; 432: } 433: | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name 434: { 435: $$.name = $5; 436: $$.sorted = none; 437: $$.exclude_name_list = $3; 438: } 439: | SORT_BY_NAME '(' wildcard_name ')' 440: { 441: $$.name = $3; 442: $$.sorted = by_name; 443: $$.exclude_name_list = NULL; 444: } 445: | SORT_BY_ALIGNMENT '(' wildcard_name ')' 446: { 447: $$.name = $3; 448: $$.sorted = by_alignment; 449: $$.exclude_name_list = NULL; 450: } 451: | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' 452: { 453: $$.name = $5; 454: $$.sorted = by_name_alignment; 455: $$.exclude_name_list = NULL; 456: } 457: | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_name ')' ')' 458: { 459: $$.name = $5; 460: $$.sorted = by_name; 461: $$.exclude_name_list = NULL; 462: } 463: | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_name ')' ')' 464: { 465: $$.name = $5; 466: $$.sorted = by_alignment_name; 467: $$.exclude_name_list = NULL; 468: } 469: | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_name ')' ')' 470: { 471: $$.name = $5; 472: $$.sorted = by_alignment; 473: $$.exclude_name_list = NULL; 474: } 475: | SORT_BY_NAME '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')' 476: { 477: $$.name = $7; 478: $$.sorted = by_name; 479: $$.exclude_name_list = $5; 480: } 481: ; 482: 483: exclude_name_list: 484: exclude_name_list wildcard_name 485: { 486: struct name_list *tmp; 487: tmp = (struct name_list *) xmalloc (sizeof *tmp); 488: tmp->name = $2; 489: tmp->next = $1; 490: $$ = tmp; 491: } 492: | 493: wildcard_name 494: { 495: struct name_list *tmp; 496: tmp = (struct name_list *) xmalloc (sizeof *tmp); 497: tmp->name = $1; 498: tmp->next = NULL; 499: $$ = tmp; 500: } 501: ; 502: 503: file_NAME_list: 504: file_NAME_list opt_comma wildcard_spec 505: { 506: struct wildcard_list *tmp; 507: tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); 508: tmp->next = $1; 509: tmp->spec = $3; 510: $$ = tmp; 511: } 512: | 513: wildcard_spec 514: { 515: struct wildcard_list *tmp; 516: tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); 517: tmp->next = NULL; 518: tmp->spec = $1; 519: $$ = tmp; 520: } 521: ; 522: 523: input_section_spec_no_keep: 524: NAME 525: { 526: struct wildcard_spec tmp; 527: tmp.name = $1; 528: tmp.exclude_name_list = NULL; 529: tmp.sorted = none; 530: lang_add_wild (&tmp, NULL, ldgram_had_keep); 531: } 532: | '[' file_NAME_list ']' 533: { 534: lang_add_wild (NULL, $2, ldgram_had_keep); 535: } 536: | wildcard_spec '(' file_NAME_list ')' 537: { 538: lang_add_wild (&$1, $3, ldgram_had_keep); 539: } 540: ; 541: 542: input_section_spec: 543: input_section_spec_no_keep 544: | KEEP '(' 545: { ldgram_had_keep = TRUE; } 546: input_section_spec_no_keep ')' 547: { ldgram_had_keep = FALSE; } 548: ; 549: 550: statement: 551: assignment end 552: | CREATE_OBJECT_SYMBOLS 553: { 554: lang_add_attribute(lang_object_symbols_statement_enum); 555: } 556: | ';' 557: | CONSTRUCTORS 558: { 559: 560: lang_add_attribute(lang_constructors_statement_enum); 561: } 562: | SORT_BY_NAME '(' CONSTRUCTORS ')' 563: { 564: constructors_sorted = TRUE; 565: lang_add_attribute (lang_constructors_statement_enum); 566: } 567: | input_section_spec 568: | length '(' mustbe_exp ')' 569: { 570: lang_add_data ((int) $1, $3); 571: } 572: 573: | FILL '(' fill_exp ')' 574: { 575: lang_add_fill ($3); 576: } 577: | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')' end 578: { ldlex_popstate (); 579: lang_add_assignment (exp_assert ($4, $6)); } 580: ; 581: 582: statement_list: 583: statement_list statement 584: | statement 585: ; 586: 587: statement_list_opt: 588: /* empty */ 589: | statement_list 590: ; 591: 592: length: 593: QUAD 594: { $$ = $1; } 595: | SQUAD 596: { $$ = $1; } 597: | LONG 598: { $$ = $1; } 599: | SHORT 600: { $$ = $1; } 601: | BYTE 602: { $$ = $1; } 603: ; 604: 605: fill_exp: 606: mustbe_exp 607: { 608: $$ = exp_get_fill ($1, 0, "fill value"); 609: } 610: ; 611: 612: fill_opt: 613: '=' fill_exp 614: { $$ = $2; } 615: | { $$ = (fill_type *) 0; } 616: ; 617: 618: assign_op: 619: PLUSEQ 620: { $$ = '+'; } 621: | MINUSEQ 622: { $$ = '-'; } 623: | MULTEQ 624: { $$ = '*'; } 625: | DIVEQ 626: { $$ = '/'; } 627: | LSHIFTEQ 628: { $$ = LSHIFT; } 629: | RSHIFTEQ 630: { $$ = RSHIFT; } 631: | ANDEQ 632: { $$ = '&'; } 633: | OREQ 634: { $$ = '|'; } 635: 636: ; 637: 638: end: ';' | ',' 639: ; 640: 641: 642: assignment: 643: NAME '=' mustbe_exp 644: { 645: lang_add_assignment (exp_assop ($2, $1, $3)); 646: } 647: | NAME assign_op mustbe_exp 648: { 649: lang_add_assignment (exp_assop ('=', $1, 650: exp_binop ($2, 651: exp_nameop (NAME, 652: $1), 653: $3))); 654: } 655: | PROVIDE '(' NAME '=' mustbe_exp ')' 656: { 657: lang_add_assignment (exp_provide ($3, $5, FALSE)); 658: } 659: | PROVIDE_HIDDEN '(' NAME '=' mustbe_exp ')' 660: { 661: lang_add_assignment (exp_provide ($3, $5, TRUE)); 662: } 663: ; 664: 665: 666: opt_comma: 667: ',' | ; 668: 669: 670: memory: 671: MEMORY '{' memory_spec memory_spec_list '}' 672: ; 673: 674: memory_spec_list: 675: memory_spec_list memory_spec 676: | memory_spec_list ',' memory_spec 677: | 678: ; 679: 680: 681: memory_spec: NAME 682: { region = lang_memory_region_lookup ($1, TRUE); } 683: attributes_opt ':' 684: origin_spec opt_comma length_spec 685: {} 686: ; 687: 688: origin_spec: 689: ORIGIN '=' mustbe_exp 690: { 691: region->origin = exp_get_vma ($3, 0, "origin"); 692: region->current = region->origin; 693: } 694: ; 695: 696: length_spec: 697: LENGTH '=' mustbe_exp 698: { 699: region->length = exp_get_vma ($3, -1, "length"); 700: } 701: ; 702: 703: attributes_opt: 704: /* empty */ 705: { /* dummy action to avoid bison 1.25 error message */ } 706: | '(' attributes_list ')' 707: ; 708: 709: attributes_list: 710: attributes_string 711: | attributes_list attributes_string 712: ; 713: 714: attributes_string: 715: NAME 716: { lang_set_flags (region, $1, 0); } 717: | '!' NAME 718: { lang_set_flags (region, $2, 1); } 719: ; 720: 721: startup: 722: STARTUP '(' filename ')' 723: { lang_startup($3); } 724: ; 725: 726: high_level_library: 727: HLL '(' high_level_library_NAME_list ')' 728: | HLL '(' ')' 729: { ldemul_hll((char *)NULL); } 730: ; 731: 732: high_level_library_NAME_list: 733: high_level_library_NAME_list opt_comma filename 734: { ldemul_hll($3); } 735: | filename 736: { ldemul_hll($1); } 737: 738: ; 739: 740: low_level_library: 741: SYSLIB '(' low_level_library_NAME_list ')' 742: ; low_level_library_NAME_list: 743: low_level_library_NAME_list opt_comma filename 744: { ldemul_syslib($3); } 745: | 746: ; 747: 748: floating_point_support: 749: FLOAT 750: { lang_float(TRUE); } 751: | NOFLOAT 752: { lang_float(FALSE); } 753: ; 754: 755: nocrossref_list: 756: /* empty */ 757: { 758: $$ = NULL; 759: } 760: | NAME nocrossref_list 761: { 762: struct lang_nocrossref *n; 763: 764: n = (struct lang_nocrossref *) xmalloc (sizeof *n); 765: n->name = $1; 766: n->next = $2; 767: $$ = n; 768: } 769: | NAME ',' nocrossref_list 770: { 771: struct lang_nocrossref *n; 772: 773: n = (struct lang_nocrossref *) xmalloc (sizeof *n); 774: n->name = $1; 775: n->next = $3; 776: $$ = n; 777: } 778: ; 779: 780: mustbe_exp: { ldlex_expression (); } 781: exp 782: { ldlex_popstate (); $$=$2;} 783: ; 784: 785: exp : 786: '-' exp %prec UNARY 787: { $$ = exp_unop ('-', $2); } 788: | '(' exp ')' 789: { $$ = $2; } 790: | NEXT '(' exp ')' %prec UNARY 791: { $$ = exp_unop ((int) $1,$3); } 792: | '!' exp %prec UNARY 793: { $$ = exp_unop ('!', $2); } 794: | '+' exp %prec UNARY 795: { $$ = $2; } 796: | '~' exp %prec UNARY 797: { $$ = exp_unop ('~', $2);} 798: 799: | exp '*' exp 800: { $$ = exp_binop ('*', $1, $3); } 801: | exp '/' exp 802: { $$ = exp_binop ('/', $1, $3); } 803: | exp '%' exp 804: { $$ = exp_binop ('%', $1, $3); } <