]>
Commit | Line | Data |
---|---|---|
1f3233d1 | 1 | /* -*- indented-text -*- */ |
2 | /* Process source files and output type information. | |
1576dec7 | 3 | Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
1f3233d1 | 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 | |
67ce556b | 19 | Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA |
20 | 02110-1301, USA. */ | |
1f3233d1 | 21 | |
22 | %{ | |
805e22b2 | 23 | #include "bconfig.h" |
805e22b2 | 24 | #include "system.h" |
12a13e7a | 25 | |
26 | #define malloc xmalloc | |
27 | #define realloc xrealloc | |
28 | ||
1f3233d1 | 29 | #include "gengtype.h" |
30 | #include "gengtype-yacc.h" | |
31 | ||
1f3233d1 | 32 | struct fileloc lexer_line; |
33 | int lexer_toplevel_done; | |
34 | ||
35 | static void | |
5a2784f8 | 36 | update_lineno (const char *l, size_t len) |
1f3233d1 | 37 | { |
38 | while (len-- > 0) | |
39 | if (*l++ == '\n') | |
40 | lexer_line.line++; | |
41 | } | |
42 | ||
1f3233d1 | 43 | %} |
44 | ||
2f3d127e | 45 | ID [[:alpha:]_][[:alnum:]_]* |
1f3233d1 | 46 | WS [[:space:]]+ |
4ee9c684 | 47 | IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD |
1f3233d1 | 48 | ITYPE {IWORD}({WS}{IWORD})* |
49 | ||
f8be92ce | 50 | %x in_struct in_struct_comment in_comment |
1f3233d1 | 51 | %option warn noyywrap nounput nodefault perf-report |
52 | %option 8bit never-interactive | |
53 | %% | |
54 | ||
55 | [^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" { | |
56 | char *tagstart; | |
57 | size_t taglen; | |
58 | char *namestart; | |
59 | size_t namelen; | |
60 | int is_pointer = 0; | |
61 | struct type *t; | |
62 | int union_p; | |
63 | ||
64 | tagstart = yytext + strlen (" typedef "); | |
74863452 | 65 | while (ISSPACE (*tagstart)) |
1f3233d1 | 66 | tagstart++; |
67 | union_p = tagstart[0] == 'u'; | |
68 | tagstart += strlen ("union "); | |
74863452 | 69 | while (ISSPACE (*tagstart)) |
1f3233d1 | 70 | tagstart++; |
74863452 | 71 | for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) |
1f3233d1 | 72 | ; |
73 | for (namestart = tagstart + taglen; | |
74863452 | 74 | ! ISIDNUM (*namestart); |
1f3233d1 | 75 | namestart++) |
76 | if (*namestart == '*') | |
77 | is_pointer = 1; | |
74863452 | 78 | for (namelen = 1; ISIDNUM (namestart[namelen]); namelen++) |
1f3233d1 | 79 | ; |
4fd61bc6 | 80 | t = find_structure ((const char *) xmemdup (tagstart, taglen, taglen+1), |
81 | union_p); | |
1f3233d1 | 82 | if (is_pointer) |
83 | t = create_pointer (t); | |
4fd61bc6 | 84 | namestart = (char *) xmemdup (namestart, namelen, namelen+1); |
512e0fec | 85 | #ifdef USE_MAPPED_LOCATION |
86 | /* temporary kludge - gentype doesn't handle cpp conditionals */ | |
a59d74d6 | 87 | if (strcmp (namestart, "location_t") != 0 |
88 | && strcmp (namestart, "expanded_location") != 0) | |
512e0fec | 89 | #endif |
90 | do_typedef (namestart, t, &lexer_line); | |
1f3233d1 | 91 | update_lineno (yytext, yyleng); |
92 | } | |
93 | ||
94 | [^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" { | |
95 | ||
96 | char *namestart; | |
97 | size_t namelen; | |
1f3233d1 | 98 | char *typestart; |
99 | size_t typelen; | |
100 | ||
74863452 | 101 | for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) |
1f3233d1 | 102 | ; |
74863452 | 103 | for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) |
1f3233d1 | 104 | ; |
105 | namestart -= namelen - 1; | |
106 | for (typestart = yytext + strlen (" typedef "); | |
74863452 | 107 | ISSPACE(*typestart); |
1f3233d1 | 108 | typestart++) |
109 | ; | |
4fd61bc6 | 110 | for (typelen = namestart - typestart; |
111 | ISSPACE (typestart[typelen-1]); | |
1f3233d1 | 112 | typelen--) |
113 | ; | |
80da8e25 | 114 | typestart[typelen] = '\0'; |
1f3233d1 | 115 | |
80da8e25 | 116 | do_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), |
117 | create_scalar_type (typestart), | |
4fd61bc6 | 118 | &lexer_line); |
1f3233d1 | 119 | update_lineno (yytext, yyleng); |
120 | } | |
121 | ||
e8d74f41 | 122 | [^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" { |
123 | char *namestart; | |
124 | size_t namelen; | |
e8d74f41 | 125 | |
126 | for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--) | |
127 | ; | |
128 | for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++) | |
129 | ; | |
130 | namestart -= namelen - 1; | |
131 | ||
80da8e25 | 132 | do_scalar_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), |
133 | &lexer_line); | |
e8d74f41 | 134 | update_lineno (yytext, yyleng); |
135 | } | |
136 | ||
34c059db | 137 | [^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" { |
e8d74f41 | 138 | char *namestart; |
139 | size_t namelen; | |
e8d74f41 | 140 | |
141 | for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--) | |
142 | ; | |
143 | for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++) | |
144 | ; | |
145 | namestart -= namelen - 1; | |
146 | ||
80da8e25 | 147 | do_scalar_typedef ((const char *) xmemdup (namestart, namelen, namelen+1), |
148 | &lexer_line); | |
e8d74f41 | 149 | update_lineno (yytext, yyleng); |
150 | } | |
151 | ||
1f3233d1 | 152 | [^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" { |
153 | char *tagstart; | |
154 | size_t taglen; | |
155 | int typedef_p; | |
156 | int union_p; | |
157 | ||
158 | typedef_p = yytext[1] == 't'; | |
159 | if (typedef_p) | |
160 | for (tagstart = yytext + strlen (" typedef "); | |
74863452 | 161 | ISSPACE(*tagstart); |
1f3233d1 | 162 | tagstart++) |
163 | ; | |
164 | else | |
165 | tagstart = yytext + 1; | |
166 | ||
167 | union_p = tagstart[0] == 'u'; | |
168 | tagstart += strlen ("union "); | |
74863452 | 169 | while (ISSPACE (*tagstart)) |
1f3233d1 | 170 | tagstart++; |
74863452 | 171 | for (taglen = 1; ISIDNUM (tagstart[taglen]); taglen++) |
1f3233d1 | 172 | ; |
173 | ||
6fee8f02 | 174 | yylval.s = (const char *) xmemdup (tagstart, taglen, taglen + 1); |
175 | ||
1f3233d1 | 176 | BEGIN(in_struct); |
177 | update_lineno (yytext, yyleng); | |
6fee8f02 | 178 | return union_p ? (typedef_p ? ENT_TYPEDEF_UNION : ENT_UNION) |
179 | : (typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT); | |
1f3233d1 | 180 | } |
181 | ||
182 | [^[:alnum:]_](extern|static){WS}/"GTY" { | |
183 | BEGIN(in_struct); | |
184 | update_lineno (yytext, yyleng); | |
185 | return ENT_EXTERNSTATIC; | |
186 | } | |
187 | ||
696e7773 | 188 | ^"DEF_VEC_"[IPO]{WS}?"("{WS}?{ID}{WS}?")" { |
189 | /* Definition of a generic VEC structure. If the letter after | |
190 | DEF_VEC_ is "I", the structure definition is slightly different | |
191 | than if it is "P" or "O". */ | |
192 | ||
193 | char *p = yytext + sizeof("DEF_VEC_") - 1; | |
194 | char *q; | |
195 | const char *type; | |
196 | bool is_I = (*p == 'I'); | |
197 | ||
198 | /* Extract the argument to the macro. */ | |
199 | p++; | |
200 | while (!ISALNUM(*p) && *p != '_') | |
201 | p++; | |
202 | q = p; | |
203 | while (ISALNUM(*q) || *q == '_') | |
204 | ++; | |
205 | type = xmemdup (p, q - p, q - p + 1); | |
206 | ||
207 | note_def_vec (type, is_I, &lexer_line); | |
208 | note_def_vec_alloc (type, "none", &lexer_line); | |
209 | } | |
046bfc77 | 210 | |
696e7773 | 211 | ^"DEF_VEC_ALLOC_"[IPO]{WS}?"("{WS}?{ID}{WS}?","{WS}?{ID}{WS}?")" { |
212 | /* Definition of an allocation strategy for a VEC structure. For | |
213 | purposes of gengtype, this just declares a wrapper structure. */ | |
214 | ||
215 | char *p = yytext + sizeof("DEF_VEC_ALLOC_I") - 1; | |
216 | char *q; | |
217 | char *type, *astrat; | |
218 | ||
219 | /* Extract the two arguments to the macro. */ | |
220 | while (!ISALNUM(*p) && *p != '_') | |
221 | p++; | |
222 | q = p; | |
223 | while (ISALNUM(*q) || *q == '_') | |
224 | q++; | |
225 | type = alloca (q - p + 1); | |
226 | memcpy (type, p, q - p); | |
227 | type[q - p] = '\0'; | |
228 | p = q; | |
229 | ||
230 | while (!ISALNUM(*p) && *p != '_') | |
231 | p++; | |
232 | q = p; | |
233 | while (ISALNUM(*q) || *q == '_') | |
234 | q++; | |
235 | astrat = alloca (q - p + 1); | |
236 | memcpy (astrat, p, q - p); | |
237 | astrat[q - p] = '\0'; | |
238 | ||
239 | note_def_vec_alloc (type, astrat, &lexer_line); | |
190183c5 | 240 | } |
241 | ||
1f3233d1 | 242 | <in_struct>{ |
243 | ||
244 | "/*" { BEGIN(in_struct_comment); } | |
245 | ||
1f3233d1 | 246 | {WS} { update_lineno (yytext, yyleng); } |
247 | ||
248 | "const"/[^[:alnum:]_] /* don't care */ | |
1f3233d1 | 249 | "GTY"/[^[:alnum:]_] { return GTY_TOKEN; } |
696e7773 | 250 | "VEC"/[^[:alnum:]_] { return VEC_TOKEN; } |
1f3233d1 | 251 | "union"/[^[:alnum:]_] { return UNION; } |
252 | "struct"/[^[:alnum:]_] { return STRUCT; } | |
253 | "enum"/[^[:alnum:]_] { return ENUM; } | |
254 | "ptr_alias"/[^[:alnum:]_] { return ALIAS; } | |
8ed01400 | 255 | "nested_ptr"/[^[:alnum:]_] { return NESTED_PTR; } |
1f3233d1 | 256 | [0-9]+ { return NUM; } |
4fd61bc6 | 257 | "param"[0-9]*"_is"/[^[:alnum:]_] { |
258 | yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); | |
c849df63 | 259 | return PARAM_IS; |
260 | } | |
1f3233d1 | 261 | |
262 | {IWORD}({WS}{IWORD})*/[^[:alnum:]_] | | |
263 | "ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")" { | |
264 | size_t len; | |
265 | ||
74863452 | 266 | for (len = yyleng; ISSPACE (yytext[len-1]); len--) |
1f3233d1 | 267 | ; |
268 | ||
80da8e25 | 269 | yylval.s = (const char *) xmemdup (yytext, len, len+1); |
1f3233d1 | 270 | update_lineno (yytext, yyleng); |
271 | return SCALAR; | |
272 | } | |
273 | ||
190183c5 | 274 | |
1f3233d1 | 275 | {ID}/[^[:alnum:]_] { |
4fd61bc6 | 276 | yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1); |
1f3233d1 | 277 | return ID; |
278 | } | |
279 | ||
280 | \"([^"\\]|\\.)*\" { | |
4fd61bc6 | 281 | yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); |
1f3233d1 | 282 | return STRING; |
283 | } | |
284 | "["[^\[\]]*"]" { | |
4fd61bc6 | 285 | yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng-1); |
1f3233d1 | 286 | return ARRAY; |
287 | } | |
1f3233d1 | 288 | "'"("\\".|[^\\])"'" { |
4fd61bc6 | 289 | yylval.s = (const char *) xmemdup (yytext+1, yyleng-2, yyleng); |
1f3233d1 | 290 | return CHAR; |
291 | } | |
292 | ||
293 | [(){},*:<>] { return yytext[0]; } | |
294 | ||
295 | [;=] { | |
296 | if (lexer_toplevel_done) | |
297 | { | |
298 | BEGIN(INITIAL); | |
299 | lexer_toplevel_done = 0; | |
300 | } | |
301 | return yytext[0]; | |
302 | } | |
303 | ||
90a3c0eb | 304 | "#define"[^\n]*\n {lexer_line.line++;} |
305 | ||
1f3233d1 | 306 | . { |
307 | error_at_line (&lexer_line, "unexpected character `%s'", yytext); | |
308 | } | |
309 | } | |
310 | ||
311 | "/*" { BEGIN(in_comment); } | |
312 | \n { lexer_line.line++; } | |
313 | {ID} | | |
2c2e43fb | 314 | "'"("\\".|[^\\])"'" | |
1f3233d1 | 315 | [^"/\n] /* do nothing */ |
316 | \"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); } | |
317 | "/"/[^*] /* do nothing */ | |
318 | ||
319 | <in_comment,in_struct_comment>{ | |
320 | \n { lexer_line.line++; } | |
321 | [^*\n]{16} | | |
322 | [^*\n] /* do nothing */ | |
323 | "*"/[^/] /* do nothing */ | |
324 | } | |
325 | <in_comment>"*/" { BEGIN(INITIAL); } | |
326 | <in_struct_comment>"*/" { BEGIN(in_struct); } | |
327 | ||
1f3233d1 | 328 | ["/] | |
329 | <in_struct_comment,in_comment>"*" { | |
330 | error_at_line (&lexer_line, | |
331 | "unterminated comment or string; unexpected EOF"); | |
332 | } | |
333 | ||
8ca71ef2 | 334 | ^"#define"{WS}"GTY(" /* do nothing */ |
335 | {WS}"GTY"{WS}?"(" { | |
336 | error_at_line (&lexer_line, "stray GTY marker"); | |
337 | } | |
338 | ||
1f3233d1 | 339 | %% |
340 | ||
341 | void | |
5a2784f8 | 342 | yyerror (const char *s) |
1f3233d1 | 343 | { |
344 | error_at_line (&lexer_line, s); | |
345 | } | |
346 | ||
347 | void | |
5a2784f8 | 348 | parse_file (const char *fname) |
1f3233d1 | 349 | { |
350 | yyin = fopen (fname, "r"); | |
351 | lexer_line.file = fname; | |
352 | lexer_line.line = 1; | |
353 | if (yyin == NULL) | |
354 | { | |
355 | perror (fname); | |
356 | exit (1); | |
357 | } | |
358 | if (yyparse() != 0) | |
359 | exit (1); | |
360 | fclose (yyin); | |
361 | } |