gengtype.c (create_option): New function.
[gcc.git] / gcc / gengtype-yacc.y
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 #include "bconfig.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "gengtype.h"
28 #define YYERROR_VERBOSE
29 %}
30
31 %union {
32 type_p t;
33 pair_p p;
34 options_p o;
35 const char *s;
36 }
37
38 %token <t>ENT_TYPEDEF_STRUCT
39 %token <t>ENT_STRUCT
40 %token ENT_EXTERNSTATIC
41 %token ENT_YACCUNION
42 %token GTY_TOKEN
43 %token UNION
44 %token STRUCT
45 %token ENUM
46 %token ALIAS
47 %token <s>PARAM_IS
48 %token NUM
49 %token PERCENTPERCENT "%%"
50 %token <t>SCALAR
51 %token <s>ID
52 %token <s>STRING
53 %token <s>ARRAY
54 %token <s>PERCENT_ID
55 %token <s>CHAR
56
57 %type <p> struct_fields yacc_ids yacc_typematch
58 %type <t> type lasttype
59 %type <o> optionsopt options option optionseq optionseqopt
60 %type <s> type_option stringseq
61
62 %%
63
64 start: /* empty */
65 | typedef_struct start
66 | externstatic start
67 | yacc_union start
68 ;
69
70 typedef_struct: ENT_TYPEDEF_STRUCT options '{' struct_fields '}' ID
71 {
72 new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
73 $4, $2);
74 do_typedef ($6, $1, &lexer_line);
75 lexer_toplevel_done = 1;
76 }
77 ';'
78 {}
79 | ENT_STRUCT options '{' struct_fields '}'
80 {
81 new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
82 $4, $2);
83 lexer_toplevel_done = 1;
84 }
85 ';'
86 {}
87 ;
88
89 externstatic: ENT_EXTERNSTATIC options lasttype ID semiequal
90 {
91 note_variable ($4, adjust_field_type ($3, $2), $2,
92 &lexer_line);
93 }
94 | ENT_EXTERNSTATIC options lasttype ID ARRAY semiequal
95 {
96 note_variable ($4, create_array ($3, $5),
97 $2, &lexer_line);
98 }
99 | ENT_EXTERNSTATIC options lasttype ID ARRAY ARRAY semiequal
100 {
101 note_variable ($4, create_array (create_array ($3, $6),
102 $5),
103 $2, &lexer_line);
104 }
105 ;
106
107 lasttype: type
108 {
109 lexer_toplevel_done = 1;
110 $$ = $1;
111 }
112 ;
113
114 semiequal: ';'
115 | '='
116 ;
117
118 yacc_union: ENT_YACCUNION options struct_fields '}' yacc_typematch
119 PERCENTPERCENT
120 {
121 note_yacc_type ($2, $3, $5, &lexer_line);
122 }
123 ;
124
125 yacc_typematch: /* empty */
126 { $$ = NULL; }
127 | yacc_typematch PERCENT_ID yacc_ids
128 {
129 pair_p p;
130 for (p = $3; p->next != NULL; p = p->next)
131 {
132 p->name = NULL;
133 p->type = NULL;
134 }
135 p->name = NULL;
136 p->type = NULL;
137 p->next = $1;
138 $$ = $3;
139 }
140 | yacc_typematch PERCENT_ID '<' ID '>' yacc_ids
141 {
142 pair_p p;
143 type_p newtype = NULL;
144 if (strcmp ($2, "type") == 0)
145 newtype = (type_p) 1;
146 for (p = $6; p->next != NULL; p = p->next)
147 {
148 p->name = $4;
149 p->type = newtype;
150 }
151 p->name = $4;
152 p->next = $1;
153 p->type = newtype;
154 $$ = $6;
155 }
156 ;
157
158 yacc_ids: /* empty */
159 { $$ = NULL; }
160 | yacc_ids ID
161 {
162 pair_p p = xcalloc (1, sizeof (*p));
163 p->next = $1;
164 p->line = lexer_line;
165 p->opt = xmalloc (sizeof (*(p->opt)));
166 p->opt->name = "tag";
167 p->opt->next = NULL;
168 p->opt->info = (char *)$2;
169 $$ = p;
170 }
171 | yacc_ids CHAR
172 {
173 pair_p p = xcalloc (1, sizeof (*p));
174 p->next = $1;
175 p->line = lexer_line;
176 p->opt = xmalloc (sizeof (*(p->opt)));
177 p->opt->name = "tag";
178 p->opt->next = NULL;
179 p->opt->info = xasprintf ("'%s'", $2);
180 $$ = p;
181 }
182 ;
183
184 struct_fields: { $$ = NULL; }
185 | type optionsopt ID bitfieldopt ';' struct_fields
186 {
187 pair_p p = xmalloc (sizeof (*p));
188 p->type = adjust_field_type ($1, $2);
189 p->opt = $2;
190 p->name = $3;
191 p->next = $6;
192 p->line = lexer_line;
193 $$ = p;
194 }
195 | type optionsopt ID ARRAY ';' struct_fields
196 {
197 pair_p p = xmalloc (sizeof (*p));
198 p->type = adjust_field_type (create_array ($1, $4), $2);
199 p->opt = $2;
200 p->name = $3;
201 p->next = $6;
202 p->line = lexer_line;
203 $$ = p;
204 }
205 | type optionsopt ID ARRAY ARRAY ';' struct_fields
206 {
207 pair_p p = xmalloc (sizeof (*p));
208 p->type = create_array (create_array ($1, $5), $4);
209 p->opt = $2;
210 p->name = $3;
211 p->next = $7;
212 p->line = lexer_line;
213 $$ = p;
214 }
215 ;
216
217 bitfieldopt: /* empty */
218 | ':' NUM
219 | ':' ID
220 ;
221
222 type: SCALAR
223 { $$ = $1; }
224 | ID
225 { $$ = resolve_typedef ($1, &lexer_line); }
226 | type '*'
227 { $$ = create_pointer ($1); }
228 | STRUCT ID '{' struct_fields '}'
229 {
230 new_structure ($2, 0, &lexer_line, $4, NULL);
231 $$ = find_structure ($2, 0);
232 }
233 | STRUCT ID
234 { $$ = find_structure ($2, 0); }
235 | UNION ID '{' struct_fields '}'
236 {
237 new_structure ($2, 1, &lexer_line, $4, NULL);
238 $$ = find_structure ($2, 1);
239 }
240 | UNION ID
241 { $$ = find_structure ($2, 1); }
242 | ENUM ID
243 { $$ = create_scalar_type ($2, strlen ($2)); }
244 | ENUM ID '{' enum_items '}'
245 { $$ = create_scalar_type ($2, strlen ($2)); }
246 ;
247
248 enum_items: /* empty */
249 | ID '=' NUM ',' enum_items
250 { }
251 | ID ',' enum_items
252 { }
253 | ID enum_items
254 { }
255 ;
256
257 optionsopt: { $$ = NULL; }
258 | options { $$ = $1; }
259 ;
260
261 options: GTY_TOKEN '(' '(' optionseqopt ')' ')'
262 { $$ = $4; }
263 ;
264
265 type_option : ALIAS
266 { $$ = "ptr_alias"; }
267 | PARAM_IS
268 { $$ = $1; }
269 ;
270
271 option: ID
272 { $$ = create_option ($1, (void *)""); }
273 | ID '(' stringseq ')'
274 { $$ = create_option ($1, (void *)$3); }
275 | type_option '(' type ')'
276 { $$ = create_option ($1, adjust_field_type ($3, NULL)); }
277
278 optionseq: option
279 {
280 $1->next = NULL;
281 $$ = $1;
282 }
283 | optionseq ',' option
284 {
285 $3->next = $1;
286 $$ = $3;
287 }
288 ;
289
290 optionseqopt: { $$ = NULL; }
291 | optionseq { $$ = $1; }
292 ;
293
294 stringseq: STRING
295 { $$ = $1; }
296 | stringseq STRING
297 {
298 size_t l1 = strlen ($1);
299 size_t l2 = strlen ($2);
300 char *s = xrealloc ((char *)$1, l1 + l2 + 1);
301 memcpy (s + l1, $2, l2 + 1);
302 free ((void *)$2);
303 $$ = s;
304 }
305 %%