home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume6 / rpc2 / part10 / rpc / rpcgen / rpc_parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  7.9 KB  |  407 lines

  1. #ifndef lint 
  2. static char sccsid[] = "@(#)rpc_parse.c 1.1 86/03/26 (C) 1986 SMI";
  3. #endif
  4.  
  5. /* 
  6.  * rpc_parse.c, Parser for the RPC protocol compiler
  7.  * Copyright (C) 1986 Sun Microsystems, Inc.
  8.  */
  9.  
  10. #include <stdio.h> 
  11. #include "rpc_util.h"
  12. #include "rpc_scan.h"
  13. #include "rpc_parse.h"
  14.  
  15. /*
  16.  * return the next definition you see
  17.  */
  18. definition *
  19. get_definition()
  20. {
  21.     definition *defp;
  22.     token tok;
  23.  
  24.  
  25.     defp = ALLOC(definition);
  26.     get_token(&tok);
  27.     switch (tok.kind) {
  28.     case TOK_STRUCT:
  29.         def_struct(defp);
  30.         break;
  31.     case TOK_UNION:
  32.         def_union(defp);
  33.         break;
  34.     case TOK_TYPEDEF:
  35.         def_typedef(defp);
  36.         break;
  37.     case TOK_ARRAY:
  38.         def_array(defp);
  39.         break;
  40.     case TOK_ENUM:
  41.         def_enum(defp);
  42.         break;
  43.     case TOK_PROGRAM:
  44.         def_program(defp);    
  45.         break;
  46.     case TOK_EOF:
  47.         return(NULL);    
  48.         break;
  49.     default:
  50.         error("definition keyword expected");
  51.     }
  52.     scan(TOK_SEMICOLON,&tok);
  53.     isdefined(defp);
  54.     return(defp);
  55. }
  56.  
  57. static 
  58. isdefined(defp)
  59.     definition *defp;
  60. {
  61.     STOREVAL(&defined,defp); 
  62. }
  63.  
  64.  
  65. static
  66. def_struct(defp)
  67.     definition *defp;
  68. {
  69.     token tok;
  70.     declaration dec;
  71.     decl_list *decls;
  72.     decl_list **tailp;
  73.  
  74.     defp->def_kind = DEF_STRUCT;
  75.  
  76.     scan(TOK_IDENT,&tok);
  77.     defp->def_name = tok.str;
  78.     scan(TOK_LBRACE,&tok);
  79.     tailp = &defp->def.st.decls;
  80.     do {
  81.         get_declaration(&dec,DEF_STRUCT);
  82.         decls = ALLOC(decl_list);
  83.         decls->decl = dec;
  84.         *tailp = decls;
  85.         tailp = &decls->next;
  86.         scan(TOK_SEMICOLON,&tok);
  87.         peek(&tok);    
  88.     } while (tok.kind != TOK_RBRACE);
  89.     get_token(&tok);    
  90.     *tailp = NULL;    
  91. }
  92.  
  93. static
  94. def_program(defp)
  95.     definition *defp;
  96. {
  97.     token tok;
  98.     version_list *vlist;
  99.     version_list **vtailp;
  100.     proc_list *plist;
  101.     proc_list **ptailp;
  102.     
  103.     defp->def_kind = DEF_PROGRAM;
  104.     scan(TOK_IDENT,&tok);
  105.     defp->def_name = tok.str;
  106.     scan(TOK_LBRACE,&tok);
  107.     vtailp = &defp->def.pr.versions;
  108.     scan(TOK_VERSION,&tok);
  109.     do {
  110.         scan(TOK_IDENT,&tok);
  111.         vlist = ALLOC(version_list);
  112.         vlist->vers_name = tok.str;
  113.         scan(TOK_LBRACE,&tok);
  114.         ptailp = &vlist->procs;
  115.         do {
  116.             plist = ALLOC(proc_list);
  117.             get_type(&plist->res_prefix,&plist->res_type,DEF_PROGRAM);
  118.             if (streq(plist->res_type,"string") || 
  119.                     streq(plist->res_type,"opaque")) {
  120.                 error("illegal result type");
  121.             }
  122.             scan(TOK_IDENT,&tok);
  123.             plist->proc_name = tok.str;
  124.             scan(TOK_LPAREN,&tok);
  125.             get_type(&plist->arg_prefix,&plist->arg_type,DEF_PROGRAM);
  126.             if (streq(plist->arg_type,"string") || 
  127.                     streq(plist->arg_type,"opaque")) {
  128.                 error("illegal argument type");
  129.             }
  130.             scan(TOK_RPAREN,&tok);
  131.             scan(TOK_EQUAL,&tok);
  132.             scan_num(&tok);
  133.             scan(TOK_SEMICOLON,&tok);
  134.             plist->proc_num = tok.str;
  135.             *ptailp = plist;
  136.             ptailp = &plist->next;
  137.             peek(&tok);
  138.         } while (tok.kind != TOK_RBRACE);
  139.         *vtailp = vlist;
  140.         vtailp = &vlist->next;
  141.         scan(TOK_RBRACE,&tok);
  142.         scan(TOK_EQUAL,&tok);
  143.         scan_num(&tok);
  144.         vlist->vers_num = tok.str;
  145.         scan(TOK_SEMICOLON,&tok);
  146.         scan2(TOK_VERSION,TOK_RBRACE,&tok);
  147.     } while (tok.kind == TOK_VERSION);
  148.     scan(TOK_EQUAL, &tok);
  149.     scan_num(&tok);
  150.     defp->def.pr.prog_num = tok.str;
  151.     *vtailp = NULL;
  152. }
  153.     
  154. static    
  155. def_enum(defp)
  156.     definition *defp;
  157. {
  158.     token tok;
  159.     enumval_list *elist;
  160.     enumval_list **tailp;
  161.  
  162.     defp->def_kind = DEF_ENUM;
  163.     scan(TOK_IDENT,&tok);
  164.     defp->def_name = tok.str;
  165.     scan(TOK_LBRACE,&tok);
  166.     tailp = &defp->def.en.vals;
  167.     do {
  168.         scan(TOK_IDENT,&tok);
  169.         elist = ALLOC(enumval_list);
  170.         elist->name = tok.str;
  171.         elist->assignment = NULL;
  172.         scan3(TOK_COMMA,TOK_RBRACE,TOK_EQUAL,&tok);    
  173.         if (tok.kind == TOK_EQUAL) {
  174.             scan_num(&tok);
  175.             elist->assignment = tok.str;
  176.             scan2(TOK_COMMA,TOK_RBRACE,&tok);
  177.         }
  178.         *tailp = elist;
  179.         tailp = &elist->next;
  180.     } while (tok.kind != TOK_RBRACE);
  181.     *tailp = NULL;
  182. }
  183.     
  184. static
  185. def_array(defp)
  186.     definition *defp;
  187. {
  188.     token tok;
  189.     declaration dec;
  190.  
  191.     defp->def_kind = DEF_ARRAY;
  192.     scan(TOK_IDENT,&tok);
  193.     defp->def_name = tok.str;
  194.     scan(TOK_LBRACE,&tok);
  195.     get_declaration(&dec,DEF_ARRAY);
  196.     if (! streq(dec.type,"u_int")) {
  197.         error("array length must be of type unsigned");
  198.     }
  199.     if (dec.rel != REL_ALIAS) {
  200.         error("array length may not be pointer or vector");
  201.     }
  202.     scan(TOK_SEMICOLON,&tok);
  203.     defp->def.ar.len_name = dec.name;
  204.     get_declaration(&dec,DEF_ARRAY);
  205.     if (dec.rel != REL_VECTOR) {
  206.         error("expected array declaration");
  207.     }
  208.     if (streq(dec.type,"string")) {
  209.         error("string declarations don't make sense here");
  210.     }
  211.     scan(TOK_SEMICOLON,&tok);
  212.     defp->def.ar.array_prefix = dec.prefix;
  213.     defp->def.ar.array_type = dec.type;
  214.     defp->def.ar.array_name = dec.name;
  215.     defp->def.ar.array_max = dec.array_max;
  216.     scan(TOK_RBRACE,&tok);
  217. }
  218.  
  219.  
  220.  
  221. static
  222. def_union(defp)
  223.     definition *defp;
  224.     token tok;
  225.     declaration dec;
  226.     case_list *cases;
  227.     case_list **tailp;
  228.  
  229.     defp->def_kind = DEF_UNION;
  230.     scan(TOK_IDENT,&tok);
  231.     defp->def_name = tok.str;
  232.     scan(TOK_SWITCH,&tok);
  233.     scan(TOK_LPAREN,&tok);
  234.     get_declaration(&dec,DEF_UNION);
  235.     defp->def.un.enum_decl = dec;
  236.     tailp = &defp->def.un.cases;
  237.     scan(TOK_RPAREN,&tok);
  238.     scan(TOK_LBRACE,&tok);
  239.     scan(TOK_CASE, &tok);
  240.     while (tok.kind == TOK_CASE) {
  241.         scan(TOK_IDENT,&tok);
  242.         cases = ALLOC(case_list);
  243.         cases->case_name = tok.str;
  244.         scan(TOK_COLON,&tok);
  245.         get_declaration(&dec,DEF_UNION);
  246.         cases->case_decl = dec;
  247.         *tailp = cases;
  248.         tailp = &cases->next;
  249.         scan(TOK_SEMICOLON,&tok);
  250.         scan3(TOK_CASE,TOK_DEFAULT,TOK_RBRACE,&tok);
  251.     }
  252.     *tailp = NULL;
  253.     if (tok.kind == TOK_DEFAULT) {
  254.         scan(TOK_COLON,&tok);
  255.         get_declaration(&dec,DEF_UNION);
  256.         defp->def.un.default_decl =  ALLOC(declaration);
  257.         *defp->def.un.default_decl = dec;
  258.         scan(TOK_SEMICOLON,&tok);
  259.         scan(TOK_RBRACE,&tok);
  260.     }
  261. }
  262.  
  263.  
  264. static
  265. def_typedef(defp)
  266.     definition *defp;
  267.     declaration dec;
  268.  
  269.     defp->def_kind = DEF_TYPEDEF;
  270.     get_declaration(&dec,DEF_TYPEDEF);
  271.     defp->def_name = dec.name;
  272.     defp->def.ty.old_prefix = dec.prefix;
  273.     defp->def.ty.old_type = dec.type;
  274.     defp->def.ty.rel = dec.rel;
  275.     defp->def.ty.array_max = dec.array_max;
  276. }
  277.  
  278.  
  279. static
  280. get_declaration(dec,dkind)
  281.     declaration *dec;
  282.     defkind dkind;
  283. {
  284.     token tok;
  285.  
  286.     get_type(&dec->prefix,&dec->type,dkind);
  287.     dec->rel = REL_ALIAS;
  288.     scan2(TOK_STAR,TOK_IDENT,&tok);
  289.     if (tok.kind == TOK_STAR) {
  290.         dec->rel = REL_POINTER;
  291.         scan(TOK_IDENT,&tok);
  292.     }
  293.     dec->name = tok.str; 
  294.     if (peekscan(TOK_LBRACKET,&tok)) {
  295.         if (dec->rel == REL_POINTER) {
  296.             error("no array-of-pointer declarations -- use typedef");
  297.         }
  298.         dec->rel = REL_VECTOR;
  299.         if (streq(dec->type,"string") && peekscan(TOK_RBRACKET,&tok)) {
  300.             dec->array_max = NULL;     /* means unspecified */
  301.         } else {    
  302.             dec->rel = REL_VECTOR;
  303.             scan_num(&tok);    
  304.             dec->array_max = tok.str;
  305.             scan(TOK_RBRACKET,&tok);
  306.         }
  307.     }
  308.     if (streq(dec->type,"opaque") || streq(dec->type,"string")) {
  309.         if (dec->rel != REL_VECTOR) {
  310.             error("vector declaration expected");
  311.         }
  312.     } else if (streq(dec->type,"void")) {
  313.         if (dec->rel != REL_ALIAS) {
  314.             error("no vector-of-void or pointer-to-void declarations");
  315.         }
  316.     }
  317. }
  318.  
  319.  
  320. static
  321. get_type(prefixp,typep, dkind)
  322.     char **prefixp;
  323.     char **typep;
  324.     defkind dkind;
  325. {
  326.     token tok;
  327.  
  328.     *prefixp = NULL; 
  329.     get_token(&tok);
  330.     switch (tok.kind) {
  331.     case TOK_IDENT:
  332.         *typep = tok.str;
  333.         break;
  334.     case TOK_STRUCT:
  335.     case TOK_ENUM:
  336.     case TOK_ARRAY:
  337.     case TOK_UNION:
  338.         *prefixp = tok.str;
  339.         scan(TOK_IDENT,&tok);    
  340.         *typep = tok.str;
  341.         break;
  342.     case TOK_UNSIGNED:
  343.         unsigned_dec(typep);
  344.         break;
  345.     case TOK_SHORT:
  346.         *typep = "short"; 
  347.         (void) peekscan(TOK_INT,&tok);
  348.         break;
  349.     case TOK_LONG:
  350.         *typep = "long"; 
  351.         (void) peekscan(TOK_INT,&tok);
  352.         break;
  353.     case TOK_VOID:
  354.         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
  355.             error("voids allowed only inside union and program definitions");
  356.         }
  357.         *typep = tok.str;
  358.         break;
  359.     case TOK_STRING:
  360.     case TOK_OPAQUE:
  361.     case TOK_CHAR:
  362.     case TOK_INT:
  363.     case TOK_FLOAT:
  364.     case TOK_DOUBLE:
  365.     case TOK_BOOL:
  366.         *typep = tok.str;
  367.         break;    
  368.     default:
  369.         error("expected type specifier");
  370.     }
  371. }
  372.  
  373.  
  374. static
  375. unsigned_dec(typep)
  376.     char **typep;
  377. {
  378.     token tok;
  379.  
  380.     peek(&tok);
  381.     switch (tok.kind) {
  382.     case TOK_CHAR:
  383.         get_token(&tok);
  384.         *typep = "u_char";
  385.         break;
  386.     case TOK_SHORT:
  387.         get_token(&tok);
  388.         *typep = "u_short";
  389.         (void) peekscan(TOK_INT,&tok);
  390.         break;
  391.     case TOK_LONG:
  392.         get_token(&tok);
  393.         *typep = "u_long";
  394.         (void) peekscan(TOK_INT,&tok);
  395.         break;
  396.     case TOK_INT:
  397.         get_token(&tok);
  398.         *typep = "u_int";
  399.         break;
  400.     default:
  401.         *typep = "u_int";
  402.         break;
  403.     }
  404. }
  405.