2005-04-05 Andrew MacLeod <amacleod@redhat.com>
[official-gcc.git] / gcc / gengtype-lex.l
blob096af89a8e3167bfb50e3b551ecf027f5753ed87
1 /* -*- indented-text -*- */
2 /* Process source files and output type information.
3    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GCC.
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.
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.
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.  */
23 #include "bconfig.h"
24 #include "coretypes.h"
25 #include "system.h"
27 #define malloc xmalloc
28 #define realloc xrealloc
30 #include "gengtype.h"
31 #include "gengtype-yacc.h"
33 #define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE))
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);
40 struct fileloc lexer_line;
41 int lexer_toplevel_done;
43 static void 
44 update_lineno (const char *l, size_t len)
46   while (len-- > 0)
47     if (*l++ == '\n')
48       lexer_line.line++;
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})*
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
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;
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);
102 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
104   char *namestart;
105   size_t namelen;
106   struct type *t;
107   char *typestart;
108   size_t typelen;
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     ;
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);
130 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
131   char *namestart;
132   size_t namelen;
133   struct type *t;
135   for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
136     ;
137   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
138     ;
139   namestart -= namelen - 1;
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);
147 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
148   char *namestart;
149   size_t namelen;
150   struct type *t;
152   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
153     ;
154   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
155     ;
156   namestart -= namelen - 1;
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);
164 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
165   char *namestart;
166   size_t namelen;
167   struct type *t;
169   for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
170     ;
171   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
172     ;
173   namestart -= namelen - 1;
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);
181 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
182   char *namestart;
183   size_t namelen;
184   struct type *t;
186   for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
187     ;
188   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
189     ;
190   namestart -= namelen - 1;
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);
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;
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;
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     ;
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;
228 [^[:alnum:]_](extern|static){WS}/"GTY" {
229   BEGIN(in_struct);
230   update_lineno (yytext, yyleng);
231   return ENT_EXTERNSTATIC;
234 ^"%union"{WS}"{"{WS}/"GTY" {
235   BEGIN(in_struct);
236   update_lineno (yytext, yyleng);
237   return ENT_YACCUNION;
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;
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;
258   /* Push the macro for later expansion.  */
259   push_macro_expansion (macro, macro_len, arg, arg_len);
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);
269 <in_struct>{
271 "/*"                            { BEGIN(in_struct_comment); }
273 ^"%{"                           { BEGIN(in_yacc_escape); } /* } */
275 {WS}                            { update_lineno (yytext, yyleng); }
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;
290 {IWORD}({WS}{IWORD})*/[^[:alnum:]_]             |
291 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")"        {
292   size_t len;
294   for (len = yyleng; ISSPACE (yytext[len-1]); len--)
295     ;
297   yylval.t = create_scalar_type (yytext, len);
298   update_lineno (yytext, yyleng);
299   return SCALAR;
302 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
303   char *macro, *arg;
304   unsigned macro_len, arg_len;
305   char *ptr = yytext;
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;
324 {ID}/[^[:alnum:]_]              {
325   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
326   return ID;
329 \"([^"\\]|\\.)*\"               {
330   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
331   return STRING;
333 "["[^\[\]]*"]"                  {
334   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
335   return ARRAY;
337 ^"%"{ID}                        {
338   yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
339   return PERCENT_ID;
341 "'"("\\".|[^\\])"'"             {
342   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
343   return CHAR;
346 [(){},*:<>]                     { return yytext[0]; }
348 [;=]                            {
349   if (lexer_toplevel_done)
350     {
351       BEGIN(INITIAL);
352       lexer_toplevel_done = 0;
353     }
354   return yytext[0];
357 ^"%%"                           {
358   BEGIN(INITIAL);
359   return PERCENTPERCENT;
362 "#define"[^\n]*\n               {lexer_line.line++;}
364 .                               {
365   error_at_line (&lexer_line, "unexpected character `%s'", yytext);
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 */
377 <in_comment,in_struct_comment>{
378 \n              { lexer_line.line++; }
379 [^*\n]{16}      |
380 [^*\n]          /* do nothing */
381 "*"/[^/]        /* do nothing */
383 <in_comment>"*/"        { BEGIN(INITIAL); } 
384 <in_struct_comment>"*/" { BEGIN(in_struct); }
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");
399 ["/]                    |
400 <in_struct_comment,in_comment>"*"       {
401   error_at_line (&lexer_line, 
402                  "unterminated comment or string; unexpected EOF");
405 ^"#define"{WS}"GTY(" /* do nothing */
406 {WS}"GTY"{WS}?"("       {
407   error_at_line (&lexer_line, "stray GTY marker");
412 /* Deal with the expansion caused by the DEF_VEC_x macros.  */
414 typedef struct macro
416   const char *name;
417   const char *expansion;
418   struct macro *next;
419 } macro_t;
421 static const macro_t macro_defs[] = 
423 #define IN_GENGTYPE 1
424 #include "vec.h"
425   {NULL, NULL, NULL}
428 /* Chain of macro expansions to do at end of scanning.  */
429 static macro_t *macro_expns;
431 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
432    expansion queue.  We ensure NAME is known at this point.  */
434 static void
435 push_macro_expansion (const char *name, unsigned name_len,
436                       const char *arg, unsigned arg_len)
438   unsigned ix;
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);
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);
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.  */
460 static unsigned
461 macro_input (char *buffer, unsigned size)
463   unsigned result;
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;
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;
499 void
500 yyerror (const char *s)
502   error_at_line (&lexer_line, s);
505 void
506 parse_file (const char *fname)
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);