Mark ChangeLog
[official-gcc.git] / gcc / gengtype-lex.l
blobe2872eeffa42849de654bd663c292bc32fe0a5d6
1 /* -*- indented-text -*- */
2 /* Process source files and output type information.
3    Copyright (C) 2002, 2003, 2004 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 ^"@@".*                         /* Used for c-parse.in C/ObjC demarcation.  */
277 {WS}                            { update_lineno (yytext, yyleng); }
279 "const"/[^[:alnum:]_]           /* don't care */
280 "GTY"/[^[:alnum:]_]             { return GTY_TOKEN; }
281 "union"/[^[:alnum:]_]           { return UNION; }
282 "struct"/[^[:alnum:]_]          { return STRUCT; }
283 "enum"/[^[:alnum:]_]            { return ENUM; }
284 "ptr_alias"/[^[:alnum:]_]       { return ALIAS; }
285 "nested_ptr"/[^[:alnum:]_]      { return NESTED_PTR; }
286 [0-9]+                          { return NUM; }
287 "param"[0-9]*"_is"/[^[:alnum:]_]                {
288   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
289   return PARAM_IS;
292 {IWORD}({WS}{IWORD})*/[^[:alnum:]_]             |
293 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")"        {
294   size_t len;
296   for (len = yyleng; ISSPACE (yytext[len-1]); len--)
297     ;
299   yylval.t = create_scalar_type (yytext, len);
300   update_lineno (yytext, yyleng);
301   return SCALAR;
304 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
305   char *macro, *arg;
306   unsigned macro_len, arg_len;
307   char *ptr = yytext;
309   macro = ptr;
310   while (*ptr != '(' && !ISSPACE (*ptr)) /* )*/
311     ptr++;
312   macro_len = ptr - macro;
313   while (*ptr == '(' || ISSPACE (*ptr))
314     ptr++;
315   arg = ptr;
316   while (*ptr != ')' && !ISSPACE (*ptr))
317     ptr++;
318   arg_len = ptr - arg;
319   ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
320   ptr[macro_len] = '_';
321   memcpy (&ptr[macro_len+1], arg, arg_len);
322   yylval.s = ptr;
323   return ID;
326 {ID}/[^[:alnum:]_]              {
327   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
328   return ID;
331 \"([^"\\]|\\.)*\"               {
332   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
333   return STRING;
335 "["[^\[\]]*"]"                  {
336   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1);
337   return ARRAY;
339 ^"%"{ID}                        {
340   yylval.s = (const char *) xmemdup (yytext+1, yyleng-1, yyleng);
341   return PERCENT_ID;
343 "'"("\\".|[^\\])"'"             {
344   yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng);
345   return CHAR;
348 [(){},*:<>]                     { return yytext[0]; }
350 [;=]                            {
351   if (lexer_toplevel_done)
352     {
353       BEGIN(INITIAL);
354       lexer_toplevel_done = 0;
355     }
356   return yytext[0];
359 ^"%%"                           {
360   BEGIN(INITIAL);
361   return PERCENTPERCENT;
364 "#define"[^\n]*\n               {lexer_line.line++;}
366 .                               {
367   error_at_line (&lexer_line, "unexpected character `%s'", yytext);
371 "/*"                    { BEGIN(in_comment); }
372 \n                      { lexer_line.line++; }
373 {ID}                    |
374 "'"("\\".|[^\\])"'"     |
375 [^"/\n]                 /* do nothing */
376 \"([^"\\]|\\.|\\\n)*\"  { update_lineno (yytext, yyleng); }
377 "/"/[^*]                /* do nothing */
379 <in_comment,in_struct_comment>{
380 \n              { lexer_line.line++; }
381 [^*\n]{16}      |
382 [^*\n]          /* do nothing */
383 "*"/[^/]        /* do nothing */
385 <in_comment>"*/"        { BEGIN(INITIAL); } 
386 <in_struct_comment>"*/" { BEGIN(in_struct); }
388 <in_yacc_escape>{
389 \n              { lexer_line.line++; }
390 [^%]{16}        |
391 [^%]            /* do nothing */
392 "%"/[^}]        /* do nothing */
393 "%}"            { BEGIN(in_struct); }
394 "%"             {
395   error_at_line (&lexer_line, 
396                  "unterminated %%{; unexpected EOF");
401 ["/]                    |
402 <in_struct_comment,in_comment>"*"       {
403   error_at_line (&lexer_line, 
404                  "unterminated comment or string; unexpected EOF");
407 ^"#define"{WS}"GTY(" /* do nothing */
408 {WS}"GTY"{WS}?"("       {
409   error_at_line (&lexer_line, "stray GTY marker");
414 /* Deal with the expansion caused by the DEF_VEC_x macros.  */
416 typedef struct macro
418   const char *name;
419   const char *expansion;
420   struct macro *next;
421 } macro_t;
423 static const macro_t macro_defs[] = 
425 #define IN_GENGTYPE 1
426 #include "vec.h"
427   {NULL, NULL, NULL}
430 /* Chain of macro expansions to do at end of scanning.  */
431 static macro_t *macro_expns;
433 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
434    expansion queue.  We ensure NAME is known at this point.  */
436 static void
437 push_macro_expansion (const char *name, unsigned name_len,
438                       const char *arg, unsigned arg_len)
440   unsigned ix;
442   for (ix = 0; macro_defs[ix].name; ix++)
443     if (strlen (macro_defs[ix].name) == name_len
444         && !memcmp (name, macro_defs[ix].name, name_len))
445       {
446         macro_t *expansion = XNEW (macro_t);
448         expansion->next = macro_expns;
449         expansion->name = (char *) xmemdup (arg, arg_len, arg_len+1);
450         expansion->expansion = macro_defs[ix].expansion;
451         macro_expns = expansion;
452         return;
453       }
454   error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
455                  name_len, name, arg_len, arg);
458 /* Attempt to read some input.  Use fread until we're at the end of
459    file.  At end of file expand the next queued macro.  We presume the
460    buffer is large enough for the entire expansion.  */
462 static unsigned
463 macro_input (char *buffer, unsigned size)
465   unsigned result;
467   result = fread (buffer, 1, size, yyin);
468   if (result)
469     /*NOP*/;
470   else if (ferror (yyin))
471     YY_FATAL_ERROR ("read of source file failed");
472   else if (macro_expns)
473     {
474       const char *expn;
475       unsigned len;
477       for (expn = macro_expns->expansion; *expn; expn++)
478         {
479           if (*expn == '#')
480             {
481               if (buffer[result-1] == ' ' && buffer[result-2] == '_')
482                 result--;
483               len = strlen (macro_expns->name);
484               memcpy (&buffer[result], macro_expns->name, len);
485               result += len;
486             }
487           else
488             {
489               buffer[result++] = *expn;
490               if (*expn == ';' || *expn == '{')
491                 buffer[result++] = '\n';
492             }
493         }
494       if (result > size)
495         YY_FATAL_ERROR ("buffer too small to expand macro");
496       macro_expns = macro_expns->next;
497     }
498   return result;
501 void
502 yyerror (const char *s)
504   error_at_line (&lexer_line, s);
507 void
508 parse_file (const char *fname)
510   yyin = fopen (fname, "r");
511   lexer_line.file = fname;
512   lexer_line.line = 1;
513   if (yyin == NULL)
514     {
515       perror (fname);
516       exit (1);
517     }
518   if (yyparse() != 0)
519     exit (1);
520   fclose (yyin);