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 static 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