Linux-2.6.12-rc2
[safe/jmp/linux-2.6] / scripts / genksyms / parse.y
1 /* C global declaration parser for genksyms.
2    Copyright 1996, 1997 Linux International.
3
4    New implementation contributed by Richard Henderson <rth@tamu.edu>
5    Based on original work by Bjorn Ekwall <bj0rn@blox.se>
6
7    This file is part of the Linux modutils.
8
9    This program is free software; you can redistribute it and/or modify it
10    under the terms of the GNU General Public License as published by the
11    Free Software Foundation; either version 2 of the License, or (at your
12    option) any later version.
13
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software Foundation,
21    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23
24 %{
25
26 #include <assert.h>
27 #include <malloc.h>
28 #include "genksyms.h"
29
30 static int is_typedef;
31 static int is_extern;
32 static char *current_name;
33 static struct string_list *decl_spec;
34
35 static void yyerror(const char *);
36
37 static inline void
38 remove_node(struct string_list **p)
39 {
40   struct string_list *node = *p;
41   *p = node->next;
42   free_node(node);
43 }
44
45 static inline void
46 remove_list(struct string_list **pb, struct string_list **pe)
47 {
48   struct string_list *b = *pb, *e = *pe;
49   *pb = e;
50   free_list(b, e);
51 }
52
53 %}
54
55 %token ASM_KEYW
56 %token ATTRIBUTE_KEYW
57 %token AUTO_KEYW
58 %token BOOL_KEYW
59 %token CHAR_KEYW
60 %token CONST_KEYW
61 %token DOUBLE_KEYW
62 %token ENUM_KEYW
63 %token EXTERN_KEYW
64 %token FLOAT_KEYW
65 %token INLINE_KEYW
66 %token INT_KEYW
67 %token LONG_KEYW
68 %token REGISTER_KEYW
69 %token RESTRICT_KEYW
70 %token SHORT_KEYW
71 %token SIGNED_KEYW
72 %token STATIC_KEYW
73 %token STRUCT_KEYW
74 %token TYPEDEF_KEYW
75 %token UNION_KEYW
76 %token UNSIGNED_KEYW
77 %token VOID_KEYW
78 %token VOLATILE_KEYW
79 %token TYPEOF_KEYW
80
81 %token EXPORT_SYMBOL_KEYW
82
83 %token ASM_PHRASE
84 %token ATTRIBUTE_PHRASE
85 %token BRACE_PHRASE
86 %token BRACKET_PHRASE
87 %token EXPRESSION_PHRASE
88
89 %token CHAR
90 %token DOTS
91 %token IDENT
92 %token INT
93 %token REAL
94 %token STRING
95 %token TYPE
96 %token OTHER
97 %token FILENAME
98
99 %%
100
101 declaration_seq:
102         declaration
103         | declaration_seq declaration
104         ;
105
106 declaration:
107         { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
108         declaration1
109         { free_list(*$2, NULL); *$2 = NULL; }
110         ;
111
112 declaration1:
113         TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
114                 { $$ = $3; }
115         | simple_declaration
116         | function_definition
117         | asm_definition
118         | export_definition
119         | error ';'                             { $$ = $2; }
120         | error '}'                             { $$ = $2; }
121         ;
122
123 simple_declaration:
124         decl_specifier_seq_opt init_declarator_list_opt ';'
125                 { if (current_name) {
126                     struct string_list *decl = (*$3)->next;
127                     (*$3)->next = NULL;
128                     add_symbol(current_name,
129                                is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
130                                decl, is_extern);
131                     current_name = NULL;
132                   }
133                   $$ = $3;
134                 }
135         ;
136
137 init_declarator_list_opt:
138         /* empty */                             { $$ = NULL; }
139         | init_declarator_list
140         ;
141
142 init_declarator_list:
143         init_declarator
144                 { struct string_list *decl = *$1;
145                   *$1 = NULL;
146                   add_symbol(current_name,
147                              is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
148                   current_name = NULL;
149                   $$ = $1;
150                 }
151         | init_declarator_list ',' init_declarator
152                 { struct string_list *decl = *$3;
153                   *$3 = NULL;
154                   free_list(*$2, NULL);
155                   *$2 = decl_spec;
156                   add_symbol(current_name,
157                              is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
158                   current_name = NULL;
159                   $$ = $3;
160                 }
161         ;
162
163 init_declarator:
164         declarator asm_phrase_opt attribute_opt initializer_opt
165                 { $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
166         ;
167
168 /* Hang on to the specifiers so that we can reuse them.  */
169 decl_specifier_seq_opt:
170         /* empty */                             { decl_spec = NULL; }
171         | decl_specifier_seq
172         ;
173
174 decl_specifier_seq:
175         decl_specifier                          { decl_spec = *$1; }
176         | decl_specifier_seq decl_specifier     { decl_spec = *$2; }
177         ;
178
179 decl_specifier:
180         storage_class_specifier
181                 { /* Version 2 checksumming ignores storage class, as that
182                      is really irrelevant to the linkage.  */
183                   remove_node($1);
184                   $$ = $1;
185                 }
186         | type_specifier
187         ;
188
189 storage_class_specifier:
190         AUTO_KEYW
191         | REGISTER_KEYW
192         | STATIC_KEYW
193         | EXTERN_KEYW   { is_extern = 1; $$ = $1; }
194         | INLINE_KEYW   { is_extern = 0; $$ = $1; }
195         ;
196
197 type_specifier:
198         simple_type_specifier
199         | cvar_qualifier
200         | TYPEOF_KEYW '(' decl_specifier_seq ')'
201
202         /* References to s/u/e's defined elsewhere.  Rearrange things
203            so that it is easier to expand the definition fully later.  */
204         | STRUCT_KEYW IDENT
205                 { remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
206         | UNION_KEYW IDENT
207                 { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
208         | ENUM_KEYW IDENT
209                 { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
210
211         /* Full definitions of an s/u/e.  Record it.  */
212         | STRUCT_KEYW IDENT class_body
213                 { struct string_list *s = *$3, *i = *$2, *r;
214                   r = copy_node(i); r->tag = SYM_STRUCT;
215                   r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
216                   add_symbol(i->string, SYM_STRUCT, s, is_extern);
217                   $$ = $3;
218                 }
219         | UNION_KEYW IDENT class_body
220                 { struct string_list *s = *$3, *i = *$2, *r;
221                   r = copy_node(i); r->tag = SYM_UNION;
222                   r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
223                   add_symbol(i->string, SYM_UNION, s, is_extern);
224                   $$ = $3;
225                 }
226         | ENUM_KEYW IDENT BRACE_PHRASE
227                 { struct string_list *s = *$3, *i = *$2, *r;
228                   r = copy_node(i); r->tag = SYM_ENUM;
229                   r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
230                   add_symbol(i->string, SYM_ENUM, s, is_extern);
231                   $$ = $3;
232                 }
233
234         /* Anonymous s/u/e definitions.  Nothing needs doing.  */
235         | ENUM_KEYW BRACE_PHRASE                        { $$ = $2; }
236         | STRUCT_KEYW class_body                        { $$ = $2; }
237         | UNION_KEYW class_body                         { $$ = $2; }
238         ;
239
240 simple_type_specifier:
241         CHAR_KEYW
242         | SHORT_KEYW
243         | INT_KEYW
244         | LONG_KEYW
245         | SIGNED_KEYW
246         | UNSIGNED_KEYW
247         | FLOAT_KEYW
248         | DOUBLE_KEYW
249         | VOID_KEYW
250         | BOOL_KEYW
251         | TYPE                  { (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
252         ;
253
254 ptr_operator:
255         '*' cvar_qualifier_seq_opt
256                 { $$ = $2 ? $2 : $1; }
257         ;
258
259 cvar_qualifier_seq_opt:
260         /* empty */                                     { $$ = NULL; }
261         | cvar_qualifier_seq
262         ;
263
264 cvar_qualifier_seq:
265         cvar_qualifier
266         | cvar_qualifier_seq cvar_qualifier             { $$ = $2; }
267         ;
268
269 cvar_qualifier:
270         CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
271         | RESTRICT_KEYW
272                 { /* restrict has no effect in prototypes so ignore it */
273                   remove_node($1);
274                   $$ = $1;
275                 }
276         ;
277
278 declarator:
279         ptr_operator declarator                 { $$ = $2; }
280         | direct_declarator
281         ;
282
283 direct_declarator:
284         IDENT
285                 { if (current_name != NULL) {
286                     error_with_pos("unexpected second declaration name");
287                     YYERROR;
288                   } else {
289                     current_name = (*$1)->string;
290                     $$ = $1;
291                   }
292                 }
293         | direct_declarator '(' parameter_declaration_clause ')'
294                 { $$ = $4; }
295         | direct_declarator '(' error ')'
296                 { $$ = $4; }
297         | direct_declarator BRACKET_PHRASE
298                 { $$ = $2; }
299         | '(' declarator ')'
300                 { $$ = $3; }
301         | '(' error ')'
302                 { $$ = $3; }
303         ;
304
305 /* Nested declarators differ from regular declarators in that they do
306    not record the symbols they find in the global symbol table.  */
307 nested_declarator:
308         ptr_operator nested_declarator          { $$ = $2; }
309         | direct_nested_declarator
310         ;
311
312 direct_nested_declarator:
313         IDENT
314         | TYPE
315         | direct_nested_declarator '(' parameter_declaration_clause ')'
316                 { $$ = $4; }
317         | direct_nested_declarator '(' error ')'
318                 { $$ = $4; }
319         | direct_nested_declarator BRACKET_PHRASE
320                 { $$ = $2; }
321         | '(' nested_declarator ')'
322                 { $$ = $3; }
323         | '(' error ')'
324                 { $$ = $3; }
325         ;
326
327 parameter_declaration_clause:
328         parameter_declaration_list_opt DOTS             { $$ = $2; }
329         | parameter_declaration_list_opt
330         | parameter_declaration_list ',' DOTS           { $$ = $3; }
331         ;
332
333 parameter_declaration_list_opt:
334         /* empty */                                     { $$ = NULL; }
335         | parameter_declaration_list
336         ;
337
338 parameter_declaration_list:
339         parameter_declaration
340         | parameter_declaration_list ',' parameter_declaration
341                 { $$ = $3; }
342         ;
343
344 parameter_declaration:
345         decl_specifier_seq m_abstract_declarator
346                 { $$ = $2 ? $2 : $1; }
347         ;
348
349 m_abstract_declarator:
350         ptr_operator m_abstract_declarator
351                 { $$ = $2 ? $2 : $1; }
352         | direct_m_abstract_declarator
353         ;
354
355 direct_m_abstract_declarator:
356         /* empty */                                     { $$ = NULL; }
357         | IDENT
358                 { /* For version 2 checksums, we don't want to remember
359                      private parameter names.  */
360                   remove_node($1);
361                   $$ = $1;
362                 }
363         /* This wasn't really a typedef name but an identifier that
364            shadows one.  */
365         | TYPE
366                 { remove_node($1);
367                   $$ = $1;
368                 }
369         | direct_m_abstract_declarator '(' parameter_declaration_clause ')'
370                 { $$ = $4; }
371         | direct_m_abstract_declarator '(' error ')'
372                 { $$ = $4; }
373         | direct_m_abstract_declarator BRACKET_PHRASE
374                 { $$ = $2; }
375         | '(' m_abstract_declarator ')'
376                 { $$ = $3; }
377         | '(' error ')'
378                 { $$ = $3; }
379         ;
380
381 function_definition:
382         decl_specifier_seq_opt declarator BRACE_PHRASE
383                 { struct string_list *decl = *$2;
384                   *$2 = NULL;
385                   add_symbol(current_name, SYM_NORMAL, decl, is_extern);
386                   $$ = $3;
387                 }
388         ;
389
390 initializer_opt:
391         /* empty */                                     { $$ = NULL; }
392         | initializer
393         ;
394
395 /* We never care about the contents of an initializer.  */
396 initializer:
397         '=' EXPRESSION_PHRASE
398                 { remove_list($2, &(*$1)->next); $$ = $2; }
399         ;
400
401 class_body:
402         '{' member_specification_opt '}'                { $$ = $3; }
403         | '{' error '}'                                 { $$ = $3; }
404         ;
405
406 member_specification_opt:
407         /* empty */                                     { $$ = NULL; }
408         | member_specification
409         ;
410
411 member_specification:
412         member_declaration
413         | member_specification member_declaration       { $$ = $2; }
414         ;
415
416 member_declaration:
417         decl_specifier_seq_opt member_declarator_list_opt ';'
418                 { $$ = $3; }
419         | error ';'
420                 { $$ = $2; }
421         ;
422
423 member_declarator_list_opt:
424         /* empty */                                     { $$ = NULL; }
425         | member_declarator_list
426         ;
427
428 member_declarator_list:
429         member_declarator
430         | member_declarator_list ',' member_declarator  { $$ = $3; }
431         ;
432
433 member_declarator:
434         nested_declarator attribute_opt                 { $$ = $2 ? $2 : $1; }
435         | IDENT member_bitfield_declarator              { $$ = $2; }
436         | member_bitfield_declarator
437         ;
438
439 member_bitfield_declarator:
440         ':' EXPRESSION_PHRASE                           { $$ = $2; }
441         ;
442
443 attribute_opt:
444         /* empty */                                     { $$ = NULL; }
445         | ATTRIBUTE_PHRASE
446         ;
447
448 asm_definition:
449         ASM_PHRASE ';'                                  { $$ = $2; }
450         ;
451
452 asm_phrase_opt:
453         /* empty */                                     { $$ = NULL; }
454         | ASM_PHRASE
455         ;
456
457 export_definition:
458         EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
459                 { export_symbol((*$3)->string); $$ = $5; }
460         ;
461
462
463 %%
464
465 static void
466 yyerror(const char *e)
467 {
468   error_with_pos("%s", e);
469 }