OSDN Git Service

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