(linenum→info "unix/slp.c:2238")

binutils/2.18/ld/ldgram.y

    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); }
<