OSDN Git Service

* config/darwin.c (indirect_data): Fix typo in strncmp logic.
[pf3gnuchains/gcc-fork.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 }