* doc/contrib.texi (Contributors): Add gfortran contributors and
[official-gcc.git] / gcc / gengtype-lex.l
blob22a5cd8ee0fdd988cbe09804600a6e41acbf3d2e
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 (xmemdup (tagstart, taglen, taglen+1), union_p);
89   if (is_pointer)
90     t = create_pointer (t);
91   namestart = xmemdup (namestart, namelen, namelen+1);
92 #ifdef USE_MAPPED_LOCATION
93   /* temporary kludge - gentype doesn't handle cpp conditionals */
94   if (strcmp (namestart, "location_t") != 0)
95 #endif
96   do_typedef (namestart, t, &lexer_line);
97   update_lineno (yytext, yyleng);
100 [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
102   char *namestart;
103   size_t namelen;
104   struct type *t;
105   char *typestart;
106   size_t typelen;
108   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
109     ;
110   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
111     ;
112   namestart -= namelen - 1;
113   for (typestart = yytext + strlen (" typedef "); 
114        ISSPACE(*typestart);
115        typestart++)
116     ;
117   for (typelen = namestart - typestart; 
118        ISSPACE(typestart[typelen-1]); 
119        typelen--)
120     ;
122   t = create_scalar_type (typestart, typelen);
123   do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
124   update_lineno (yytext, yyleng);
127 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
128   char *namestart;
129   size_t namelen;
130   struct type *t;
132   for (namestart = yytext + yyleng - 7; ISSPACE (*namestart); namestart--)
133     ;
134   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
135     ;
136   namestart -= namelen - 1;
138   t = create_scalar_type ("function type", sizeof ("function type")-1);
139   do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
140   update_lineno (yytext, yyleng);
143 [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
144   char *namestart;
145   size_t namelen;
146   struct type *t;
148   for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
149     ;
150   for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
151     ;
152   namestart -= namelen - 1;
154   t = create_scalar_type ("function type", sizeof ("function type")-1);
155   do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
156   update_lineno (yytext, yyleng);
159 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
160   char *namestart;
161   size_t namelen;
162   struct type *t;
164   for (namestart = yytext + yyleng - 7; !ISIDNUM (*namestart); namestart--)
165     ;
166   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
167     ;
168   namestart -= namelen - 1;
170   t = create_scalar_type ("function type", sizeof ("function type")-1);
171   do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
172   update_lineno (yytext, yyleng);
175 [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
176   char *namestart;
177   size_t namelen;
178   struct type *t;
180   for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
181     ;
182   for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
183     ;
184   namestart -= namelen - 1;
186   t = create_scalar_type ("function type", sizeof ("function type")-1);
187   do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
188   update_lineno (yytext, yyleng);
191 [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
192   char *tagstart;
193   size_t taglen;
194   int typedef_p;
195   int union_p;
197   typedef_p = yytext[1] == 't';
198   if (typedef_p)
199     for (tagstart = yytext + strlen (" typedef "); 
200          ISSPACE(*tagstart);
201          tagstart++)
202       ;
203   else
204     tagstart = yytext + 1;
206   union_p = tagstart[0] == 'u';
207   tagstart += strlen ("union ");
208   while (ISSPACE (*tagstart))
209     tagstart++;
210   for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++)
211     ;
213   yylval.t = find_structure (xmemdup (tagstart, taglen, taglen + 1), union_p);
214   BEGIN(in_struct);
215   update_lineno (yytext, yyleng);
216   return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
219 [^[:alnum:]_](extern|static){WS}/"GTY" {
220   BEGIN(in_struct);
221   update_lineno (yytext, yyleng);
222   return ENT_EXTERNSTATIC;
225 ^"%union"{WS}"{"{WS}/"GTY" {
226   BEGIN(in_struct);
227   update_lineno (yytext, yyleng);
228   return ENT_YACCUNION;
231 ^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
232   char *macro, *arg;
233   unsigned macro_len, arg_len;
234   char *ptr = yytext;
235   type_p t;
237   /* Locate the macro and argument strings.  */
238   macro = ptr;
239   while (*ptr != '(' && !ISSPACE (*ptr))
240     ptr++;
241   macro_len = ptr - macro;
242   while (*ptr == '(' || ISSPACE (*ptr))
243     ptr++;
244   arg = ptr;
245   while (*ptr != ')' && !ISSPACE (*ptr))
246     ptr++;
247   arg_len = ptr - arg;
249   /* Push the macro for later expansion.  */
250   push_macro_expansion (macro, macro_len, arg, arg_len);
252   /* Create the struct and typedef.  */
253   ptr = xmemdup ("VEC_", 4, 4 + arg_len + 1);
254   memcpy (&ptr[4], arg, arg_len);
255   ptr[4 + arg_len] = 0;
256   t = find_structure (ptr, 0);
257   do_typedef (ptr, t, &lexer_line);
260 <in_struct>{
262 "/*"                            { BEGIN(in_struct_comment); }
264 ^"%{"                           { BEGIN(in_yacc_escape); }
266 ^"@@".*                         /* Used for c-parse.in C/ObjC demarcation.  */
268 {WS}                            { update_lineno (yytext, yyleng); }
270 "const"/[^[:alnum:]_]           /* don't care */
271 "GTY"/[^[:alnum:]_]             { return GTY_TOKEN; }
272 "union"/[^[:alnum:]_]           { return UNION; }
273 "struct"/[^[:alnum:]_]          { return STRUCT; }
274 "enum"/[^[:alnum:]_]            { return ENUM; }
275 "ptr_alias"/[^[:alnum:]_]       { return ALIAS; }
276 "nested_ptr"/[^[:alnum:]_]      { return NESTED_PTR; }
277 [0-9]+                          { return NUM; }
278 "param"[0-9]*"_is"/[^[:alnum:]_]                { 
279   yylval.s = xmemdup (yytext, yyleng, yyleng+1);
280   return PARAM_IS;
283 {IWORD}({WS}{IWORD})*/[^[:alnum:]_]             |
284 "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")"        {
285   size_t len;
287   for (len = yyleng; ISSPACE (yytext[len-1]); len--)
288     ;
290   yylval.t = create_scalar_type (yytext, len);
291   update_lineno (yytext, yyleng);
292   return SCALAR;
295 "VEC"{WS}?"("{WS}?{ID}{WS}?")" {
296   char *macro, *arg;
297   unsigned macro_len, arg_len;
298   char *ptr = yytext;
300   macro = ptr;
301   while (*ptr != '(' && !ISSPACE (*ptr))
302     ptr++;
303   macro_len = ptr - macro;
304   while (*ptr == '(' || ISSPACE (*ptr))
305     ptr++;
306   arg = ptr;
307   while (*ptr != ')' && !ISSPACE (*ptr))
308     ptr++;
309   arg_len = ptr - arg;
310   ptr = xmemdup (macro, macro_len, macro_len + arg_len + 2);
311   ptr[macro_len] = '_';
312   memcpy (&ptr[macro_len+1], arg, arg_len);
313   yylval.s = ptr;
314   return ID;
317 {ID}/[^[:alnum:]_]              {
318   yylval.s = xmemdup (yytext, yyleng, yyleng+1);
319   return ID;
322 \"([^"\\]|\\.)*\"               {
323   yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
324   return STRING;
326 "["[^\[\]]*"]"                  {
327   yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
328   return ARRAY;
330 ^"%"{ID}                        {
331   yylval.s = xmemdup (yytext+1, yyleng-1, yyleng);
332   return PERCENT_ID;
334 "'"("\\".|[^\\])"'"             {
335   yylval.s = xmemdup (yytext+1, yyleng-2, yyleng);
336   return CHAR;
339 [(){},*:<>]                     { return yytext[0]; }
341 [;=]                            {
342   if (lexer_toplevel_done)
343     {
344       BEGIN(INITIAL);
345       lexer_toplevel_done = 0;
346     }
347   return yytext[0];
350 ^"%%"                           {
351   BEGIN(INITIAL);
352   return PERCENTPERCENT;
355 .                               {
356   error_at_line (&lexer_line, "unexpected character `%s'", yytext);
360 "/*"                    { BEGIN(in_comment); }
361 \n                      { lexer_line.line++; }
362 {ID}                    |
363 "'"("\\".|[^\\])"'"     |
364 [^"/\n]                 /* do nothing */
365 \"([^"\\]|\\.|\\\n)*\"  { update_lineno (yytext, yyleng); }
366 "/"/[^*]                /* do nothing */
368 <in_comment,in_struct_comment>{
369 \n              { lexer_line.line++; }
370 [^*\n]{16}      |
371 [^*\n]          /* do nothing */
372 "*"/[^/]        /* do nothing */
374 <in_comment>"*/"        { BEGIN(INITIAL); } 
375 <in_struct_comment>"*/" { BEGIN(in_struct); }
377 <in_yacc_escape>{
378 \n              { lexer_line.line++; }
379 [^%]{16}        |
380 [^%]            /* do nothing */
381 "%"/[^}]        /* do nothing */
382 "%}"            { BEGIN(in_struct); }
383 "%"             {
384   error_at_line (&lexer_line, 
385                  "unterminated %%{; unexpected EOF");
390 ["/]                    |
391 <in_struct_comment,in_comment>"*"       {
392   error_at_line (&lexer_line, 
393                  "unterminated comment or string; unexpected EOF");
396 ^"#define"{WS}"GTY(" /* do nothing */
397 {WS}"GTY"{WS}?"("       {
398   error_at_line (&lexer_line, "stray GTY marker");
403 /* Deal with the expansion caused by the DEF_VEC_x macros.  */
405 typedef struct macro
407   const char *name;
408   const char *expansion;
409   struct macro *next;
410 } macro_t;
412 static const macro_t macro_defs[] = 
414 #define IN_GENGTYPE 1
415 #include "vec.h"
416   {NULL, NULL, NULL}
419 /* Chain of macro expansions to do at end of scanning.  */
420 static macro_t *macro_expns;
422 /* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
423    expansion queue.  We ensure NAME is known at this point.  */
425 static void
426 push_macro_expansion (const char *name, unsigned name_len,
427                       const char *arg, unsigned arg_len)
429   unsigned ix;
431   for (ix = 0; macro_defs[ix].name; ix++)
432     if (strlen (macro_defs[ix].name) == name_len
433         && !memcmp (name, macro_defs[ix].name, name_len))
434       {
435         macro_t *expansion = xmalloc (sizeof (*expansion));
437         expansion->next = macro_expns;
438         expansion->name = xmemdup (arg, arg_len, arg_len+1);
439         expansion->expansion = macro_defs[ix].expansion;
440         macro_expns = expansion;
441         return;
442       }
443   error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
444                  name_len, name, arg_len, arg);
447 /* Attempt to read some input.  Use fread until we're at the end of
448    file.  At end of file expand the next queued macro.  We presume the
449    buffer is large enough for the entire expansion.  */
451 static unsigned
452 macro_input (char *buffer, unsigned size)
454   unsigned result;
456   result = fread (buffer, 1, size, yyin);
457   if (result)
458     /*NOP*/;
459   else if (ferror (yyin))
460     YY_FATAL_ERROR ("read of source file failed");
461   else if (macro_expns)
462     {
463       const char *expn;
464       unsigned len;
466       for (expn = macro_expns->expansion; *expn; expn++)
467         {
468           if (*expn == '#')
469             {
470               if (buffer[result-1] == ' ' && buffer[result-2] == '_')
471                 result--;
472               len = strlen (macro_expns->name);
473               memcpy (&buffer[result], macro_expns->name, len);
474               result += len;
475             }
476           else
477             {
478               buffer[result++] = *expn;
479               if (*expn == ';' || *expn == '{')
480                 buffer[result++] = '\n';
481             }
482         }
483       if (result > size)
484         YY_FATAL_ERROR ("buffer too small to expand macro");
485       macro_expns = macro_expns->next;
486     }
487   return result;
490 void
491 yyerror (const char *s)
493   error_at_line (&lexer_line, s);
496 void
497 parse_file (const char *fname)
499   yyin = fopen (fname, "r");
500   lexer_line.file = fname;
501   lexer_line.line = 1;
502   if (yyin == NULL)
503     {
504       perror (fname);
505       exit (1);
506     }
507   if (yyparse() != 0)
508     exit (1);
509   fclose (yyin);