Fix support for NOLOAD, add INCLUDE
[platform/upstream/binutils.git] / ld / ldgram.y
1 /* A YACC grammer to parse a superset of the AT&T linker scripting languaue.
2    Copyright (C) 1991 Free Software Foundation, Inc.
3    Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
4
5 This file is part of GNU ld.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 %{
22 /*
23
24  */
25
26 #define DONTDECLARE_MALLOC
27
28 #include "bfd.h"
29 #include "sysdep.h"
30 #include "ld.h"    
31 #include "ldexp.h"
32 #include "ldver.h"
33 #include "ldlang.h"
34 #include "ldemul.h"
35 #include "ldfile.h"
36 #include "ldmisc.h"
37 #include "mri.h"
38
39 #define YYDEBUG 1
40
41 boolean option_v;
42 extern unsigned int lineno;
43 extern boolean trace_files;
44 extern boolean write_map;
45 extern boolean option_longmap;
46 boolean hex_mode;
47 static int typebits;
48 strip_symbols_type strip_symbols=STRIP_NONE;
49 discard_locals_type discard_locals=DISCARD_NONE;
50
51
52 lang_memory_region_type *region;
53
54
55 lang_memory_region_type *lang_memory_region_lookup();
56 lang_output_section_statement_type *lang_output_section_statement_lookup();
57
58 #ifdef __STDC__
59
60 void lang_add_data(int type, union etree_union *exp);
61 void lang_enter_output_section_statement(char *output_section_statement_name, etree_type *address_exp, int flags, bfd_vma block_value,etree_type*,etree_type*);
62
63 #else
64
65 void lang_add_data();
66 void lang_enter_output_section_statement();
67
68 #endif /* __STDC__ */
69
70 extern args_type command_line;
71 char *current_file;
72 boolean ldgram_want_filename = true;
73 boolean had_script = false;
74 boolean force_make_executable = false;
75
76 boolean ldgram_in_script = false;
77 boolean ldgram_had_equals = false;
78 /* LOCALS */
79
80
81 #define ERROR_NAME_MAX 20
82 static char *error_names[ERROR_NAME_MAX];
83 static int error_index;
84 #define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++;
85 #define POP_ERROR()   error_index--;
86 %}
87 %union {
88   bfd_vma integer;
89   int voidval;
90   char *name;
91   int token;
92   union etree_union *etree;
93 struct sec *section;
94   struct lang_output_section_statement_struct *output_section_statement;
95   union  lang_statement_union **statement_ptr;
96   int lineno;
97   struct {
98     FILE *file;
99     char *name;
100     unsigned int lineno;
101   } state;
102
103   
104 }
105
106 %type <etree> exp  opt_exp_with_type  mustbe_exp
107 %type <integer> fill_opt
108 %type <name> memspec_opt
109 %token <integer> INT  
110 %token <name> NAME
111 %type  <integer> length
112
113 %right <token> PLUSEQ MINUSEQ MULTEQ DIVEQ  '=' LSHIFTEQ RSHIFTEQ   ANDEQ OREQ 
114 %right <token> '?' ':'
115 %left <token> OROR
116 %left <token>  ANDAND
117 %left <token> '|'
118 %left <token>  '^'
119 %left  <token> '&'
120 %left <token>  EQ NE
121 %left  <token> '<' '>' LE GE
122 %left  <token> LSHIFT RSHIFT
123
124 %left  <token> '+' '-'
125 %left  <token> '*' '/' '%'
126
127 /*%token <token> '+' '-' '*' '/' '%'*/
128 %right UNARY
129 %token END 
130 %left <token> '('
131 %token <token> ALIGN_K BLOCK LONG SHORT BYTE
132 %token SECTIONS  
133 %token '{' '}'
134 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
135 %token SIZEOF_HEADERS
136 %token INCLUDE
137 %token MEMORY  DEFSYMEND
138 %token NOLOAD DSECT COPY INFO OVERLAY
139 %token NAME DEFINED TARGET_K SEARCH_DIR MAP ENTRY 
140 %token OPTION_e OPTION_c OPTION_noinhibit_exec OPTION_s OPTION_S OPTION_sort_common
141 %token OPTION_format  OPTION_F OPTION_u OPTION_Bstatic OPTION_N
142 %token <integer> SIZEOF NEXT ADDR 
143 %token OPTION_d OPTION_dc OPTION_dp OPTION_x OPTION_X OPTION_defsym
144 %token OPTION_v OPTION_V OPTION_M OPTION_t STARTUP HLL SYSLIB FLOAT  NOFLOAT 
145 %token OPTION_Map
146 %token OPTION_n OPTION_r OPTION_o OPTION_b  OPTION_R OPTION_relax
147 %token <name> OPTION_l OPTION_L OPTION_T OPTION_Aarch OPTION_Tfile  OPTION_Texp
148 %token <name> OPTION_y
149 %token OPTION_Ur 
150 %token ORIGIN FILL OPTION_g
151 %token LENGTH    CREATE_OBJECT_SYMBOLS INPUT OUTPUT  CONSTRUCTORS
152 %token OPTION_RETAIN_SYMBOLS_FILE ALIGNMOD
153
154 %type <token> assign_op 
155
156 %type <name>  filename
157
158
159 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD
160 %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE
161
162 %{
163 ld_config_type config;
164 %}
165
166 %%
167
168 file:   command_line  { lang_final(); };
169
170
171 filename:  NAME;
172
173
174 command_line:
175                 command_line command_line_option
176         |
177         ;
178
179 command_line_option:
180                 OPTION_Bstatic { }
181         |       OPTION_v
182                         {       
183                         ldversion(0);
184                         option_v = true;
185                         }
186         |       OPTION_V
187                         {       
188                         ldversion(1);
189                         option_v = true;
190                         }
191         |       OPTION_t {
192                         trace_files = true;
193                         }
194         |     OPTION_Map  NAME
195                 {
196                 write_map = true;
197                 config.map_filename = $2;
198                 }
199         |       OPTION_M {
200             config.map_filename = "-";
201                             
202                         }
203         |       OPTION_n {
204                         config.magic_demand_paged = false;
205                         }
206         |       OPTION_N {
207                         config.text_read_only = false;
208                         config.magic_demand_paged = false;
209                         }
210         |       OPTION_s {
211                         strip_symbols = STRIP_ALL;
212                         }
213         |       OPTION_S {
214                         strip_symbols = STRIP_DEBUGGER;
215                         }
216         |       OPTION_u NAME {
217                         ldlang_add_undef($2);
218                 }
219             
220         |       OPTION_r {
221                         config.relocateable_output = true;
222                         config.build_constructors = false;
223                         config.magic_demand_paged = false;
224                         config.text_read_only = false;
225                         }
226         |       OPTION_Ur {
227                         config.relocateable_output = true;
228                         config.build_constructors = true;
229                         config.magic_demand_paged = false;
230                         config.text_read_only = false;
231                       }             
232         |       OPTION_o filename
233                         {
234                         lang_add_output($2); 
235                         }
236         |       OPTION_e NAME
237                         { lang_add_entry($2); 
238                         }
239         |       OPTION_X {
240                         discard_locals = DISCARD_L;
241                 }
242         |       OPTION_x {
243                         discard_locals = DISCARD_ALL;
244                 }
245
246         |       OPTION_noinhibit_exec
247                         {
248                         force_make_executable = true;
249                         }
250         |      OPTION_sort_common {
251         config.sort_common = true;
252       }
253         |      OPTION_d {
254                           command_line.force_common_definition = true;
255                         }
256
257         |      OPTION_relax {
258                           command_line.relax = true;
259                         }
260         |      OPTION_dc
261                          {
262                           command_line.force_common_definition = true;
263                         }
264         |       OPTION_g
265                         {
266                         /* Ignored */
267                         }
268         |       OPTION_dp
269                          {
270                           command_line.force_common_definition = true;
271                         }
272         |       OPTION_format NAME
273                    {
274                           lang_add_target($2);
275                    }
276         |       OPTION_Texp 
277                 { ldlex_expression();
278                         hex_mode  = 16; 
279                 } 
280                 INT
281                 {  ldlex_popstate();
282                         lang_section_start($1,exp_intop($3));
283                         hex_mode = 0; 
284                 }
285         |       OPTION_y
286                         {
287                         add_ysym($1);
288                         }
289         |       OPTION_Aarch 
290                 { 
291                         ldfile_add_arch($1); 
292                 }
293         |        OPTION_b NAME
294                         {
295                         lang_add_target($2);
296                         }
297         |       OPTION_L
298                         {
299                         ldfile_add_library_path($1);
300                         }
301         |       OPTION_F
302                 {
303                 /* Ignore */
304                 }
305         |       NAME
306                 { lang_add_input_file($1,lang_input_file_is_file_enum,
307                                  (char *)NULL); }
308         |       OPTION_c filename 
309                         { ldfile_open_command_file($2); } mri_script_file  END {  ldlex_command();}
310
311         |       OPTION_Tfile 
312                         { ldfile_open_command_file($1); } script_file
313                         END {  ldlex_command();}
314
315         |       OPTION_T filename 
316                         { ldfile_open_command_file($2); } script_file
317                 END {  ldlex_command();}
318
319         |       OPTION_l
320                         {
321                           lang_add_input_file($1,
322                                          lang_input_file_is_l_enum,
323                                          (char *)NULL);
324                         }
325         |       OPTION_R filename
326                         {
327                         lang_add_input_file($2,
328                                 lang_input_file_is_symbols_only_enum,
329                                 (char *)NULL);
330                         }
331
332         |       OPTION_defsym  { ldlex_defsym(); }
333                 NAME     '=' exp  DEFSYMEND { ldlex_popstate();
334                         lang_add_assignment(exp_assop($4,$3,$5));
335                         }
336         |       OPTION_RETAIN_SYMBOLS_FILE filename
337                 { lang_add_keepsyms_file ($2); }
338         | '-' NAME
339                  { info("%P%F Unrecognized option -%s\n", $2);  }
340
341         | '{' script_file '}'  
342         ;
343
344
345 /* SYNTAX WITHIN AN MRI SCRIPT FILE */  
346 mri_script_file:
347                 {       ldlex_mri_script();
348                         PUSH_ERROR("MRI style script");
349                 }
350              mri_script_lines
351                 {       ldlex_popstate(); 
352                         POP_ERROR();
353                 }
354         ;
355
356 mri_script_lines:
357                 mri_script_lines mri_script_command NEWLINE
358           |
359         ;
360
361 mri_script_command:
362                 CHIP  exp 
363         |       CHIP  exp ',' exp
364         |       NAME    {
365                         einfo("%P%F: unrecognised keyword in MRI style script '%s'\n",$1);
366                         }
367         |       LIST    {
368                         write_map = true;
369                         config.map_filename = "-";
370                         }
371         |       ORDER ordernamelist
372         |       ENDWORD 
373         |       PUBLIC NAME '=' exp 
374                         { mri_public($2, $4); }
375         |       PUBLIC NAME ',' exp 
376                         { mri_public($2, $4); }
377         |       PUBLIC NAME  exp 
378                         { mri_public($2, $3); }
379         |       FORMAT NAME
380                         { mri_format($2); }
381         |       SECT NAME ',' exp 
382                         { mri_output_section($2, $4);}
383         |       SECT NAME  exp
384                         { mri_output_section($2, $3);}
385         |       SECT NAME '=' exp
386                         { mri_output_section($2, $4);}
387         |       ALIGN_K NAME '=' exp
388                         { mri_align($2,$4); }
389         |       ALIGNMOD NAME '=' exp
390                         { mri_alignmod($2,$4); }
391         |       ABSOLUTE mri_abs_name_list
392         |       LOAD     mri_load_name_list
393         |       NAMEWORD NAME 
394                         { mri_name($2); }   
395         |       ALIAS NAME ',' NAME
396                         { mri_alias($2,$4,0);}
397         |       ALIAS NAME ',' INT
398                         { mri_alias($2,0,$4);}
399         |       BASE     exp
400                         { mri_base($2); }
401         |       TRUNCATE INT
402                 {  mri_truncate($2); }
403         |
404         ;
405
406 ordernamelist:
407               ordernamelist ',' NAME         { mri_order($3); }
408         |     ordernamelist  NAME         { mri_order($2); }
409         |
410         ;
411
412 mri_load_name_list:
413                 NAME
414                         { mri_load($1); }
415         |       mri_load_name_list ',' NAME { mri_load($3); }
416         ;
417
418 mri_abs_name_list:
419                 NAME
420                         { mri_only_load($1); }
421         |       mri_abs_name_list ','  NAME
422                         { mri_only_load($3); }
423         ;
424
425 script_file:
426         {
427          ldlex_both();
428         }
429        ifile_list
430         {
431         ldlex_popstate();
432         }
433         ;
434
435
436 ifile_list:
437        ifile_list ifile_p1
438         |
439         ;
440
441
442
443 ifile_p1:
444                 memory
445         |       sections
446         |       startup
447         |       high_level_library
448         |       low_level_library
449         |       floating_point_support
450         |       statement_anywhere
451         |        ';'
452         |       TARGET_K '(' NAME ')'
453                 { lang_add_target($3); }
454         |       SEARCH_DIR '(' filename ')'
455                 { ldfile_add_library_path($3); }
456         |       OUTPUT '(' filename ')'
457                 { lang_add_output($3); }
458         | OUTPUT_FORMAT '(' NAME ')'
459                   { lang_add_output_format($3); }
460         | OUTPUT_ARCH '(' NAME ')'
461                   { ldfile_set_output_arch($3); }
462         |       FORCE_COMMON_ALLOCATION
463                 { command_line.force_common_definition = true ; }
464         |       INPUT '(' input_list ')'
465         |       MAP '(' filename ')'
466                 { lang_add_map($3); }
467         |       INCLUDE filename 
468                 { ldfile_open_command_file($2); } ifile_list END
469         ;
470
471 input_list:
472                 NAME
473                 { lang_add_input_file($1,lang_input_file_is_file_enum,
474                                  (char *)NULL); }
475         |       input_list ',' NAME
476                 { lang_add_input_file($3,lang_input_file_is_file_enum,
477                                  (char *)NULL); }
478         |       input_list NAME
479                 { lang_add_input_file($2,
480 lang_input_file_is_file_enum,
481                                  (char *)NULL); }
482         ;
483
484 sections:
485                 SECTIONS '{' sec_or_group_p1 '}'
486         ;
487
488 sec_or_group_p1:
489                 sec_or_group_p1 section
490         |       sec_or_group_p1 statement_anywhere
491         |
492         ;
493
494 statement_anywhere:
495                 ENTRY '(' NAME ')'
496                 { lang_add_entry($3); }
497         |       assignment end
498         ;
499
500 file_NAME_list:
501                 NAME
502                         { lang_add_wild($1, current_file); }
503         |       file_NAME_list opt_comma NAME
504                         { lang_add_wild($3, current_file); }
505         ;
506
507 input_section_spec:
508                 NAME
509                 {
510                 lang_add_wild((char *)NULL, $1);
511                 }
512         |       '['
513                         {
514                         current_file = (char *)NULL;
515                         }
516                         file_NAME_list
517                 ']'
518         |       NAME
519                         {
520                         current_file =$1;
521                         }
522                 '(' file_NAME_list ')'
523         |       '*'
524                         {
525                         current_file = (char *)NULL;
526                         }
527                 '(' file_NAME_list ')'
528         ;
529
530 statement:
531                 statement assignment end
532         |       statement CREATE_OBJECT_SYMBOLS
533                 {
534                 
535 lang_add_attribute(lang_object_symbols_statement_enum); }
536         |       statement ';'
537         |       statement CONSTRUCTORS
538                 {
539                 
540 lang_add_attribute(lang_constructors_statement_enum); }
541
542         |       statement input_section_spec
543         | statement length '(' exp ')'
544                         {
545                         lang_add_data($2,$4);
546                         }
547   
548         |       statement FILL '(' exp ')'
549                         {
550                           lang_add_fill
551                             (exp_get_value_int($4,
552                                                0,
553                                                "fill value",
554                                         
555 lang_first_phase_enum));
556                         }
557         |
558         ;
559
560 length:
561                 LONG
562                         { $$ = $1; }
563         |       SHORT
564                         { $$ = $1; }
565         |       BYTE
566                         { $$ = $1; }
567         ;
568
569 fill_opt:
570           '=' mustbe_exp
571                 {
572                   $$ =   exp_get_value_int($2,
573                                            0,
574                                            "fill value",
575                                            lang_first_phase_enum);
576                 }
577         |       { $$ = 0; }
578         ;
579
580                 
581
582 assign_op:
583                 PLUSEQ
584                         { $$ = '+'; }
585         |       MINUSEQ
586                         { $$ = '-'; }
587         |       MULTEQ
588                         { $$ = '*'; }
589         |       DIVEQ
590                         { $$ = '/'; }
591         |       LSHIFTEQ
592                         { $$ = LSHIFT; }
593         |       RSHIFTEQ
594                         { $$ = RSHIFT; }
595         |       ANDEQ
596                         { $$ = '&'; }
597         |       OREQ
598                         { $$ = '|'; }
599
600         ;
601
602 end:    ';' | ','
603         ;
604
605
606 assignment:
607                 NAME '=' mustbe_exp
608                 {
609                   lang_add_assignment(exp_assop($2,$1,$3));
610                 }
611         |       NAME assign_op mustbe_exp
612                 {
613                 
614 lang_add_assignment(exp_assop('=',$1,exp_binop($2,exp_nameop(NAME,$1),$3)));
615                 }
616                 
617         ;
618
619
620 opt_comma:
621                 ','     |       ;
622
623
624 memory:
625                 MEMORY '{' memory_spec memory_spec_list '}'
626         ;
627
628 memory_spec_list:
629                 memory_spec_list memory_spec
630         |       memory_spec_list ',' memory_spec
631         |
632         ;
633
634
635 memory_spec:            NAME
636                         { region = lang_memory_region_lookup($1); }
637                 attributes_opt ':'
638                 origin_spec opt_comma length_spec
639
640         ; origin_spec:
641         ORIGIN '=' mustbe_exp
642                 { region->current =
643                  region->origin =
644                  exp_get_vma($3, 0L,"origin", lang_first_phase_enum);
645 }
646         ; length_spec:
647              LENGTH '=' mustbe_exp
648                { region->length = exp_get_vma($3,
649                                                ~((bfd_vma)0),
650                                                "length",
651                                                lang_first_phase_enum);
652                 }
653         
654
655 attributes_opt:
656                   '(' NAME ')'
657                         {
658                         lang_set_flags(&region->flags, $2);
659                         }
660         |
661   
662         ;
663
664 startup:
665         STARTUP '(' filename ')'
666                 { lang_startup($3); }
667         ;
668
669 high_level_library:
670                 HLL '(' high_level_library_NAME_list ')'
671         |       HLL '(' ')'
672                         { ldemul_hll((char *)NULL); }
673         ;
674
675 high_level_library_NAME_list:
676                 high_level_library_NAME_list opt_comma filename
677                         { ldemul_hll($3); }
678         |       filename
679                         { ldemul_hll($1); }
680
681         ;
682
683 low_level_library:
684         SYSLIB '(' low_level_library_NAME_list ')'
685         ; low_level_library_NAME_list:
686                 low_level_library_NAME_list opt_comma filename
687                         { ldemul_syslib($3); }
688         |
689         ;
690
691 floating_point_support:
692                 FLOAT
693                         { lang_float(true); }
694         |       NOFLOAT
695                         { lang_float(false); }
696         ;
697                 
698
699 mustbe_exp:              { ldlex_expression(); }
700                 exp
701                          { ldlex_popstate(); $$=$2;}
702         ;
703
704 exp     :
705                 '-' exp %prec UNARY
706                         { $$ = exp_unop('-', $2); }
707         |       '(' exp ')'
708                         { $$ = $2; }
709         |       NEXT '(' exp ')' %prec UNARY
710                         { $$ = exp_unop($1,$3); }
711         |       '!' exp %prec UNARY
712                         { $$ = exp_unop('!', $2); }
713         |       '+' exp %prec UNARY
714                         { $$ = $2; }
715         |       '~' exp %prec UNARY
716                         { $$ = exp_unop('~', $2);}
717
718         |       exp '*' exp
719                         { $$ = exp_binop('*', $1, $3); }
720         |       exp '/' exp
721                         { $$ = exp_binop('/', $1, $3); }
722         |       exp '%' exp
723                         { $$ = exp_binop('%', $1, $3); }
724         |       exp '+' exp
725                         { $$ = exp_binop('+', $1, $3); }
726         |       exp '-' exp
727                         { $$ = exp_binop('-' , $1, $3); }
728         |       exp LSHIFT exp
729                         { $$ = exp_binop(LSHIFT , $1, $3); }
730         |       exp RSHIFT exp
731                         { $$ = exp_binop(RSHIFT , $1, $3); }
732         |       exp EQ exp
733                         { $$ = exp_binop(EQ , $1, $3); }
734         |       exp NE exp
735                         { $$ = exp_binop(NE , $1, $3); }
736         |       exp LE exp
737                         { $$ = exp_binop(LE , $1, $3); }
738         |       exp GE exp
739                         { $$ = exp_binop(GE , $1, $3); }
740         |       exp '<' exp
741                         { $$ = exp_binop('<' , $1, $3); }
742         |       exp '>' exp
743                         { $$ = exp_binop('>' , $1, $3); }
744         |       exp '&' exp
745                         { $$ = exp_binop('&' , $1, $3); }
746         |       exp '^' exp
747                         { $$ = exp_binop('^' , $1, $3); }
748         |       exp '|' exp
749                         { $$ = exp_binop('|' , $1, $3); }
750         |       exp '?' exp ':' exp
751                         { $$ = exp_trinop('?' , $1, $3, $5); }
752         |       exp ANDAND exp
753                         { $$ = exp_binop(ANDAND , $1, $3); }
754         |       exp OROR exp
755                         { $$ = exp_binop(OROR , $1, $3); }
756         |       DEFINED '(' NAME ')'
757                         { $$ = exp_nameop(DEFINED, $3); }
758         |       INT
759                         { $$ = exp_intop($1); }
760         |       SIZEOF_HEADERS
761                         { $$ = exp_nameop(SIZEOF_HEADERS,0); }
762
763         |       SIZEOF '(' NAME ')'
764                         { $$ = exp_nameop(SIZEOF,$3); }
765         |       ADDR '(' NAME ')'
766                         { $$ = exp_nameop(ADDR,$3); }
767         |       ABSOLUTE '(' exp ')'
768                         { $$ = exp_unop(ABSOLUTE, $3); }
769         |       ALIGN_K '(' exp ')'
770                         { $$ = exp_unop(ALIGN_K,$3); }
771         |       NAME
772                         { $$ = exp_nameop(NAME,$1); }
773         ;
774
775
776
777
778 section:        NAME            { ldlex_expression(); }
779                 opt_exp_with_type       { ldlex_popstate(); }
780                 '{'
781                 {
782                 lang_enter_output_section_statement($1,$3,typebits,0,0,0);
783                 }
784                statement        
785                 '}' {ldlex_expression();} fill_opt memspec_opt
786                 {
787                   ldlex_popstate();
788                   lang_leave_output_section_statement($10, $11);
789                 }
790 opt_comma
791
792         ;
793
794 type:
795            NOLOAD  { typebits = SEC_NEVER_LOAD; }
796         |  DSECT   { typebits = 0; }
797         |  COPY    { typebits = 0; }
798         |  INFO    { typebits = 0; }
799         |  OVERLAY { typebits = 0; }
800         | { typebits = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; }
801         ;
802
803
804 opt_exp_with_type:
805                 exp ':' { $$ = $1; typebits =0;}
806         |       exp '(' type ')' ':' { $$ = $1; }
807         |       ':'     { $$= (etree_type *)NULL; typebits = 0}
808         ;
809
810 memspec_opt:
811                 '>' NAME
812                 { $$ = $2; }
813         |       { $$ = "*default*"; }
814         ;
815 %%
816 void
817 yyerror(arg) 
818 char *arg;
819
820   if (error_index> 0  && error_index < ERROR_NAME_MAX)
821      einfo("%P%F: %S syntax error in %s\n",error_names[error_index-1]);
822   else
823      einfo("%P%F: %S syntax error\n");
824 }