* Makefile.in: added relax, also made three stage go through a
[platform/upstream/binutils.git] / ld / ldlex.l
1 %{
2 /* Copyright (C) 1991 Free Software Foundation, Inc.
3
4 This file is part of GLD, the Gnu Linker.
5
6 GLD is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GLD is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GLD; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /*
21  *  $Id$ 
22
23  *
24 */
25
26
27
28 /*SUPPRESS 529*/
29 /*SUPPRESS 26*/
30 /*SUPPRESS 29*/
31 /*#define LEXDEBUG 0*/
32 #include "bfd.h"
33 #include "sysdep.h"
34
35 #include <ctype.h>
36 #include "ldlex.h"
37
38 #include "ld.h"
39 #include "ldexp.h"
40 #include "ldgram.h"
41 #include "ldmisc.h"
42
43 #undef input
44 #undef unput
45 #define input lex_input
46 #define unput lex_unput
47
48 int debug;
49
50
51 static boolean ldgram_in_defsym;
52 static boolean ldgram_had_equals;
53 extern boolean ldgram_in_script;
54 static char *command_line;
55
56 extern int fgetc();
57 extern int yyparse();
58
59 typedef struct {
60         char *name;     
61 int value;
62 } keyword_type;
63 #define RTOKEN(x)  {  yylval.token = x; return x; }
64 keyword_type keywords[] = 
65 {
66 "/", '/',
67 "MEMORY",MEMORY,
68 "ORIGIN",ORIGIN,
69 "BLOCK",BLOCK,
70 "LENGTH",LENGTH,
71 "ALIGN",ALIGN_K,
72 "ADDR",ADDR,
73 "ENTRY",ENTRY,
74 "NEXT",NEXT,
75 "sizeof_headers",SIZEOF_HEADERS,
76 "SIZEOF_HEADERS",SIZEOF_HEADERS,
77 "MAP",MAP,
78 "SIZEOF",SIZEOF,
79 "TARGET",TARGET_K,
80 "SEARCH_DIR",SEARCH_DIR,
81 "OUTPUT",OUTPUT,
82 "INPUT",INPUT,
83 "DEFINED",DEFINED,
84 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
85 "CONSTRUCTORS", CONSTRUCTORS,
86 "FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
87 "SECTIONS",SECTIONS,
88 "FILL",FILL,
89 "STARTUP",STARTUP,
90 "OUTPUT_FORMAT",OUTPUT_FORMAT,
91 "OUTPUT_ARCH", OUTPUT_ARCH,
92 "HLL",HLL,
93 "SYSLIB",SYSLIB,
94 "FLOAT",FLOAT,
95 "LONG", LONG,
96 "SHORT", SHORT,
97 "BYTE", BYTE,
98 "NOFLOAT",NOFLOAT,
99
100 "NOLOAD",NOLOAD,
101 "DSECT",DSECT,
102 "COPY",COPY,
103 "INFO",INFO,
104 "OVERLAY",OVERLAY,
105
106 "o",ORIGIN,
107 "org",ORIGIN,
108 "l", LENGTH,
109 "len", LENGTH,
110 0,0};
111 unsigned int lineno;
112 extern boolean hex_mode;
113 FILE *ldlex_input_stack;
114 static unsigned int have_pushback;
115
116 #define NPUSHBACK 10
117 int pushback[NPUSHBACK];
118 int thischar;
119 extern char *ldfile_input_filename;
120 int donehash = 0;
121 int
122 lex_input()
123 {
124   if (have_pushback > 0) 
125       {
126         have_pushback --;
127         return thischar = pushback[have_pushback];
128       }
129   if (ldlex_input_stack) {
130     thischar = fgetc(ldlex_input_stack);
131
132     if (thischar == EOF)  {
133       fclose(ldlex_input_stack);
134       ldlex_input_stack = (FILE *)NULL;
135       ldfile_input_filename = (char *)NULL;
136       /* First char after script eof is a @ so that we can tell the grammer
137          that we've left */
138       thischar = '@';
139
140     }
141   }
142   else if (command_line && *command_line)  {
143     thischar = *(command_line++);
144   }
145   else {
146  thischar = 0;
147   }
148   if(thischar == '\t') thischar = ' ';
149   if (thischar == '\n') { thischar = ' '; lineno++; }
150   return thischar ;
151 }
152
153 void
154 lex_unput(c)
155 int c;
156 {
157   if (have_pushback > NPUSHBACK) {
158     info("%F%P Too many pushbacks\n");
159   }
160
161   pushback[have_pushback] = c;
162   have_pushback ++;
163 }
164
165
166         int
167 yywrap()
168          { return 1; }
169 /*VARARGS*/
170
171 void
172 allprint(x) 
173 int x;
174 {
175 fprintf(yyout,"%d",x);
176 }
177
178 void
179 sprint(x) 
180 char *x;
181 {
182 fprintf(yyout,"%s",x);
183 }
184
185 int  thischar;
186
187 void parse_line(arg)
188 char *arg;
189 {
190   command_line = arg;
191   have_pushback = 0;
192   yyparse();
193 }
194
195
196
197 void
198 parse_args(ac, av)
199 int ac;
200 char **av;
201 {
202   char *p;
203   int i;
204   size_t size = 0;
205   char *dst;
206   debug = 1;
207   for (i= 1; i < ac; i++) {
208     size += strlen(av[i]) + 2; 
209   }
210   dst = p = (char *)ldmalloc(size + 2);
211 /* Put a space arount each option */
212
213
214   for (i =1; i < ac; i++) {
215
216     unsigned int s = strlen(av[i]);
217   *dst++ = ' ';
218     memcpy(dst, av[i], s);
219     dst[s] = ' ';
220     dst += s + 1;
221   }
222   *dst  = 0;
223   parse_line(p);
224
225   free(p);
226
227
228 }
229
230 static long 
231 DEFUN(number,(default_if_zero,base),
232       int default_if_zero AND
233       int base)
234 {
235   unsigned  long l = 0;
236   int ch = yytext[0];
237   if (ch == 0) {
238     base = default_if_zero;
239   }
240   while (1) {
241     switch (ch) {
242     case 'x':
243       base = 16;
244       break;
245     case 'k':
246     case 'K':
247       l =l * 1024;
248       break;
249     case 'm':
250     case 'M':
251       l =l * 1024 * 1024;
252       break;
253     case '0': case '1': case '2': case '3': case '4':
254     case '5': case '6': case '7': case '8': case '9':
255       l = l * base + ch - '0';
256       break;
257     case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
258       l =l *base + ch - 'a' + 10;
259       break;
260     case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
261       l =l *base + ch - 'A' + 10;
262       break;
263     default:
264       unput(ch);
265       yylval.integer = l;
266       return INT;
267     }
268 ch = input();
269   }
270 }
271 %}
272
273 %a 4000
274 %o 5000
275 FILENAMECHAR    [a-zA-Z0-9\/\.\-\_\+\=]
276 FILENAME        {FILENAMECHAR}+
277 WHITE           [ \t]+ 
278
279 %%
280
281 "@" { return '}'; }
282 "\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
283 "\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
284 "\ -sort_common\ " { return OPTION_sort_common;}
285 "\ -format\ " { return OPTION_format; }
286 "\ -n\ "                { return OPTION_n; }
287 "\ -N\ "                { return OPTION_N; }
288 "\ -r\ "                { return OPTION_r; }
289 "\ -relax\ "            { return OPTION_relax; }
290 "\ -i\ "                { return OPTION_r; }
291 "\ -Ur\ "               { return OPTION_Ur; }
292 "\ -o\ "                { return OPTION_o; }
293 "\ -g\ "                { return OPTION_g; }
294 "\ -e\ "                { return OPTION_e; }
295 "\ -b\ "                { return OPTION_b; }
296 "\ -dc\ "               { return OPTION_dc; }
297 "\ -dp\ "               { return OPTION_dp; }
298 "\ -d\ "                { return OPTION_d; }
299 "\ -v\ "                { return OPTION_v; }
300 "\ -V\ "                { return OPTION_V; }
301 "\ -M\ "                { return OPTION_M; }
302 "\ -Map\ "              { return OPTION_Map;}
303 "\ -t\ "                { return OPTION_t; }
304 "\ -X\ "                { return OPTION_X; }
305 "\ -x\ "                { return OPTION_x; }
306 "\ -c\ "                { return OPTION_c; }
307 "\ -R\ "                { return OPTION_R; }
308 "\ -u\ "                { return OPTION_u; }
309 "\ -s\ "            { return OPTION_s; }
310 "\ -S\ "            { return OPTION_S; }
311 "\ -Bstatic"  { return OPTION_Bstatic; }
312 "\ -B{FILENAME}\ "    { /* Ignored */ }
313 "\ -l"{FILENAME} {
314                 yylval.name = buystring(yytext+3);
315                 return OPTION_l; 
316         }
317
318 "\ -L"{FILENAME}        { 
319                 yylval.name = buystring(yytext+3);
320                 return OPTION_L; 
321          }
322 "\ -Ttext\ "  {
323                  yylval.name = ".text";
324                  return OPTION_Texp;
325                }
326 "\ -Tdata\ "  {
327                  yylval.name = ".data";
328                  return OPTION_Texp;
329                }
330 "\ -Tbss\ "  {
331                  yylval.name = ".bss";
332                  return OPTION_Texp;
333                }
334 "\ -O"{FILENAME} {
335                 yylval.name = buystring(yytext+3);
336                 return OPTION_Texp;
337                 }
338
339 "\ -T"{FILENAME}  {
340                  yylval.name = buystring(yytext+3);
341                  return OPTION_Tfile;
342                }
343 "\ -T\ "          {
344                  return OPTION_T;
345                }
346
347 "\ -F"{FILENAME}  {
348                  return OPTION_F;
349                }
350 "\ -F\ "          {
351                  return OPTION_F;
352                }
353
354 "\ -A"{FILENAME} {
355                  yylval.name = buystring(yytext+3);
356                  return OPTION_Aarch;
357                }
358
359 " "             {
360                  if (ldgram_had_equals == true) {
361                           ldgram_in_defsym = false;
362                           ldgram_had_equals = false;
363                   }
364         }
365 "<<="           { RTOKEN(LSHIFTEQ);}
366 ">>="           { RTOKEN(RSHIFTEQ);}
367 "||"            { RTOKEN(OROR);}
368 "=="            { RTOKEN(EQ);}
369 "!="            { RTOKEN(NE);}
370 ">="            { RTOKEN(GE);}
371 "<="            { RTOKEN(LE);}
372 "<<"            { RTOKEN(LSHIFT);}
373 ">>"            { RTOKEN(RSHIFT);}
374 "+="            { RTOKEN(PLUSEQ);}
375 "-="            { RTOKEN(MINUSEQ);}
376 "*="            { RTOKEN(MULTEQ);}
377 "/="            { RTOKEN(DIVEQ);}
378 "&="            { RTOKEN(ANDEQ);}
379 "|="            { RTOKEN(OREQ);}
380 "&&"            { RTOKEN(ANDAND);}
381 ">"             { RTOKEN('>');}
382 ","             { RTOKEN(',');}
383 "&"             { RTOKEN('&');}
384 "|"             { RTOKEN('|');}
385 "~"             { RTOKEN('~');}
386 "!"             { RTOKEN('!');}
387 "?"             { RTOKEN('?');}
388 "*"             { RTOKEN('*');}
389 "%"             { RTOKEN('%');}
390 "<"             { RTOKEN('<');}
391 ">"             { RTOKEN('>');}
392 "}"             { RTOKEN('}') ; }
393 "{"             { RTOKEN('{'); }
394 ")"             { RTOKEN(')');}
395 "("             { RTOKEN('(');}
396 "]"             { RTOKEN(']');}
397 "["             { RTOKEN('[');}
398 ":"             { RTOKEN(':'); }
399 ";"             { RTOKEN(';');}
400 "-"             { RTOKEN('-');}
401
402
403
404 "/*"            { 
405   while (1) {
406     int ch;
407     ch = input();
408     while (ch != '*') {
409       ch = input();
410     }
411
412
413
414     if (input() == '/') {
415       break;
416     }
417     unput(yytext[yyleng-1]);
418   }
419 }
420
421 "\""[^\"]*"\"" {
422
423   yylval.name = buystring(yytext+1);
424   yylval.name[yyleng-2] = 0; /* Fry final quote */
425   return NAME;
426 }
427
428 {FILENAMECHAR} {
429
430   boolean loop = false;
431   int ch;
432   keyword_type *k;
433
434   /* If we're in hex mode (only after a -T) then all we can see are numbers
435      hex digit we see will be a number. */
436
437   if (hex_mode) {       
438     return number(16, 16);
439   }
440
441   /* If we're in a defsym then all things starting with a digit are in
442      hex */
443
444   if (isdigit(yytext[0]) && ldgram_in_defsym) {
445     return number(16,16);
446   }
447
448
449   /* Otherwise if we're in a script we will parse the numbers
450      normally */
451
452   if (ldgram_in_script == true && isdigit(yytext[0])) {
453     return number(8,10);
454   }
455
456   /* Anywhere not in a script or defsym, an opertor is part of a
457      filename, except / and, which is an operator when on its own */
458   if (ldgram_in_script == true|| ldgram_in_defsym == true) {
459
460     switch (yytext[0]) {
461       case '*': RTOKEN('*');
462
463       case '=': {
464         ldgram_had_equals = true;
465         RTOKEN('=');
466       }
467         break;
468      case '/': {
469        if (ldgram_in_defsym) RTOKEN('/');
470      }
471         break;
472       case '+': RTOKEN('+');
473       case '-': RTOKEN('-');
474       case '!': RTOKEN('!');
475       case '~': RTOKEN('~');
476       }
477     }
478
479
480 /* Otherwise this must be a file or a symbol name, and it will continue to be a
481    filename until we get to something strange. In scripts operator looking
482    things  are taken to be operators, except /, which will be left
483  */
484   ch = input();
485   while (true)
486       {
487         if (ldgram_in_defsym == true) {
488           switch (ch) {
489           case '*': 
490           case '=': 
491           case '+': 
492           case '/': 
493           case '-': 
494           case '!': 
495           case '~': 
496             goto quit;
497           }
498           
499         }
500         if(ldgram_in_script == true) {
501           switch (ch) {
502           case '*': 
503           case '=': 
504           case '+': 
505           case '-': 
506           case '!': 
507           case '~': 
508             goto quit;
509           }
510         }
511
512         if (isalpha(ch) || isdigit(ch) || ch == '.'  || ch == '_'  ||
513             ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
514           yytext[yyleng++] = ch;
515         }
516         else 
517           break;
518         ch = input();
519       }
520  quit:;
521   yytext[yyleng] = 0;
522   unput(ch);
523
524   for(k = keywords; k ->name != (char *)NULL; k++) {
525     if (strcmp(k->name, yytext)==0) {
526       yylval.token = k->value;
527       return k->value;
528     }
529   }
530   yylval.name = buystring(yytext);
531   return NAME;
532 }
533
534
535
536
537
538 %%