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