OSDN Git Service

* gengtype-lex.l: Remove rules for parsing pointer-to-function
[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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, 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 const char *push_macro_expansion (const char *, unsigned,
37                                          const char *, unsigned);
38 static char *mangle_macro_name (const char *, unsigned,
39                                 const char *, unsigned);
40 static void update_lineno (const char *l, size_t len);
41
42 struct fileloc lexer_line;
43 int lexer_toplevel_done;
44
45 static void 
46 update_lineno (const char *l, size_t len)
47 {
48   while (len-- > 0)
49     if (*l++ == '\n')
50       lexer_line.line++;
51 }
52
53 %}
54
55 ID      [[:alpha:]_][[:alnum:]_]*
56 WS      [[:space:]]+
57 IWORD   short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD
58 ITYPE   {IWORD}({WS}{IWORD})*
59
60 %x in_struct in_struct_comment in_comment
61 %option warn noyywrap nounput nodefault perf-report
62 %option 8bit never-interactive
63 %%
64
65 [^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" {
66   char *tagstart;
67   size_t taglen;
68   char *namestart;
69   size_t namelen;
70   int is_pointer = 0;
71   struct type *t;
72   int union_p;
73
74   tagstart = yytext + strlen (" typedef ");
75   while (ISSPACE (*tagstart))
76     tagstart++;
77   union_p = tagstart[0] == 'u';
78   tagstart += strlen ("union ");
79   while (ISSPACE (*tagstart))
80     tagstart++;
81   for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
82     ;
83   for (namestart = tagstart + taglen; 
84        ! ISIDNUM (*namestart);
85        namestart++)
86     if (*namestart == '*')
87       is_pointer = 1;
88   for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++)
89     ;
90   t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1),
91                       union_p);
92   if (is_pointer)
93     t = create_pointer (t);
94   namestart = (char *) xmemdup (namestart, namelen, namelen+1);
95 #ifdef USE_MAPPED_LOCATION
96   /* temporary kludge - gentype doesn't handle cpp conditionals */
97   if (strcmp (namestart, "location_t") != 0
98       && strcmp (namestart, "expanded_location") != 0)
99 #endif
100   do_typedef (namestart, t, &lexer_line);
101   update_lineno (yytext, yyleng);
102 }
103
104 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
105
106   char *namestart;
107   size_t namelen;
108   struct type *t;
109   char *typestart;
110   size_t typelen;
111
112   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
113     ;
114   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
115     ;
116   namestart -= namelen - 1;
117   for (typestart = yytext + strlen (" typedef "); 
118        ISSPACE(*typestart);
119        typestart++)
120     ;
121   for (typelen = namestart - typestart;
122        ISSPACE (typestart[typelen-1]);
123        typelen--)
124     ;
125
126   t = create_scalar_type (typestart, typelen);
127   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
128               &lexer_line);
129   update_lineno (yytext, yyleng);
130 }
131
132 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
133   char *namestart;
134   size_t namelen;
135   struct type *t;
136
137   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
138     ;
139   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
140     ;
141   namestart -= namelen - 1;
142
143   t = create_scalar_type ("function type", sizeof ("function type")-1);
144   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
145               &lexer_line);
146   update_lineno (yytext, yyleng);
147 }
148
149 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
150   char *namestart;
151   size_t namelen;
152   struct type *t;
153
154   for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
155     ;
156   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
157     ;
158   namestart -= namelen - 1;
159
160   t = create_scalar_type ("function type", sizeof ("function type")-1);
161   do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), t,
162               &lexer_line);
163   update_lineno (yytext, yyleng);
164 }
165
166 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
167   char *tagstart;
168   size_t taglen;
169   int typedef_p;
170   int union_p;
171
172   typedef_p = yytext[1] == 't';
173   if (typedef_p)
174     for (tagstart = yytext + strlen (" typedef "); 
175          ISSPACE(*tagstart);
176          tagstart++)
177       ;
178   else
179     tagstart = yytext + 1;
180
181   union_p = tagstart[0] == 'u';
182   tagstart += strlen ("union ");
183   while (ISSPACE (*tagstart))
184     tagstart++;
185   for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
186     ;
187
188   yylval.t = find_structure ((const char *) xmemdup (tagstart, taglen,
189                                                      taglen + 1),
190                              union_p);
191   BEGIN(in_struct);
192   update_lineno (yytext, yyleng);
193   return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
194 }
195
196 [^[:alnum:]_](extern|static){WS}/"GTY" {
197   BEGIN(in_struct);
198   update_lineno (yytext, yyleng);
199   return ENT_EXTERNSTATIC;
200 }
201
202 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
203   char *macro, *arg;
204   unsigned macro_len, arg_len;
205   char *ptr = yytext;
206   const char *additional;
207   type_p t;
208
209   /* Find the macro name.  */
210   for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
211     continue;
212   for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++)
213     continue;
214
215   /* Find the argument(s).  */
216   for (arg = ptr; *ptr != ')'; ptr++)
217     continue;
218   arg_len = ptr - arg;
219
220   /* Create the struct and typedef.  */
221   ptr = mangle_macro_name ("VEC", 3, arg, arg_len);
222
223   t = find_structure (ptr, 0);
224   do_typedef (ptr, t, &lexer_line);
225
226   /* Push the macro for later expansion.  */
227   additional = push_macro_expansion (macro, macro_len, arg, arg_len);
228
229   if (additional)
230     {
231       ptr = mangle_macro_name (ptr, strlen (ptr),
232                                additional, strlen (additional));
233       t = find_structure (ptr, 0);
234       do_typedef (ptr, t, &lexer_line);
235     }
236 }
237
238 <in_struct>{
239
240 "/*"                            { BEGIN(in_struct_comment); }
241
242 {WS}                            { update_lineno (yytext, yyleng); }
243
244 "const"/[^[:alnum:]_]           /* don't care */
245 "GTY"/[^[:alnum:]_]             { return GTY_TOKEN; }
246 "union"/[^[:alnum:]_]           { return UNION; }
247 "struct"/[^[:alnum:]_]          { return STRUCT; }
248 "enum"/[^[:alnum:]_]            { return ENUM; }
249 "ptr_alias"/[^[:alnum:]_]       { return ALIAS; }
250 "nested_ptr"/[^[:alnum:]_]      { return NESTED_PTR; }
251 [0-9]+                          { return NUM; }
252 "param"[0-9]*"_is"/[^[:alnum:]_]                {
253   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
254   return PARAM_IS;
255 }
256
257 {IWORD}({WS}{IWORD})*/[^[:alnum:]_]             |
258 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")"        {
259   size_t len;
260
261   for (len = yyleng; ISSPACE (yytext[len-1]); len--)
262     ;
263
264   yylval.t = create_scalar_type (yytext, len);
265   update_lineno (yytext, yyleng);
266   return SCALAR;
267 }
268
269 "VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
270   char *macro, *arg;
271   unsigned macro_len, arg_len;
272   char *ptr = yytext;
273
274   /* Find the macro name */
275   for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
276     continue;
277   for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++)
278     continue;
279
280   /* Find the arguments.  */
281   for (arg = ptr; *ptr != ')'; ptr++)
282     continue;
283   arg_len = ptr - arg;
284
285   ptr = mangle_macro_name (macro, macro_len, arg, arg_len);
286   yylval.s = ptr;
287   return ID;
288 }
289
290 {ID}/[^[:alnum:]_]              {
291   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
292   return ID;
293 }
294
295 \"([^"\\]|\\.)*\"               {
296   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
297   return STRING;
298 }
299 "["[^\[\]]*"]"                  {
300   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
301   return ARRAY;
302 }
303 "'"("\\".|[^\\])"'"             {
304   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
305   return CHAR;
306 }
307
308 [(){},*:<>]                     { return yytext[0]; }
309
310 [;=]                            {
311   if (lexer_toplevel_done)
312     {
313       BEGIN(INITIAL);
314       lexer_toplevel_done = 0;
315     }
316   return yytext[0];
317 }
318
319 "#define"[^\n]*\n               {lexer_line.line++;}
320
321 .                               {
322   error_at_line (&lexer_line, "unexpected character `%s'", yytext);
323 }
324 }
325
326 "/*"                    { BEGIN(in_comment); }
327 \n                      { lexer_line.line++; }
328 {ID}                    |
329 "'"("\\".|[^\\])"'"     |
330 [^"/\n]                 /* do nothing */
331 \"([^"\\]|\\.|\\\n)*\"  { update_lineno (yytext, yyleng); }
332 "/"/[^*]                /* do nothing */
333
334 <in_comment,in_struct_comment>{
335 \n              { lexer_line.line++; }
336 [^*\n]{16}      |
337 [^*\n]          /* do nothing */
338 "*"/[^/]        /* do nothing */
339 }
340 <in_comment>"*/"        { BEGIN(INITIAL); } 
341 <in_struct_comment>"*/" { BEGIN(in_struct); }
342
343 ["/]                    |
344 <in_struct_comment,in_comment>"*"       {
345   error_at_line (&lexer_line, 
346                  "unterminated comment or string; unexpected EOF");
347 }
348
349 ^"#define"{WS}"GTY(" /* do nothing */
350 {WS}"GTY"{WS}?"("       {
351   error_at_line (&lexer_line, "stray GTY marker");
352 }
353
354 %%
355
356 /* Deal with the expansion caused by the DEF_VEC_x macros.  */
357
358 /* Mangle a macro and argument list as done by cpp concatenation in
359    the compiler proper.  */
360 static char *
361 mangle_macro_name (const char *macro, unsigned macro_len,
362                    const char *arg, unsigned arg_len)
363 {
364   char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
365
366   /* Now copy and concatenate each argument */
367   while (arg_len)
368     {
369       ptr[macro_len++] = '_';
370       for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--)
371         ptr[macro_len++] = *arg++;
372       for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--)
373         arg++;
374     }
375   ptr[macro_len] = 0;
376
377   return ptr;
378 }
379
380 typedef struct macro_def
381 {
382   const char *name;
383   const char *expansion;
384   const char *additional;
385 } macro_def_t;
386
387 typedef struct macro
388 {
389   const macro_def_t *def;
390   struct macro *next;
391   const char *args[10];
392 } macro_t;
393
394 static const macro_def_t macro_defs[] = 
395 {
396 #define IN_GENGTYPE 1
397 #include "vec.h"
398   {NULL, NULL, NULL}
399 };
400
401 /* Chain of macro expansions to do at end of scanning.  */
402 static macro_t *macro_expns;
403 static macro_t *macro_expns_end;
404
405 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
406    expansion queue.  We ensure NAME is known at this point.  */
407
408 static const char *
409 push_macro_expansion (const char *name, unsigned name_len,
410                       const char *arg, unsigned arg_len)
411 {
412   unsigned ix;
413
414   for (ix = 0; macro_defs[ix].name; ix++)
415     if (strlen (macro_defs[ix].name) == name_len
416         && !memcmp (name, macro_defs[ix].name, name_len))
417       {
418         macro_t *expansion = XNEW (macro_t);
419         char *args;
420         unsigned argno, last_arg;
421
422         expansion->def = &macro_defs[ix];
423         expansion->next = NULL;
424         args = (char *) xmemdup (arg, arg_len, arg_len+1);
425         args[arg_len] = 0;
426         for (argno = 0; *args;)
427           {
428             expansion->args[argno++] = args;
429             while (*args && (ISALNUM (*args) || *args == '_'))
430               args++;
431             if (argno == 1)
432               expansion->args[argno++] = "base";
433             if (!*args)
434               break;
435             *args++ = 0;
436             while (*args && !(ISALNUM (*args) || *args == '_'))
437               args++;
438           }
439         last_arg = argno;
440         for (; argno != 10; argno++)
441           expansion->args[argno] = NULL;
442         if (macro_expns_end)
443           macro_expns_end->next = expansion;
444         else
445           macro_expns = expansion;
446         macro_expns_end = expansion;
447         if (macro_defs[ix].additional)
448           {
449             macro_t *expn2 = XNEW (macro_t);
450             memcpy (expn2, expansion, sizeof (*expn2));
451             expansion = expn2;
452             expansion->def += 1;
453             expansion->args[last_arg++] = macro_defs[ix].additional;
454             macro_expns_end->next = expansion;
455             macro_expns_end = expansion;
456           }
457         if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap"))
458           expansion->args[last_arg++] = "GTY (())";
459         return macro_defs[ix].additional;
460       }
461   error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
462                  name_len, name, arg_len, arg);
463   return NULL;
464 }
465
466 /* Attempt to read some input.  Use fread until we're at the end of
467    file.  At end of file expand the next queued macro.  We presume the
468    buffer is large enough for the entire expansion.  */
469
470 static unsigned
471 macro_input (char *buffer, unsigned size)
472 {
473   unsigned result;
474
475   result = fread (buffer, 1, size, yyin);
476   if (result)
477     /*NOP*/;
478   else if (ferror (yyin))
479     YY_FATAL_ERROR ("read of source file failed");
480   else if (macro_expns)
481     {
482       const char *expn;
483       unsigned len;
484
485       for (expn = macro_expns->def->expansion; *expn; expn++)
486         {
487           if (*expn == '#')
488             {
489               int argno;
490
491               argno = expn[1] - '0';
492               expn += 1;
493
494               /* Remove inserted space? */
495               if (buffer[result-1] == ' ' && buffer[result-2] == '_')
496                 result--;
497
498               /* Insert the argument value */
499               if (macro_expns->args[argno])
500                 {
501                   len = strlen (macro_expns->args[argno]);
502                   memcpy (&buffer[result], macro_expns->args[argno], len);
503                   result += len;
504                 }
505
506               /* Skip next space? */
507               if (expn[1] == ' ' && expn[2] == '_')
508                 expn++;
509             }
510           else
511             {
512               buffer[result++] = *expn;
513               if (*expn == ';' || *expn == '{')
514                 buffer[result++] = '\n';
515             }
516         }
517       if (result > size)
518         YY_FATAL_ERROR ("buffer too small to expand macro");
519       macro_expns = macro_expns->next;
520       if (!macro_expns)
521         macro_expns_end = NULL;
522     }
523   return result;
524 }
525
526 void
527 yyerror (const char *s)
528 {
529   error_at_line (&lexer_line, s);
530 }
531
532 void
533 parse_file (const char *fname)
534 {
535   yyin = fopen (fname, "r");
536   lexer_line.file = fname;
537   lexer_line.line = 1;
538   if (yyin == NULL)
539     {
540       perror (fname);
541       exit (1);
542     }
543   if (yyparse() != 0)
544     exit (1);
545   fclose (yyin);
546 }