1/* -*- indented-text -*- */
2/* Process source files and output type information.
3   Copyright (C) 2002 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.  */
21
22%{
23#include "hconfig.h"
24#include "system.h"
25#include "gengtype.h"
26#define YYERROR_VERBOSE
27%}
28
29%union {
30  type_p t;
31  pair_p p;
32  options_p o;
33  const char *s;
34}
35
36%token <t>ENT_TYPEDEF_STRUCT
37%token <t>ENT_STRUCT
38%token ENT_EXTERNSTATIC
39%token ENT_YACCUNION
40%token GTY_TOKEN
41%token UNION
42%token STRUCT
43%token ENUM
44%token ALIAS
45%token <s>PARAM_IS
46%token NUM
47%token PERCENTPERCENT "%%"
48%token <t>SCALAR
49%token <s>ID
50%token <s>STRING
51%token <s>ARRAY
52%token <s>PERCENT_ID
53%token <s>CHAR
54
55%type <p> struct_fields yacc_ids yacc_typematch
56%type <t> type lasttype
57%type <o> optionsopt options option optionseq optionseqopt
58%type <s> type_option
59
60%%
61
62start: /* empty */
63       | typedef_struct start
64       | externstatic start
65       | yacc_union start
66       ;
67
68typedef_struct: ENT_TYPEDEF_STRUCT options '{' struct_fields '}' ID
69		   {
70		     new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
71				    $4, $2);
72		     do_typedef ($6, $1, &lexer_line);
73		     lexer_toplevel_done = 1;
74		   }
75		 ';'
76		   {}
77		| ENT_STRUCT options '{' struct_fields '}'
78		   {
79		     new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
80				    $4, $2);
81		     lexer_toplevel_done = 1;
82		   }
83		 ';'
84		   {}
85		;
86
87externstatic: ENT_EXTERNSTATIC options lasttype ID semiequal
88	         {
89	           note_variable ($4, adjust_field_type ($3, $2), $2,
90				  &lexer_line);
91	         }
92	      | ENT_EXTERNSTATIC options lasttype ID ARRAY semiequal
93	         {
94	           note_variable ($4, create_array ($3, $5),
95	      		    $2, &lexer_line);
96	         }
97	      | ENT_EXTERNSTATIC options lasttype ID ARRAY ARRAY semiequal
98	         {
99	           note_variable ($4, create_array (create_array ($3, $6),
100	      				      $5),
101	      		    $2, &lexer_line);
102	         }
103	      ;
104
105lasttype: type
106	    {
107	      lexer_toplevel_done = 1;
108	      $$ = $1;
109	    }
110	    ;
111
112semiequal: ';'
113	   | '='
114	   ;
115
116yacc_union: ENT_YACCUNION options struct_fields '}' yacc_typematch
117	    PERCENTPERCENT
118	      {
119	        note_yacc_type ($2, $3, $5, &lexer_line);
120	      }
121	    ;
122
123yacc_typematch: /* empty */
124		   { $$ = NULL; }
125		| yacc_typematch PERCENT_ID yacc_ids
126		   {
127		     pair_p p;
128		     for (p = $3; p->next != NULL; p = p->next)
129		       {
130		         p->name = NULL;
131			 p->type = NULL;
132		       }
133		     p->name = NULL;
134		     p->type = NULL;
135		     p->next = $1;
136		     $$ = $3;
137		   }
138		| yacc_typematch PERCENT_ID '<' ID '>' yacc_ids
139		   {
140		     pair_p p;
141		     type_p newtype = NULL;
142		     if (strcmp ($2, "type") == 0)
143		       newtype = (type_p) 1;
144		     for (p = $6; p->next != NULL; p = p->next)
145		       {
146		         p->name = $4;
147		         p->type = newtype;
148		       }
149		     p->name = $4;
150		     p->next = $1;
151		     p->type = newtype;
152		     $$ = $6;
153		   }
154		;
155
156yacc_ids: /* empty */
157	{ $$ = NULL; }
158     | yacc_ids ID
159        {
160	  pair_p p = xcalloc (1, sizeof (*p));
161	  p->next = $1;
162	  p->line = lexer_line;
163	  p->opt = xmalloc (sizeof (*(p->opt)));
164	  p->opt->name = "tag";
165	  p->opt->next = NULL;
166	  p->opt->info = (char *)$2;
167	  $$ = p;
168	}
169     | yacc_ids CHAR
170        {
171	  pair_p p = xcalloc (1, sizeof (*p));
172	  p->next = $1;
173	  p->line = lexer_line;
174	  p->opt = xmalloc (sizeof (*(p->opt)));
175	  p->opt->name = "tag";
176	  p->opt->next = NULL;
177	  p->opt->info = xasprintf ("'%s'", $2);
178	  $$ = p;
179	}
180     ;
181
182struct_fields: { $$ = NULL; }
183	       | type optionsopt ID bitfieldopt ';' struct_fields
184	          {
185	            pair_p p = xmalloc (sizeof (*p));
186		    p->type = adjust_field_type ($1, $2);
187		    p->opt = $2;
188		    p->name = $3;
189		    p->next = $6;
190		    p->line = lexer_line;
191		    $$ = p;
192		  }
193	       | type optionsopt ID ARRAY ';' struct_fields
194	          {
195	            pair_p p = xmalloc (sizeof (*p));
196		    p->type = adjust_field_type (create_array ($1, $4), $2);
197		    p->opt = $2;
198		    p->name = $3;
199		    p->next = $6;
200		    p->line = lexer_line;
201		    $$ = p;
202		  }
203	       | type optionsopt ID ARRAY ARRAY ';' struct_fields
204	          {
205	            pair_p p = xmalloc (sizeof (*p));
206		    p->type = create_array (create_array ($1, $5), $4);
207		    p->opt = $2;
208		    p->name = $3;
209		    p->next = $7;
210		    p->line = lexer_line;
211		    $$ = p;
212		  }
213	       ;
214
215bitfieldopt: /* empty */
216	     | ':' NUM
217	     | ':' ID
218	     ;
219
220type: SCALAR
221         { $$ = $1; }
222      | ID
223         { $$ = resolve_typedef ($1, &lexer_line); }
224      | type '*'
225         { $$ = create_pointer ($1); }
226      | STRUCT ID '{' struct_fields '}'
227         {
228	   new_structure ($2, 0, &lexer_line, $4, NULL);
229           $$ = find_structure ($2, 0);
230	 }
231      | STRUCT ID
232         { $$ = find_structure ($2, 0); }
233      | UNION ID '{' struct_fields '}'
234         {
235	   new_structure ($2, 1, &lexer_line, $4, NULL);
236           $$ = find_structure ($2, 1);
237	 }
238      | UNION ID
239         { $$ = find_structure ($2, 1); }
240      | ENUM ID
241         { $$ = create_scalar_type ($2, strlen ($2)); }
242      | ENUM ID '{' enum_items '}'
243         { $$ = create_scalar_type ($2, strlen ($2)); }
244      ;
245
246enum_items: /* empty */
247	    | ID '=' NUM ',' enum_items
248	      { }
249	    | ID ',' enum_items
250	      { }
251	    | ID enum_items
252	      { }
253	    ;
254
255optionsopt: { $$ = NULL; }
256	    | options { $$ = $1; }
257	    ;
258
259options: GTY_TOKEN '(' '(' optionseqopt ')' ')'
260	   { $$ = $4; }
261	 ;
262
263type_option : ALIAS
264	        { $$ = "ptr_alias"; }
265	      | PARAM_IS
266	        { $$ = $1; }
267	      ;
268
269option:	type_option '(' type ')'
270	   {
271	     options_p o = xmalloc (sizeof (*o));
272	     o->name = $1;
273	     o->info = adjust_field_type ($3, NULL);
274	     $$ = o;
275	   }
276	| ID '(' STRING ')'
277	   {
278	     options_p o = xmalloc (sizeof (*o));
279	     o->name = $1;
280	     o->info = (void *)$3;
281	     $$ = o;
282	   }
283	;
284
285optionseq: option
286	      {
287	        $1->next = NULL;
288		$$ = $1;
289	      }
290	    | optionseq ',' option
291	      {
292	        $3->next = $1;
293		$$ = $3;
294	      }
295	    ;
296
297optionseqopt: { $$ = NULL; }
298	      | optionseq { $$ = $1; }
299	      ;
300%%
301