Header generation working.
[portablexdr.git] / rpcgen_parse.y
1 /* rpcgen - Generate XDR bindings automatically.    -*- text -*-
2  * Copyright (C) 2008 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 %{
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "rpcgen_int.h"
24
25 extern void yyerror (const char *str);
26 %}
27
28 %union {
29   char *str;
30   struct type *type;
31   struct decl *decl;
32   struct enum_value *enum_value;
33   struct union_case *union_case;
34   struct cons *list;
35 }
36
37 %type <type> type_ident
38 %type <str> const
39 %type <decl> decl
40 %type <decl> simple_decl fixed_array_decl variable_array_decl pointer_decl
41 %type <decl> string_decl
42 %type <enum_value> enum_value
43 %type <union_case> union_case
44 %type <list> decls enum_values union_cases
45
46 %token STRUCT
47 %token ENUM
48 %token CONST
49 %token TYPEDEF
50 %token UNION
51 %token SWITCH
52 %token CASE
53 %token DEFAULT
54 %token PROGRAM
55
56 %token UNSIGNED
57 %token SIGNED
58 %token CHAR
59 %token SHORT
60 %token INT
61 %token HYPER
62 %token DOUBLE
63 %token STRING
64 %token OPAQUE
65 %token BOOL
66
67 /* This is sometimes lumped together with the other types, but
68  * the special keyword void can only occur after "default:" in
69  * union statements.
70  */
71 %token VOID
72
73 %token <str> IDENT
74 %token <str> INTLIT
75 %token <str> STRLIT
76
77 %%
78
79 file    : /* empty */
80         | stmts
81         ;
82
83 /* Statements. */
84 stmts   : stmt ';'
85         | stmts stmt ';'
86         ;
87
88 stmt    : ENUM IDENT '{' enum_values '}'
89         {
90           struct cons *enums = list_rev ($4);
91           gen_enum ($2, enums);
92           free ($2);
93           list_free (enums);
94         }
95         | STRUCT IDENT '{' decls '}'
96         {
97           struct cons *decls = list_rev ($4);
98           gen_struct ($2, decls);
99           free ($2);
100           list_free (decls);
101         }
102         | UNION IDENT SWITCH '(' decl ')' '{' union_cases '}'
103         {
104           struct cons *cases = list_rev ($8);
105           gen_union ($2, $5, cases);
106           free ($2);
107           free_decl ($5);
108           list_free (cases);
109         }
110         | TYPEDEF decl
111         {
112           gen_typedef ($2);
113           free_decl ($2);
114         }
115         | CONST IDENT '=' const
116         {
117           gen_const ($2, $4);
118           free ($2);
119           free ($4);
120         }
121         | PROGRAM
122         {
123           error ("PortableXDR does not support SunRPC program statements");
124         }
125         ;
126
127 /* Declarations used inside structs and unions.  eg. "int foo;" */
128 decls   : decl ';'
129         { $$ = new_cons (NULL, $1, (free_fn) free_decl); }
130         | decls decl ';'
131         { $$ = new_cons ($1, $2, (free_fn) free_decl); }
132         ;
133
134 decl    : string_decl
135         | simple_decl
136         | fixed_array_decl
137         | variable_array_decl
138         | pointer_decl
139         ;
140
141 string_decl
142         : STRING IDENT '<' const '>'
143         {
144           $$ = new_decl (decl_type_simple,
145                          new_type (type_string, 0, NULL, $4),
146                          $2, NULL);
147         }
148         | STRING IDENT '<' '>'
149         {
150           $$ = new_decl (decl_type_simple,
151                          new_type (type_string, 0, NULL, NULL),
152                          $2, NULL);
153         }
154         ;
155
156 simple_decl
157         : type_ident IDENT
158         { $$ = new_decl (decl_type_simple, $1, $2, NULL); }
159         ;
160
161 fixed_array_decl
162         : type_ident IDENT '[' const ']'
163         { $$ = new_decl (decl_type_fixed_array, $1, $2, $4); }
164         ;
165
166 variable_array_decl
167         : type_ident IDENT '<' const '>'
168         { $$ = new_decl (decl_type_variable_array, $1, $2, $4); }
169         | type_ident IDENT '<' '>'
170         { $$ = new_decl (decl_type_variable_array, $1, $2, NULL); }
171         ;
172
173 pointer_decl
174         : type_ident '*' IDENT
175         { $$ = new_decl (decl_type_pointer, $1, $3, NULL); }
176         ;
177
178 /* Enumerations. */
179 enum_values
180         : enum_value
181         { $$ = new_cons (NULL, $1, (free_fn) free_enum_value); }
182         | enum_values ',' enum_value
183         { $$ = new_cons ($1, $3, (free_fn) free_enum_value); }
184         ;
185
186 enum_value
187         : IDENT
188         { $$ = new_enum_value ($1, NULL); }
189         | IDENT '=' const
190         { $$ = new_enum_value ($1, $3); }
191         ;
192
193 /* Case list inside a union. */
194 union_cases
195         : union_case ';'
196         { $$ = new_cons (NULL, $1, (free_fn) free_union_case); }
197         | union_cases union_case ';'
198         { $$ = new_cons ($1, $2, (free_fn) free_union_case); }
199         ;
200
201 union_case
202         : CASE const ':' decl
203         { $$ = new_union_case (union_case_normal, $2, $4); }
204         | DEFAULT ':' VOID
205         { $$ = new_union_case (union_case_default_void, NULL, NULL); }
206         | DEFAULT ':' decl
207         { $$ = new_union_case (union_case_default_decl, NULL, $3); }
208         ;
209
210 /* Constants, which may be integer literals or refer to previously
211  * defined constants (using "const" keyword).
212  * XXX In future we should probably allow computed constants.
213  */
214 const   : INTLIT
215         | IDENT
216         ;
217
218 /* Types.  Note 'string' and 'void' are handled by special cases above. */
219 type_ident
220         : CHAR
221         { $$ = new_type (type_char, 1, NULL, NULL); }
222         | SIGNED CHAR
223         { $$ = new_type (type_char, 1, NULL, NULL); }
224         | UNSIGNED CHAR
225         { $$ = new_type (type_char, 0, NULL, NULL); }
226         | SHORT
227         { $$ = new_type (type_short, 1, NULL, NULL); }
228         | SIGNED SHORT
229         { $$ = new_type (type_short, 1, NULL, NULL); }
230         | UNSIGNED SHORT
231         { $$ = new_type (type_short, 0, NULL, NULL); }
232         | INT
233         { $$ = new_type (type_int, 1, NULL, NULL); }
234         | SIGNED INT
235         { $$ = new_type (type_int, 1, NULL, NULL); }
236         | UNSIGNED INT
237         { $$ = new_type (type_int, 0, NULL, NULL); }
238         | HYPER
239         { $$ = new_type (type_hyper, 1, NULL, NULL); }
240         | SIGNED HYPER
241         { $$ = new_type (type_hyper, 1, NULL, NULL); }
242         | UNSIGNED HYPER
243         { $$ = new_type (type_hyper, 0, NULL, NULL); }
244         | SIGNED
245         { $$ = new_type (type_int, 1, NULL, NULL); }
246         | UNSIGNED
247         { $$ = new_type (type_int, 0, NULL, NULL); }
248         | DOUBLE
249         { $$ = new_type (type_double, 0, NULL, NULL); }
250         | OPAQUE
251         { $$ = new_type (type_opaque, 0, NULL, NULL); }
252         | BOOL
253         { $$ = new_type (type_bool, 0, NULL, NULL); }
254         | IDENT
255         { $$ = new_type (type_ident, 0, $1, NULL); }
256         ;
257
258 %%
259
260 void
261 yyerror (const char *str)
262 {
263   error ("%s", str);
264 }