steps to support modern FreeBSD. After Robert Watson <rwatson@FreeBSD.org> and Alec...
[arla.git] / ydr / parse.y
blob42fd86d3ec7a9efcfec5a5f7308a15bb920cc5b2
1 /*
2 * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 RCSID("$Id$");
38 #endif
40 #include <stdio.h>
41 #include <list.h>
42 #include <bool.h>
43 #include <roken.h>
44 #include "sym.h"
45 #include "types.h"
46 #include "output.h"
47 #include "lex.h"
49 void yyerror (char *);
50 static int varcnt = 0;
54 %union {
55 int constant;
56 Symbol *sym;
57 List *list;
58 char *name;
59 Type *type;
60 StructEntry *sentry;
61 Argument *arg;
62 Bool bool;
63 unsigned flags;
66 %token T_UNION T_SWITCH T_CASE
67 %token T_ENUM T_STRUCT T_CONST T_UNSIGNED T_ULONG T_INT T_CHAR T_STRING
68 %token T_LONG T_TYPEDEF T_OPAQUE T_IN T_OUT T_INOUT T_SPLIT T_MULTI
69 %token T_SHORT T_USHORT T_UCHAR T_ASIS T_PROC
70 %token T_LONGLONG T_ULONGLONG
71 %token <name> T_IDENTIFIER T_VERBATIM T_PACKAGE T_PREFIX T_ERROR_FUNCTION
72 %token <constant> T_CONSTANT
73 %token <sym> T_IDCONST T_IDTYPE
75 %type <constant> constant opt_constant opt_proc
76 %type <constant> param_type
77 %type <sym> enumentry type_decl proc_decl
78 %type <list> enumentries enumbody structbody unionbody params attrs
79 %type <list> memberdecls umemberdecls
80 %type <type> type inttype
81 %type <sentry> memberdecl umemberdecl memberdecl2
82 %type <arg> param
83 %type <flags> flags
84 %type <name> attr
86 %start specification
90 specification:
91 | specification declaration
92 | specification directive
93 | error ';'
96 declaration: type_decl {
97 if (!sym_find_attr($1, "__nogenerate__")) {
98 generate_header ($1, headerfile.stream);
99 generate_sizeof ($1, headerfile.stream);
100 generate_function ($1, ydrfile.stream, TRUE);
101 generate_function_prototype ($1, headerfile.stream, TRUE);
102 generate_function ($1, ydrfile.stream, FALSE);
103 generate_function_prototype ($1, headerfile.stream, FALSE);
104 generate_printfunction ($1, ydrfile.stream);
105 generate_printfunction_prototype ($1, headerfile.stream);
106 generate_freefunction ($1, ydrfile.stream);
107 generate_freefunction_prototype ($1, headerfile.stream);
110 | proc_decl {
111 generate_client_stub ($1, clientfile.stream,
112 clienthdrfile.stream);
113 generate_server_stub ($1, serverfile.stream,
114 serverhdrfile.stream,
115 headerfile.stream);
119 type_decl : T_ENUM T_IDENTIFIER enumbody ';'
120 { $$ = define_enum ($2, $3); varcnt = 0; }
121 | T_UNION T_IDENTIFIER { define_union($2); } T_SWITCH '(' inttype T_IDENTIFIER ')' unionbody ';'
122 { $$ = set_struct_body ($2, $9);
123 $$->unionlabel = estrdup($7);
125 | T_STRUCT T_IDENTIFIER { define_struct($2); } structbody attrs ';'
126 { $$ = set_struct_body ($2, $4);
127 set_sym_attrs($$, $5); }
128 | T_STRUCT type structbody attrs';'
129 { if($2->symbol && $2->symbol->type != YDR_TSTRUCT)
130 error_message (1, "%s is not a struct\n",
131 $2->symbol->name);
132 $$ = set_struct_body_sym ($2->symbol, $3);
133 set_sym_attrs($2->symbol, $4);
135 | T_TYPEDEF memberdecl ';'
136 { $$ = define_typedef ($2); }
137 | T_CONST T_IDENTIFIER '=' constant ';'
138 { $$ = define_const ($2, $4); }
141 flags: { $$ = TSIMPLE; }
142 | T_SPLIT { $$ = TSPLIT; }
143 | T_MULTI { $$ = TSPLIT | TSIMPLE | TMULTI; }
146 opt_proc: { $$ = 0; }/* empty */
147 | T_PROC { $$ = 0; }
150 proc_decl: opt_proc T_IDENTIFIER '(' params ')' flags '=' constant ';'
151 { $$ = (Symbol *)emalloc(sizeof(Symbol));
152 $$->type = YDR_TPROC;
153 $$->name = $2;
154 $$->u.proc.package = package;
155 $$->u.proc.arguments = $4;
156 $$->u.proc.id = $8;
157 $$->u.proc.flags = $6;
161 params: { $$ = listnew(); }
162 | param { $$ = listnew(); listaddhead ($$, $1); }
163 | params ',' param
164 { listaddtail ($1, $3); $$ = $1; }
167 param: param_type memberdecl
168 { $$ = (Argument *)emalloc(sizeof(Argument));
169 $$->argtype = $1;
170 $$->name = $2->name;
171 $$->type = $2->type;
172 free($2); }
175 param_type: T_IN { $$ = TIN; }
176 | T_OUT { $$ = TOUT; }
177 | T_INOUT { $$ = TINOUT; }
178 | { $$ = TIN; }
181 directive: T_PACKAGE T_IDENTIFIER
182 { package = estrdup($2);
183 listaddtail (packagelist, package);
185 | T_PREFIX T_IDENTIFIER
186 { prefix = $2; }
187 | T_VERBATIM
188 { fprintf (headerfile.stream, "%s\n", $1); }
189 | T_ERROR_FUNCTION T_IDENTIFIER
190 { error_function = $2; }
193 enumbody: '{' enumentries '}' { $$ = $2; }
196 enumentries: { $$ = listnew (); }
197 | enumentry
198 { $$ = listnew(); listaddhead ($$, $1); }
199 | enumentries ',' enumentry
200 { listaddtail ($1, $3); $$ = $1;}
203 enumentry: T_IDENTIFIER '=' constant
204 { $$ = createenumentry ($1, $3); varcnt = $3 + 1; }
205 | T_IDENTIFIER
206 { $$ = createenumentry ($1, varcnt++); }
209 memberdecl: T_ASIS memberdecl2
210 { $$ = $2; $$->type->flags |= TASIS; }
211 | memberdecl2
212 { $$ = $1; }
215 memberdecl2: type T_IDENTIFIER
216 { $$ = createstructentry ($2, $1); }
217 | T_STRING T_IDENTIFIER '<' opt_constant '>'
218 { Type *t = create_type (YDR_TSTRING, NULL, $4, NULL, NULL,0);
219 $$ = createstructentry ($2, t);
221 | T_STRING T_IDENTIFIER
222 { Type *t = create_type (YDR_TSTRING, NULL, 0, NULL, NULL, 0);
223 $$ = createstructentry ($2, t);
225 | type T_IDENTIFIER '[' opt_constant ']'
226 { Type *t = create_type (YDR_TARRAY, NULL, $4, $1, NULL, 0);
227 $$ = createstructentry ($2, t); }
228 | type T_IDENTIFIER '<' opt_constant '>'
229 { Type *t = create_type (YDR_TVARRAY, NULL, $4, $1, NULL, 0);
230 $$ = createstructentry ($2, t); }
231 | type T_IDENTIFIER '<' type '>'
232 { Type *t = create_type (YDR_TVARRAY, NULL, 0, $1, $4, 0);
233 $$ = createstructentry ($2, t); }
236 inttype: long_or_int
237 { $$ = create_type (YDR_TLONG, NULL, 0, NULL, NULL, 0); }
238 | T_UNSIGNED
239 { $$ = create_type (YDR_TULONG, NULL, 0, NULL, NULL, 0); }
240 | T_ULONG
241 { $$ = create_type (YDR_TULONG, NULL, 0, NULL, NULL, 0); }
242 | T_UNSIGNED T_LONG
243 { $$ = create_type (YDR_TULONG, NULL, 0, NULL, NULL, 0); }
244 | T_LONGLONG
245 { $$ = create_type (YDR_TLONGLONG, NULL, 0, NULL, NULL, 0); }
246 | T_ULONGLONG
247 { $$ = create_type (YDR_TULONGLONG, NULL, 0, NULL, NULL, 0); }
248 | T_CHAR
249 { $$ = create_type (YDR_TCHAR, NULL, 0, NULL, NULL, 0); }
250 | T_UCHAR
251 { $$ = create_type (YDR_TUCHAR, NULL, 0, NULL, NULL, 0); }
252 | T_UNSIGNED T_CHAR
253 { $$ = create_type (YDR_TUCHAR, NULL, 0, NULL, NULL, 0); }
254 | T_SHORT
255 { $$ = create_type (YDR_TSHORT, NULL, 0, NULL, NULL, 0); }
256 | T_USHORT
257 { $$ = create_type (YDR_TUSHORT, NULL, 0, NULL, NULL, 0); }
258 | T_UNSIGNED T_SHORT
259 { $$ = create_type (YDR_TUSHORT, NULL, 0, NULL, NULL, 0); }
262 type: inttype
263 { $$ = $1; }
264 | T_STRING
265 { $$ = create_type (YDR_TSTRING, NULL, 0, NULL, NULL, 0); }
266 | T_OPAQUE
267 { $$ = create_type (YDR_TOPAQUE, NULL, 0, NULL, NULL, 0); }
268 | type '*'
269 { $$ = create_type (YDR_TPOINTER, NULL, 0, $1, NULL, 0); }
270 | T_IDTYPE
271 { $$ = create_type (YDR_TUSERDEF, $1, 0, NULL, NULL, 0);
272 if ($$->symbol->type != YDR_TSTRUCT
273 && $$->symbol->type != YDR_TENUM
274 && $$->symbol->type != YDR_TTYPEDEF)
275 error_message (1, "%s used as a type\n",
276 $$->symbol->name);
278 | T_STRUCT type
280 $$ = $2;
281 if ($$->symbol && $$->symbol->type != YDR_TSTRUCT)
282 error_message (1, "%s is not a struct\n",
283 $$->symbol->name);
285 | T_STRUCT T_IDENTIFIER
286 { $$ = create_type (YDR_TUSERDEF, define_struct($2), 0, NULL,
287 NULL, 0);
291 long_or_int: T_LONG
292 | T_INT
295 memberdecls: { $$ = listnew(); }
296 | memberdecls memberdecl ';'
297 { listaddtail ($1, $2); $$ = $1; }
300 structbody: '{' memberdecls '}' { $$ = $2; }
303 umemberdecl: T_CASE constant ':' type T_IDENTIFIER
304 { $$ = createunionentry($5, $2, $4); }
307 umemberdecls: { $$ = listnew(); }
308 | umemberdecls umemberdecl ';'
309 { listaddtail ($1, $2); $$ = $1; }
312 unionbody: '{' umemberdecls '}' { $$ = $2; }
315 opt_constant: { $$ = 0; }
316 | constant { $$ = $1; }
319 constant: T_CONSTANT { $$ = $1; }
320 | T_IDCONST
321 { Symbol *s = $1;
322 if (s->type != YDR_TCONST) {
323 error_message (1, "%s not a constant\n", s->name);
324 } else
325 $$ = s->u.val;
329 attrs: { $$ = listnew(); }
330 | attr { $$ = listnew(); listaddhead ($$, $1); }
331 | attrs attr
332 { listaddtail ($1, $2); $$ = $1; }
335 attr: T_IDENTIFIER '(' '(' T_IDENTIFIER ')' ')'
336 { $$ = $4;
337 if (strcmp($1, "__attribute__") != 0)
338 error_message(1, "%s isn't __attribute__"); }
342 void
343 yyerror (char *s)
345 error_message (1, "%s\n", s);