real.h (struct real_format): Split the signbit field into two two fields, signbit_ro...
[gcc.git] / gcc / gengtype-lex.l
1 /* -*- indented-text -*- */
2 /* Process source files and output type information.
3 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22 %{
23 #include "bconfig.h"
24 #include "coretypes.h"
25 #include "system.h"
26
27 #define malloc xmalloc
28 #define realloc xrealloc
29
30 #include "gengtype.h"
31 #include "gengtype-yacc.h"
32
33 #define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE))
34
35 static unsigned macro_input (char *buffer, unsigned);
36 static void push_macro_expansion (const char *, unsigned,
37 const char *, unsigned);
38 static void update_lineno (const char *l, size_t len);
39
40 struct fileloc lexer_line;
41 int lexer_toplevel_done;
42
43 static void
44 update_lineno (const char *l, size_t len)
45 {
46 while (len-- > 0)
47 if (*l++ == '\n')
48 lexer_line.line++;
49 }
50
51 %}
52
53 ID [[:alpha:]_][[:alnum:]_]*
54 WS [[:space:]]+
55 IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD
56 ITYPE {IWORD}({WS}{IWORD})*
57
58 %x in_struct in_struct_comment in_comment in_yacc_escape
59 %option warn noyywrap nounput nodefault perf-report
60 %option 8bit never-interactive
61 %%
62
63 [^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" {
64 char *tagstart;
65 size_t taglen;
66 char *namestart;
67 size_t namelen;
68 int is_pointer = 0;
69 struct type *t;
70 int union_p;
71
72 tagstart = yytext + strlen (" typedef ");
73 while (ISSPACE (*tagstart))
74 tagstart++;
75 union_p = tagstart[0] == 'u';
76 tagstart += strlen ("union ");
77 while (ISSPACE (*tagstart))
78 tagstart++;
79 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
80 ;
81 for (namestart = tagstart + taglen;
82 ! ISIDNUM (*namestart);
83 namestart++)
84 if (*namestart == '*')
85 is_pointer = 1;
86 for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++)
87 ;
88 t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1),
89 union_p);
90 if (is_pointer)
91 t = create_pointer (t);
92 namestart = (char *) xmemdup (namestart, namelen, namelen+1);
93 #ifdef USE_MAPPED_LOCATION
94 /* temporary kludge - gentype doesn't handle cpp conditionals */
95 if (strcmp (namestart, "location_t") != 0
96 && strcmp (namestart, "expanded_location") != 0)
97 #endif
98 do_typedef (namestart, t, &lexer_line);
99 update_lineno (yytext, yyleng);
100 }
101
102 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
103
104 char *namestart;
105 size_t namelen;
106 struct type *t;
107 char *typestart;
108 size_t typelen;
109
110 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
111 ;
112 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
113 ;
114 namestart -= namelen - 1;
115 for (typestart = yytext + strlen (" typedef ");
116 ISSPACE(*typestart);
117 typestart++)
118 ;
119 for (typelen = namestart - typestart;
120 ISSPACE (typestart[typelen-1]);
121 typelen--)
122 ;
123
124 t = create_scalar_type (typestart, typelen);
125 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
126 &lexer_line);
127 update_lineno (yytext, yyleng);
128 }
129
130 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
131 char *namestart;
132 size_t namelen;
133 struct type *t;
134
135 for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
136 ;
137 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
138 ;
139 namestart -= namelen - 1;
140
141 t = create_scalar_type ("function type", sizeof ("function type")-1);
142 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
143 &lexer_line);
144 update_lineno (yytext, yyleng);
145 }
146
147 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
148 char *namestart;
149 size_t namelen;
150 struct type *t;
151
152 for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
153 ;
154 for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
155 ;
156 namestart -= namelen - 1;
157
158 t = create_scalar_type ("function type", sizeof ("function type")-1);
159 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
160 &lexer_line);
161 update_lineno (yytext, yyleng);
162 }
163
164 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
165 char *namestart;
166 size_t namelen;
167 struct type *t;
168
169 for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
170 ;
171 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
172 ;
173 namestart -= namelen - 1;
174
175 t = create_scalar_type ("function type", sizeof ("function type")-1);
176 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
177 &lexer_line);
178 update_lineno (yytext, yyleng);
179 }
180
181 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
182 char *namestart;
183 size_t namelen;
184 struct type *t;
185
186 for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
187 ;
188 for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
189 ;
190 namestart -= namelen - 1;
191
192 t = create_scalar_type ("function type", sizeof ("function type")-1);
193 do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
194 &lexer_line);
195 update_lineno (yytext, yyleng);
196 }
197
198 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
199 char *tagstart;
200 size_t taglen;
201 int typedef_p;
202 int union_p;
203
204 typedef_p = yytext[1] == 't';
205 if (typedef_p)
206 for (tagstart = yytext + strlen (" typedef ");
207 ISSPACE(*tagstart);
208 tagstart++)
209 ;
210 else
211 tagstart = yytext + 1;
212
213 union_p = tagstart[0] == 'u';
214 tagstart += strlen ("union ");
215 while (ISSPACE (*tagstart))
216 tagstart++;
217 for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
218 ;
219
220 yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen,
221 taglen + 1),
222 union_p);
223 BEGIN(in_struct);
224 update_lineno (yytext, yyleng);
225 return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
226 }
227
228 [^[:alnum:]_](extern|static){WS}/"GTY" {
229 BEGIN(in_struct);
230 update_lineno (yytext, yyleng);
231 return ENT_EXTERNSTATIC;
232 }
233
234 ^"%union"{WS}"{"{WS}/"GTY" {
235 BEGIN(in_struct);
236 update_lineno (yytext, yyleng);
237 return ENT_YACCUNION;
238 }
239
240 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
241 char *macro, *arg;
242 unsigned macro_len, arg_len;
243 char *ptr = yytext;
244 type_p t;
245
246 /* Locate the macro and argument strings. */
247 macro = ptr;
248 while (*ptr != '(' && !ISSPACE (*ptr))
249 ptr++;
250 macro_len = ptr - macro;
251 while (*ptr == '(' || ISSPACE (*ptr))
252 ptr++;
253 arg = ptr;
254 while (*ptr != ')' && !ISSPACE (*ptr))
255 ptr++;
256 arg_len = ptr - arg;
257
258 /* Push the macro for later expansion. */
259 push_macro_expansion (macro, macro_len, arg, arg_len);
260
261 /* Create the struct and typedef. */
262 ptr = (char *) xmemdup ("VEC_", 4, 4 + arg_len + 1);
263 memcpy (&ptr[4], arg, arg_len);
264 ptr[4 + arg_len] = 0;
265 t = find_structure (ptr, 0);
266 do_typedef (ptr, t, &lexer_line);
267 }
268
269 <in_struct>{
270
271 "/*" { BEGIN(in_struct_comment); }
272
273 ^"%{" { BEGIN(in_yacc_escape); } /* } */
274
275 {WS} { update_lineno (yytext, yyleng); }
276
277 "const"/[^[:alnum:]_] /* don't care */
278 "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
279 "union"/[^[:alnum:]_] { return UNION; }
280 "struct"/[^[:alnum:]_] { return STRUCT; }
281 "enum"/[^[:alnum:]_] { return ENUM; }
282 "ptr_alias"/[^[:alnum:]_] { return ALIAS; }
283 "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; }
284 [0-9]+ { return NUM; }
285 "param"[0-9]*"_is"/[^[:alnum:]_] {
286 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
287 return PARAM_IS;
288 }
289
290 {IWORD}({WS}{IWORD})*/[^[:alnum:]_] |
291 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" {
292 size_t len;
293
294 for (len = yyleng; ISSPACE (yytext[len-1]); len--)
295 ;
296
297 yylval.t = create_scalar_type (yytext, len);
298 update_lineno (yytext, yyleng);
299 return SCALAR;
300 }
301
302 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
303 char *macro, *arg;
304 unsigned macro_len, arg_len;
305 char *ptr = yytext;
306
307 macro = ptr;
308 while (*ptr != '(' && !ISSPACE (*ptr)) /* )*/
309 ptr++;
310 macro_len = ptr - macro;
311 while (*ptr == '(' || ISSPACE (*ptr))
312 ptr++;
313 arg = ptr;
314 while (*ptr != ')' && !ISSPACE (*ptr))
315 ptr++;
316 arg_len = ptr - arg;
317 ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
318 ptr[macro_len] = '_';
319 memcpy (&ptr[macro_len+1], arg, arg_len);
320 yylval.s = ptr;
321 return ID;
322 }
323
324 {ID}/[^[:alnum:]_] {
325 yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
326 return ID;
327 }
328
329 \"([^"\\]|\\.)*\" {
330 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
331 return STRING;
332 }
333 "["[^\[\]]*"]" {
334 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
335 return ARRAY;
336 }
337 ^"%"{ID} {
338 yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
339 return PERCENT_ID;
340 }
341 "'"("\\".|[^\\])"'" {
342 yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
343 return CHAR;
344 }
345
346 [(){},*:<>] { return yytext[0]; }
347
348 [;=] {
349 if (lexer_toplevel_done)
350 {
351 BEGIN(INITIAL);
352 lexer_toplevel_done = 0;
353 }
354 return yytext[0];
355 }
356
357 ^"%%" {
358 BEGIN(INITIAL);
359 return PERCENTPERCENT;
360 }
361
362 "#define"[^\n]*\n {lexer_line.line++;}
363
364 . {
365 error_at_line (&lexer_line, "unexpected character `%s'", yytext);
366 }
367 }
368
369 "/*" { BEGIN(in_comment); }
370 \n { lexer_line.line++; }
371 {ID} |
372 "'"("\\".|[^\\])"'" |
373 [^"/\n] /* do nothing */
374 \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
375 "/"/[^*] /* do nothing */
376
377 <in_comment,in_struct_comment>{
378 \n { lexer_line.line++; }
379 [^*\n]{16} |
380 [^*\n] /* do nothing */
381 "*"/[^/] /* do nothing */
382 }
383 <in_comment>"*/" { BEGIN(INITIAL); }
384 <in_struct_comment>"*/" { BEGIN(in_struct); }
385
386 <in_yacc_escape>{
387 \n { lexer_line.line++; }
388 [^%]{16} |
389 [^%] /* do nothing */
390 "%"/[^}] /* do nothing */
391 "%}" { BEGIN(in_struct); }
392 "%" {
393 error_at_line (&lexer_line,
394 "unterminated %%{; unexpected EOF");
395 }
396 }
397
398
399 ["/] |
400 <in_struct_comment,in_comment>"*" {
401 error_at_line (&lexer_line,
402 "unterminated comment or string; unexpected EOF");
403 }
404
405 ^"#define"{WS}"GTY(" /* do nothing */
406 {WS}"GTY"{WS}?"(" {
407 error_at_line (&lexer_line, "stray GTY marker");
408 }
409
410 %%
411
412 /* Deal with the expansion caused by the DEF_VEC_x macros. */
413
414 typedef struct macro
415 {
416 const char *name;
417 const char *expansion;
418 struct macro *next;
419 } macro_t;
420
421 static const macro_t macro_defs[] =
422 {
423 #define IN_GENGTYPE 1
424 #include "vec.h"
425 {NULL, NULL, NULL}
426 };
427
428 /* Chain of macro expansions to do at end of scanning. */
429 static macro_t *macro_expns;
430
431 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
432 expansion queue. We ensure NAME is known at this point. */
433
434 static void
435 push_macro_expansion (const char *name, unsigned name_len,
436 const char *arg, unsigned arg_len)
437 {
438 unsigned ix;
439
440 for (ix = 0; macro_defs[ix].name; ix++)
441 if (strlen (macro_defs[ix].name) == name_len
442 && !memcmp (name, macro_defs[ix].name, name_len))
443 {
444 macro_t *expansion = XNEW (macro_t);
445
446 expansion->next = macro_expns;
447 expansion->name = (char *) xmemdup (arg, arg_len, arg_len+1);
448 expansion->expansion = macro_defs[ix].expansion;
449 macro_expns = expansion;
450 return;
451 }
452 error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
453 name_len, name, arg_len, arg);
454 }
455
456 /* Attempt to read some input. Use fread until we're at the end of
457 file. At end of file expand the next queued macro. We presume the
458 buffer is large enough for the entire expansion. */
459
460 static unsigned
461 macro_input (char *buffer, unsigned size)
462 {
463 unsigned result;
464
465 result = fread (buffer, 1, size, yyin);
466 if (result)
467 /*NOP*/;
468 else if (ferror (yyin))
469 YY_FATAL_ERROR ("read of source file failed");
470 else if (macro_expns)
471 {
472 const char *expn;
473 unsigned len;
474
475 for (expn = macro_expns->expansion; *expn; expn++)
476 {
477 if (*expn == '#')
478 {
479 if (buffer[result-1] == ' ' && buffer[result-2] == '_')
480 result--;
481 len = strlen (macro_expns->name);
482 memcpy (&buffer[result], macro_expns->name, len);
483 result += len;
484 }
485 else
486 {
487 buffer[result++] = *expn;
488 if (*expn == ';' || *expn == '{')
489 buffer[result++] = '\n';
490 }
491 }
492 if (result > size)
493 YY_FATAL_ERROR ("buffer too small to expand macro");
494 macro_expns = macro_expns->next;
495 }
496 return result;
497 }
498
499 void
500 yyerror (const char *s)
501 {
502 error_at_line (&lexer_line, s);
503 }
504
505 void
506 parse_file (const char *fname)
507 {
508 yyin = fopen (fname, "r");
509 lexer_line.file = fname;
510 lexer_line.line = 1;
511 if (yyin == NULL)
512 {
513 perror (fname);
514 exit (1);
515 }
516 if (yyparse() != 0)
517 exit (1);
518 fclose (yyin);
519 }