rpc_parse.c revision 1.1 1 /* @(#)rpc_parse.c 2.1 88/08/01 4.0 RPCSRC */
2 /*
3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4 * unrestricted use provided that this legend is included on all tape
5 * media and as a part of the software program in whole or part. Users
6 * may copy or modify Sun RPC without charge, but are not authorized
7 * to license or distribute it to anyone else except as part of a product or
8 * program developed by the user.
9 *
10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13 *
14 * Sun RPC is provided with no support and without any obligation on the
15 * part of Sun Microsystems, Inc. to assist in its use, correction,
16 * modification or enhancement.
17 *
18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20 * OR ANY PART THEREOF.
21 *
22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23 * or profits or other special, indirect and consequential damages, even if
24 * Sun has been advised of the possibility of such damages.
25 *
26 * Sun Microsystems, Inc.
27 * 2550 Garcia Avenue
28 * Mountain View, California 94043
29 */
30 #ifndef lint
31 static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";
32 #endif
33
34 /*
35 * rpc_parse.c, Parser for the RPC protocol compiler
36 * Copyright (C) 1987 Sun Microsystems, Inc.
37 */
38 #include <stdio.h>
39 #include "rpc_util.h"
40 #include "rpc_scan.h"
41 #include "rpc_parse.h"
42
43 int isdefined(), def_struct(), def_program(), def_enum(), def_const(),
44 def_union(), def_typedef(), get_declaration(), get_type(),
45 unsigned_dec();
46 /*
47 * return the next definition you see
48 */
49 definition *
50 get_definition()
51 {
52 definition *defp;
53 token tok;
54
55 defp = ALLOC(definition);
56 get_token(&tok);
57 switch (tok.kind) {
58 case TOK_STRUCT:
59 def_struct(defp);
60 break;
61 case TOK_UNION:
62 def_union(defp);
63 break;
64 case TOK_TYPEDEF:
65 def_typedef(defp);
66 break;
67 case TOK_ENUM:
68 def_enum(defp);
69 break;
70 case TOK_PROGRAM:
71 def_program(defp);
72 break;
73 case TOK_CONST:
74 def_const(defp);
75 break;
76 case TOK_EOF:
77 return (NULL);
78 break;
79 default:
80 error("definition keyword expected");
81 }
82 scan(TOK_SEMICOLON, &tok);
83 isdefined(defp);
84 return (defp);
85 }
86
87 static
88 isdefined(defp)
89 definition *defp;
90 {
91 STOREVAL(&defined, defp);
92 }
93
94
95 static
96 def_struct(defp)
97 definition *defp;
98 {
99 token tok;
100 declaration dec;
101 decl_list *decls;
102 decl_list **tailp;
103
104 defp->def_kind = DEF_STRUCT;
105
106 scan(TOK_IDENT, &tok);
107 defp->def_name = tok.str;
108 scan(TOK_LBRACE, &tok);
109 tailp = &defp->def.st.decls;
110 do {
111 get_declaration(&dec, DEF_STRUCT);
112 decls = ALLOC(decl_list);
113 decls->decl = dec;
114 *tailp = decls;
115 tailp = &decls->next;
116 scan(TOK_SEMICOLON, &tok);
117 peek(&tok);
118 } while (tok.kind != TOK_RBRACE);
119 get_token(&tok);
120 *tailp = NULL;
121 }
122
123 static
124 def_program(defp)
125 definition *defp;
126 {
127 token tok;
128 version_list *vlist;
129 version_list **vtailp;
130 proc_list *plist;
131 proc_list **ptailp;
132
133 defp->def_kind = DEF_PROGRAM;
134 scan(TOK_IDENT, &tok);
135 defp->def_name = tok.str;
136 scan(TOK_LBRACE, &tok);
137 vtailp = &defp->def.pr.versions;
138 scan(TOK_VERSION, &tok);
139 do {
140 scan(TOK_IDENT, &tok);
141 vlist = ALLOC(version_list);
142 vlist->vers_name = tok.str;
143 scan(TOK_LBRACE, &tok);
144 ptailp = &vlist->procs;
145 do {
146 plist = ALLOC(proc_list);
147 get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
148 if (streq(plist->res_type, "opaque")) {
149 error("illegal result type");
150 }
151 scan(TOK_IDENT, &tok);
152 plist->proc_name = tok.str;
153 scan(TOK_LPAREN, &tok);
154 get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
155 if (streq(plist->arg_type, "opaque")) {
156 error("illegal argument type");
157 }
158 scan(TOK_RPAREN, &tok);
159 scan(TOK_EQUAL, &tok);
160 scan_num(&tok);
161 scan(TOK_SEMICOLON, &tok);
162 plist->proc_num = tok.str;
163 *ptailp = plist;
164 ptailp = &plist->next;
165 peek(&tok);
166 } while (tok.kind != TOK_RBRACE);
167 *vtailp = vlist;
168 vtailp = &vlist->next;
169 scan(TOK_RBRACE, &tok);
170 scan(TOK_EQUAL, &tok);
171 scan_num(&tok);
172 vlist->vers_num = tok.str;
173 scan(TOK_SEMICOLON, &tok);
174 scan2(TOK_VERSION, TOK_RBRACE, &tok);
175 } while (tok.kind == TOK_VERSION);
176 scan(TOK_EQUAL, &tok);
177 scan_num(&tok);
178 defp->def.pr.prog_num = tok.str;
179 *vtailp = NULL;
180 }
181
182 static
183 def_enum(defp)
184 definition *defp;
185 {
186 token tok;
187 enumval_list *elist;
188 enumval_list **tailp;
189
190 defp->def_kind = DEF_ENUM;
191 scan(TOK_IDENT, &tok);
192 defp->def_name = tok.str;
193 scan(TOK_LBRACE, &tok);
194 tailp = &defp->def.en.vals;
195 do {
196 scan(TOK_IDENT, &tok);
197 elist = ALLOC(enumval_list);
198 elist->name = tok.str;
199 elist->assignment = NULL;
200 scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
201 if (tok.kind == TOK_EQUAL) {
202 scan_num(&tok);
203 elist->assignment = tok.str;
204 scan2(TOK_COMMA, TOK_RBRACE, &tok);
205 }
206 *tailp = elist;
207 tailp = &elist->next;
208 } while (tok.kind != TOK_RBRACE);
209 *tailp = NULL;
210 }
211
212 static
213 def_const(defp)
214 definition *defp;
215 {
216 token tok;
217
218 defp->def_kind = DEF_CONST;
219 scan(TOK_IDENT, &tok);
220 defp->def_name = tok.str;
221 scan(TOK_EQUAL, &tok);
222 scan2(TOK_IDENT, TOK_STRCONST, &tok);
223 defp->def.co = tok.str;
224 }
225
226 static
227 def_union(defp)
228 definition *defp;
229 {
230 token tok;
231 declaration dec;
232 case_list *cases;
233 case_list **tailp;
234
235 defp->def_kind = DEF_UNION;
236 scan(TOK_IDENT, &tok);
237 defp->def_name = tok.str;
238 scan(TOK_SWITCH, &tok);
239 scan(TOK_LPAREN, &tok);
240 get_declaration(&dec, DEF_UNION);
241 defp->def.un.enum_decl = dec;
242 tailp = &defp->def.un.cases;
243 scan(TOK_RPAREN, &tok);
244 scan(TOK_LBRACE, &tok);
245 scan(TOK_CASE, &tok);
246 while (tok.kind == TOK_CASE) {
247 scan(TOK_IDENT, &tok);
248 cases = ALLOC(case_list);
249 cases->case_name = tok.str;
250 scan(TOK_COLON, &tok);
251 get_declaration(&dec, DEF_UNION);
252 cases->case_decl = dec;
253 *tailp = cases;
254 tailp = &cases->next;
255 scan(TOK_SEMICOLON, &tok);
256 scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
257 }
258 *tailp = NULL;
259 if (tok.kind == TOK_DEFAULT) {
260 scan(TOK_COLON, &tok);
261 get_declaration(&dec, DEF_UNION);
262 defp->def.un.default_decl = ALLOC(declaration);
263 *defp->def.un.default_decl = dec;
264 scan(TOK_SEMICOLON, &tok);
265 scan(TOK_RBRACE, &tok);
266 } else {
267 defp->def.un.default_decl = NULL;
268 }
269 }
270
271
272 static
273 def_typedef(defp)
274 definition *defp;
275 {
276 declaration dec;
277
278 defp->def_kind = DEF_TYPEDEF;
279 get_declaration(&dec, DEF_TYPEDEF);
280 defp->def_name = dec.name;
281 defp->def.ty.old_prefix = dec.prefix;
282 defp->def.ty.old_type = dec.type;
283 defp->def.ty.rel = dec.rel;
284 defp->def.ty.array_max = dec.array_max;
285 }
286
287
288 static
289 get_declaration(dec, dkind)
290 declaration *dec;
291 defkind dkind;
292 {
293 token tok;
294
295 get_type(&dec->prefix, &dec->type, dkind);
296 dec->rel = REL_ALIAS;
297 if (streq(dec->type, "void")) {
298 return;
299 }
300 scan2(TOK_STAR, TOK_IDENT, &tok);
301 if (tok.kind == TOK_STAR) {
302 dec->rel = REL_POINTER;
303 scan(TOK_IDENT, &tok);
304 }
305 dec->name = tok.str;
306 if (peekscan(TOK_LBRACKET, &tok)) {
307 if (dec->rel == REL_POINTER) {
308 error("no array-of-pointer declarations -- use typedef");
309 }
310 dec->rel = REL_VECTOR;
311 scan_num(&tok);
312 dec->array_max = tok.str;
313 scan(TOK_RBRACKET, &tok);
314 } else if (peekscan(TOK_LANGLE, &tok)) {
315 if (dec->rel == REL_POINTER) {
316 error("no array-of-pointer declarations -- use typedef");
317 }
318 dec->rel = REL_ARRAY;
319 if (peekscan(TOK_RANGLE, &tok)) {
320 dec->array_max = "~0"; /* unspecified size, use max */
321 } else {
322 scan_num(&tok);
323 dec->array_max = tok.str;
324 scan(TOK_RANGLE, &tok);
325 }
326 }
327 if (streq(dec->type, "opaque")) {
328 if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
329 error("array declaration expected");
330 }
331 } else if (streq(dec->type, "string")) {
332 if (dec->rel != REL_ARRAY) {
333 error("variable-length array declaration expected");
334 }
335 }
336 }
337
338
339 static
340 get_type(prefixp, typep, dkind)
341 char **prefixp;
342 char **typep;
343 defkind dkind;
344 {
345 token tok;
346
347 *prefixp = NULL;
348 get_token(&tok);
349 switch (tok.kind) {
350 case TOK_IDENT:
351 *typep = tok.str;
352 break;
353 case TOK_STRUCT:
354 case TOK_ENUM:
355 case TOK_UNION:
356 *prefixp = tok.str;
357 scan(TOK_IDENT, &tok);
358 *typep = tok.str;
359 break;
360 case TOK_UNSIGNED:
361 unsigned_dec(typep);
362 break;
363 case TOK_SHORT:
364 *typep = "short";
365 (void) peekscan(TOK_INT, &tok);
366 break;
367 case TOK_LONG:
368 *typep = "long";
369 (void) peekscan(TOK_INT, &tok);
370 break;
371 case TOK_VOID:
372 if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
373 error("voids allowed only inside union and program definitions");
374 }
375 *typep = tok.str;
376 break;
377 case TOK_STRING:
378 case TOK_OPAQUE:
379 case TOK_CHAR:
380 case TOK_INT:
381 case TOK_FLOAT:
382 case TOK_DOUBLE:
383 case TOK_BOOL:
384 *typep = tok.str;
385 break;
386 default:
387 error("expected type specifier");
388 }
389 }
390
391
392 static
393 unsigned_dec(typep)
394 char **typep;
395 {
396 token tok;
397
398 peek(&tok);
399 switch (tok.kind) {
400 case TOK_CHAR:
401 get_token(&tok);
402 *typep = "u_char";
403 break;
404 case TOK_SHORT:
405 get_token(&tok);
406 *typep = "u_short";
407 (void) peekscan(TOK_INT, &tok);
408 break;
409 case TOK_LONG:
410 get_token(&tok);
411 *typep = "u_long";
412 (void) peekscan(TOK_INT, &tok);
413 break;
414 case TOK_INT:
415 get_token(&tok);
416 *typep = "u_int";
417 break;
418 default:
419 *typep = "u_int";
420 break;
421 }
422 }
423