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