Initial revision
[deliverable/binutils-gdb.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 1, 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
32 #include "sysdep.h"
33 #include "bfd.h"
34
35 #include <ctype.h>
36 #include "ldlex.h"
37
38 #include "ld.h"
39 #include "ldexp.h"
40 #include "ldgram.tab.h"
41 #include "ldmisc.h"
42
43 #undef input
44 #undef unput
45 #define input lex_input
46 #define unput lex_unput
47 int debug;
48
49 extern boolean ldgram_in_expression;
50 extern boolean ldgram_in_defsym;
51
52 static char *command_line;
53
54 extern int fgetc();
55 extern int yyparse();
56
57 typedef struct {
58 char *name;
59 int value;
60 } keyword_type;
61 #define RTOKEN(x) { yylval.token = x; return x; }
62 keyword_type keywords[] =
63 {
64 "MEMORY",MEMORY,
65 "ORIGIN",ORIGIN,
66 "BLOCK",BLOCK,
67 "LENGTH",LENGTH,
68 "ALIGN",ALIGN_K,
69 "SUBSECTION_ALIGN",SUBSECTION_ALIGN,
70 "ADDR",ADDR,
71 "ENTRY",ENTRY,
72 "NEXT",NEXT,
73 "MAP",MAP,
74 "SIZEOF",SIZEOF,
75 "TARGET",TARGET_K,
76 "SEARCH_DIR",SEARCH_DIR,
77 "OUTPUT",OUTPUT,
78 "INPUT",INPUT,
79 "DEFINED",DEFINED,
80 "CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
81 "SECTIONS",SECTIONS,
82 "FILL",FILL,
83 "STARTUP",STARTUP,
84 "HLL",HLL,
85 "SYSLIB",SYSLIB,
86 "FLOAT",FLOAT,
87 "LONG", LONG,
88 "SHORT", SHORT,
89 "BYTE", BYTE,
90 "NOFLOAT",NOFLOAT,
91 "o",ORIGIN,
92 "org",ORIGIN,
93 "l", LENGTH,
94 "len", LENGTH,
95 0,0};
96 unsigned int lineno;
97 extern boolean hex_mode;
98 FILE *ldlex_input_stack;
99 static unsigned int have_pushback;
100 #define NPUSHBACK 10
101 int pushback[NPUSHBACK];
102 int thischar;
103 extern char *ldfile_input_filename;
104
105 int
106 lex_input()
107 {
108
109
110 if (have_pushback > 0)
111 {
112 have_pushback --;
113 return thischar = pushback[have_pushback];
114 }
115 if (ldlex_input_stack) {
116 thischar = fgetc(ldlex_input_stack);
117
118 if (thischar == EOF) {
119 fclose(ldlex_input_stack);
120 ldlex_input_stack = (FILE *)NULL;
121 ldfile_input_filename = (char *)NULL;
122 thischar = lex_input();
123
124 }
125 }
126 else if (command_line && *command_line) {
127 thischar = *(command_line++);
128 }
129 else thischar = 0;
130 if(thischar == '\t') thischar = ' ';
131 if (thischar == '\n') { thischar = ' '; lineno++; }
132 return thischar ;
133 }
134
135 void
136 lex_unput(c)
137 int c;
138 {
139 if (have_pushback > NPUSHBACK) {
140 info("%F%P Too many pushbacks\n");
141 }
142
143 pushback[have_pushback] = c;
144 have_pushback ++;
145 }
146
147
148 int
149 yywrap()
150 { return 1; }
151 /*VARARGS*/
152
153 void
154 allprint(x)
155 int x;
156 {
157 fprintf(yyout,"%d",x);
158 }
159
160 void
161 sprint(x)
162 char *x;
163 {
164 fprintf(yyout,"%s",x);
165 }
166
167 int thischar;
168
169 void parse_line(arg)
170 char *arg;
171 {
172 command_line = arg;
173 have_pushback = 0;
174 yyparse();
175 }
176
177
178
179 void
180 parse_args(ac, av)
181 int ac;
182 char **av;
183 {
184 char *p;
185 int i;
186 size_t size = 0;
187 char *dst;
188 debug = 1;
189 for (i= 1; i < ac; i++) {
190 size += strlen(av[i]) + 2;
191 }
192 dst = p = (char *)ldmalloc(size + 2);
193 /* Put a space arount each option */
194
195
196 for (i =1; i < ac; i++) {
197
198 unsigned int s = strlen(av[i]);
199 *dst++ = ' ';
200 memcpy(dst, av[i], s);
201 dst[s] = ' ';
202 dst += s + 1;
203 }
204 *dst = 0;
205 parse_line(p);
206
207 free(p);
208
209
210 }
211
212 long number(text, base)
213 char *text;
214 int base;
215 {
216 unsigned long l = 0;
217 char *p;
218 for (p = text; *p != 0; p++) {
219 if (*p == 'K') {
220 l =l * 1024;
221 }
222 else if(*p== 'M') {
223 l =l * 1024 * 1024;
224 }
225 else {
226 l =l * base;
227 if (isdigit(*p)) {
228 l += *p - '0';
229 }
230 else if (islower(*p)) {
231 l += *p - 'a' + 10;
232 }
233 else {
234 l += *p - 'A' + 10;
235 }
236 }
237 }
238 return l;
239 }
240 %}
241
242 %a 4000
243 %o 5000
244 FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+]
245 FILENAME {FILENAMECHAR}+
246
247
248 WHITE [ \t]+
249
250 %%
251
252
253 "\ -defsym" { return OPTION_defsym; }
254 "\ -noinhibit_exec" { return OPTION_noinhibit_exec; }
255 "\ -format" { return OPTION_format; }
256 "\ -n" { return OPTION_n; }
257 "\ -r" { return OPTION_r; }
258 "\ -Ur" { return OPTION_Ur; }
259 "\ -o" { return OPTION_o; }
260 "\ -g" { return OPTION_g; }
261 "\ -e" { return OPTION_e; }
262 "\ -b" { return OPTION_b; }
263 "\ -dc" { return OPTION_dc; }
264 "\ -dp" { return OPTION_dp; }
265 "\ -d" { return OPTION_d; }
266 "\ -v" { return OPTION_v; }
267 "\ -M" { return OPTION_M; }
268 "\ -t" { return OPTION_t; }
269 "\ -X" { return OPTION_X; }
270 "\ -x" { return OPTION_x; }
271 "\ -c" { return OPTION_c; }
272 "\ -s" { return OPTION_s; }
273 "\ -S" { return OPTION_S; }
274 "\ -l"{FILENAME} {
275 yylval.name = buystring(yytext+3);
276 return OPTION_l;
277 }
278
279 "\ -L"{FILENAME} {
280 yylval.name = buystring(yytext+3);
281 return OPTION_L;
282 }
283 "\ -Ttext" {
284 yylval.name = ".text";
285 return OPTION_Texp;
286 }
287 "\ -Tdata" {
288 yylval.name = ".data";
289 return OPTION_Texp;
290 }
291 "\ -Tbss" {
292 yylval.name = ".bss";
293 return OPTION_Texp;
294 }
295
296 "\ -T"{FILENAME} {
297 yylval.name = buystring(yytext+3);
298 return OPTION_Tfile;
299 }
300 "\ -T" {
301 return OPTION_T;
302 }
303
304 "\ -F"{FILENAME} {
305 return OPTION_F;
306 }
307 "\ -F" {
308 return OPTION_F;
309 }
310
311 "\ -A"{FILENAME} {
312 yylval.name = buystring(yytext+3);
313 return OPTION_Aarch;
314 }
315 " " { }
316 "<<=" { RTOKEN(LSHIFTEQ);}
317 ">>=" { RTOKEN(RSHIFTEQ);}
318 "||" { RTOKEN(OROR);}
319 "==" { RTOKEN(EQ);}
320 "!=" { RTOKEN(NE);}
321 ">=" { RTOKEN(GE);}
322 "<=" { RTOKEN(LE);}
323 "<<" { RTOKEN(LSHIFT);}
324 ">>" { RTOKEN(RSHIFT);}
325 "+=" { RTOKEN(PLUSEQ);}
326 "-=" { RTOKEN(MINUSEQ);}
327 "*=" { RTOKEN(MULTEQ);}
328 "/=" { RTOKEN(DIVEQ);}
329 "&=" { RTOKEN(ANDEQ);}
330 "|=" { RTOKEN(OREQ);}
331
332 "&&" { RTOKEN(ANDAND);}
333 ">" { RTOKEN('>');}
334 "," { RTOKEN(',');}
335 "&" { RTOKEN('&');}
336 "|" { RTOKEN('|');}
337 "~" { RTOKEN('~');}
338 "!" { RTOKEN('!');}
339 "?" { RTOKEN('?');}
340 "*" { RTOKEN('*');}
341 "%" { RTOKEN('%');}
342 "<" { RTOKEN('<');}
343 "+" { RTOKEN('+');}
344 ">" { RTOKEN('>');}
345 "}" { RTOKEN('}') ; }
346 "{" { RTOKEN('{'); }
347 ")" { RTOKEN(')');}
348 "(" { RTOKEN('(');}
349 "]" { RTOKEN(']');}
350 "[" { RTOKEN('[');}
351 ":" { RTOKEN(':'); }
352 ";" { RTOKEN(';');}
353 "-" { RTOKEN('-');}
354 "=" { RTOKEN('=');}
355
356
357 "/*" {
358 while (1) {
359 int ch;
360 ch = input();
361 while (ch != '*') {
362 ch = input();
363 }
364
365
366
367 if (input() == '/') {
368 break;
369 }
370 unput(yytext[yyleng-1]);
371 }
372 }
373
374 "\""[^\"]*"\"" {
375
376 yylval.name = buystring(yytext+1);
377 yylval.name[yyleng-2] = 0; /* Fry final quote */
378 return NAME;
379 }
380 [0][0-7KM]* {
381
382 yylval.integer = number(yytext+1, 8);
383 return INT;
384 }
385
386 [0-9]+[KM]? {
387 if (hex_mode == true) {
388 yylval.integer = number(yytext, 16);
389 }
390 else {
391 yylval.integer = number(yytext, 10);
392 }
393 return INT;
394 }
395
396 0[Xx][0-9a-fA-FKM]+ {
397
398 yylval.integer = number(yytext+2,16);
399 return INT;
400 }
401
402 "\#"{WHITE}*{FILENAMECHAR}+ {
403 char *p = yytext+1;
404 while(*p ==' ' || *p == '\t') p++;
405 yylval.name = buystring(p);
406 return NAME;
407 }
408 {FILENAMECHAR} {
409
410 boolean loop = false;
411 /*
412 Tokenize a name, this is really pain, since a name can be a
413 filename or a symbol name. filenames have slashes and stuff whist
414 in an expression those things are seperate tokens. We hack this by
415 setting lang_in_expression when we are expecting a symbol, so that
416 [/+-] get taken to be seperate tokens. An extra gotcha is
417 expressions after defsyms, we only allow +s and -s in a defsym
418 expression, so -defsym foo=bar+9 /file.o is parsed ok.
419
420 */
421 int ch;
422 keyword_type *k;
423 if (ldgram_in_expression) {
424 if (yytext[0] != '/' || ldgram_in_defsym == false) {
425 switch (yytext[0]) {
426 case '/': RTOKEN('/');
427 case '+': RTOKEN('+');
428 case '-': RTOKEN('-');
429 }
430 }
431 }
432
433 ch = input();
434 while (true)
435 {
436 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_') {
437 yytext[yyleng++] = ch;
438 }
439 else if (ch == '+' || ch == '-' || ch == '/') {
440 if (ldgram_in_expression) break;
441 yytext[yyleng++] = ch;
442 }
443 else
444 break;
445 ch = input();
446 }
447
448 yytext[yyleng] = 0;
449 unput(ch);
450
451 for(k = keywords; k ->name != (char *)NULL; k++) {
452
453 if (strcmp(k->name, yytext)==0) {
454 yylval.token = k->value;
455 return k->value;
456 }
457 }
458 yylval.name = buystring(yytext);
459 return NAME;
460 }
461
462
463
464
465
466 %%
This page took 0.039028 seconds and 4 git commands to generate.