Header generation working.
[portablexdr.git] / rpcgen_parse.y
index 04b073a..5ccc7dd 100644 (file)
@@ -27,9 +27,21 @@ extern void yyerror (const char *str);
 
 %union {
   char *str;
+  struct type *type;
+  struct decl *decl;
+  struct enum_value *enum_value;
+  struct union_case *union_case;
+  struct cons *list;
 }
 
+%type <type> type_ident
 %type <str> const
+%type <decl> decl
+%type <decl> simple_decl fixed_array_decl variable_array_decl pointer_decl
+%type <decl> string_decl
+%type <enum_value> enum_value
+%type <union_case> union_case
+%type <list> decls enum_values union_cases
 
 %token STRUCT
 %token ENUM
@@ -50,6 +62,7 @@ extern void yyerror (const char *str);
 %token DOUBLE
 %token STRING
 %token OPAQUE
+%token BOOL
 
 /* This is sometimes lumped together with the other types, but
  * the special keyword void can only occur after "default:" in
@@ -73,62 +86,125 @@ stmts      : stmt ';'
        ;
 
 stmt   : ENUM IDENT '{' enum_values '}'
+       {
+         struct cons *enums = list_rev ($4);
+         gen_enum ($2, enums);
+         free ($2);
+         list_free (enums);
+       }
        | STRUCT IDENT '{' decls '}'
+       {
+         struct cons *decls = list_rev ($4);
+         gen_struct ($2, decls);
+         free ($2);
+         list_free (decls);
+       }
        | UNION IDENT SWITCH '(' decl ')' '{' union_cases '}'
+       {
+         struct cons *cases = list_rev ($8);
+         gen_union ($2, $5, cases);
+         free ($2);
+         free_decl ($5);
+         list_free (cases);
+       }
        | TYPEDEF decl
+       {
+         gen_typedef ($2);
+         free_decl ($2);
+       }
        | CONST IDENT '=' const
+       {
+         gen_const ($2, $4);
+         free ($2);
+         free ($4);
+       }
        | PROGRAM
+       {
+         error ("PortableXDR does not support SunRPC program statements");
+       }
        ;
 
 /* Declarations used inside structs and unions.  eg. "int foo;" */
 decls  : decl ';'
+       { $$ = new_cons (NULL, $1, (free_fn) free_decl); }
        | decls decl ';'
+       { $$ = new_cons ($1, $2, (free_fn) free_decl); }
        ;
 
-decl   : simple_decl
+decl   : string_decl
+       | simple_decl
        | fixed_array_decl
        | variable_array_decl
        | pointer_decl
        ;
 
+string_decl
+       : STRING IDENT '<' const '>'
+       {
+         $$ = new_decl (decl_type_simple,
+                        new_type (type_string, 0, NULL, $4),
+                        $2, NULL);
+       }
+       | STRING IDENT '<' '>'
+       {
+         $$ = new_decl (decl_type_simple,
+                        new_type (type_string, 0, NULL, NULL),
+                        $2, NULL);
+       }
+       ;
+
 simple_decl
        : type_ident IDENT
+       { $$ = new_decl (decl_type_simple, $1, $2, NULL); }
        ;
 
 fixed_array_decl
        : type_ident IDENT '[' const ']'
+       { $$ = new_decl (decl_type_fixed_array, $1, $2, $4); }
        ;
 
 variable_array_decl
        : type_ident IDENT '<' const '>'
+       { $$ = new_decl (decl_type_variable_array, $1, $2, $4); }
        | type_ident IDENT '<' '>'
+       { $$ = new_decl (decl_type_variable_array, $1, $2, NULL); }
        ;
 
 pointer_decl
        : type_ident '*' IDENT
+       { $$ = new_decl (decl_type_pointer, $1, $3, NULL); }
        ;
 
 /* Enumerations. */
 enum_values
        : enum_value
+       { $$ = new_cons (NULL, $1, (free_fn) free_enum_value); }
        | enum_values ',' enum_value
+       { $$ = new_cons ($1, $3, (free_fn) free_enum_value); }
        ;
 
 enum_value
        : IDENT
+       { $$ = new_enum_value ($1, NULL); }
        | IDENT '=' const
+       { $$ = new_enum_value ($1, $3); }
        ;
 
 /* Case list inside a union. */
 union_cases
        : union_case ';'
+       { $$ = new_cons (NULL, $1, (free_fn) free_union_case); }
        | union_cases union_case ';'
+       { $$ = new_cons ($1, $2, (free_fn) free_union_case); }
        ;
 
 union_case
        : CASE const ':' decl
+       { $$ = new_union_case (union_case_normal, $2, $4); }
        | DEFAULT ':' VOID
+       { $$ = new_union_case (union_case_default_void, NULL, NULL); }
        | DEFAULT ':' decl
+       { $$ = new_union_case (union_case_default_decl, NULL, $3); }
        ;
 
 /* Constants, which may be integer literals or refer to previously
@@ -139,26 +215,44 @@ const     : INTLIT
        | IDENT
        ;
 
-/* Types. */
+/* Types.  Note 'string' and 'void' are handled by special cases above. */
 type_ident
        : CHAR
+       { $$ = new_type (type_char, 1, NULL, NULL); }
        | SIGNED CHAR
+       { $$ = new_type (type_char, 1, NULL, NULL); }
        | UNSIGNED CHAR
+       { $$ = new_type (type_char, 0, NULL, NULL); }
        | SHORT
+       { $$ = new_type (type_short, 1, NULL, NULL); }
        | SIGNED SHORT
+       { $$ = new_type (type_short, 1, NULL, NULL); }
        | UNSIGNED SHORT
+       { $$ = new_type (type_short, 0, NULL, NULL); }
        | INT
+       { $$ = new_type (type_int, 1, NULL, NULL); }
        | SIGNED INT
+       { $$ = new_type (type_int, 1, NULL, NULL); }
        | UNSIGNED INT
+       { $$ = new_type (type_int, 0, NULL, NULL); }
        | HYPER
+       { $$ = new_type (type_hyper, 1, NULL, NULL); }
        | SIGNED HYPER
+       { $$ = new_type (type_hyper, 1, NULL, NULL); }
        | UNSIGNED HYPER
+       { $$ = new_type (type_hyper, 0, NULL, NULL); }
        | SIGNED
+       { $$ = new_type (type_int, 1, NULL, NULL); }
        | UNSIGNED
+       { $$ = new_type (type_int, 0, NULL, NULL); }
        | DOUBLE
-       | STRING
+       { $$ = new_type (type_double, 0, NULL, NULL); }
        | OPAQUE
+       { $$ = new_type (type_opaque, 0, NULL, NULL); }
+       | BOOL
+       { $$ = new_type (type_bool, 0, NULL, NULL); }
        | IDENT
+       { $$ = new_type (type_ident, 0, $1, NULL); }
        ;
 
 %%