• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/scripts/genksyms/
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
30static int is_typedef;
31static int is_extern;
32static char *current_name;
33static struct string_list *decl_spec;
34
35static void yyerror(const char *);
36
37static inline void
38remove_node(struct string_list **p)
39{
40  struct string_list *node = *p;
41  *p = node->next;
42  free_node(node);
43}
44
45static inline void
46remove_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 EXTENSION_KEYW
65%token FLOAT_KEYW
66%token INLINE_KEYW
67%token INT_KEYW
68%token LONG_KEYW
69%token REGISTER_KEYW
70%token RESTRICT_KEYW
71%token SHORT_KEYW
72%token SIGNED_KEYW
73%token STATIC_KEYW
74%token STRUCT_KEYW
75%token TYPEDEF_KEYW
76%token UNION_KEYW
77%token UNSIGNED_KEYW
78%token VOID_KEYW
79%token VOLATILE_KEYW
80%token TYPEOF_KEYW
81
82%token EXPORT_SYMBOL_KEYW
83
84%token ASM_PHRASE
85%token ATTRIBUTE_PHRASE
86%token BRACE_PHRASE
87%token BRACKET_PHRASE
88%token EXPRESSION_PHRASE
89
90%token CHAR
91%token DOTS
92%token IDENT
93%token INT
94%token REAL
95%token STRING
96%token TYPE
97%token OTHER
98%token FILENAME
99
100%%
101
102declaration_seq:
103	declaration
104	| declaration_seq declaration
105	;
106
107declaration:
108	{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; }
109	declaration1
110	{ free_list(*$2, NULL); *$2 = NULL; }
111	;
112
113declaration1:
114	EXTENSION_KEYW TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
115		{ $$ = $4; }
116	| TYPEDEF_KEYW { is_typedef = 1; } simple_declaration
117		{ $$ = $3; }
118	| simple_declaration
119	| function_definition
120	| asm_definition
121	| export_definition
122	| error ';'				{ $$ = $2; }
123	| error '}'				{ $$ = $2; }
124	;
125
126simple_declaration:
127	decl_specifier_seq_opt init_declarator_list_opt ';'
128		{ if (current_name) {
129		    struct string_list *decl = (*$3)->next;
130		    (*$3)->next = NULL;
131		    add_symbol(current_name,
132			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
133			       decl, is_extern);
134		    current_name = NULL;
135		  }
136		  $$ = $3;
137		}
138	;
139
140init_declarator_list_opt:
141	/* empty */				{ $$ = NULL; }
142	| init_declarator_list
143	;
144
145init_declarator_list:
146	init_declarator
147		{ struct string_list *decl = *$1;
148		  *$1 = NULL;
149		  add_symbol(current_name,
150			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
151		  current_name = NULL;
152		  $$ = $1;
153		}
154	| init_declarator_list ',' init_declarator
155		{ struct string_list *decl = *$3;
156		  *$3 = NULL;
157		  free_list(*$2, NULL);
158		  *$2 = decl_spec;
159		  add_symbol(current_name,
160			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
161		  current_name = NULL;
162		  $$ = $3;
163		}
164	;
165
166init_declarator:
167	declarator asm_phrase_opt attribute_opt initializer_opt
168		{ $$ = $4 ? $4 : $3 ? $3 : $2 ? $2 : $1; }
169	;
170
171/* Hang on to the specifiers so that we can reuse them.  */
172decl_specifier_seq_opt:
173	/* empty */				{ decl_spec = NULL; }
174	| decl_specifier_seq
175	;
176
177decl_specifier_seq:
178	decl_specifier				{ decl_spec = *$1; }
179	| decl_specifier_seq decl_specifier	{ decl_spec = *$2; }
180	;
181
182decl_specifier:
183	storage_class_specifier
184		{ /* Version 2 checksumming ignores storage class, as that
185		     is really irrelevant to the linkage.  */
186		  remove_node($1);
187		  $$ = $1;
188		}
189	| type_specifier
190	;
191
192storage_class_specifier:
193	AUTO_KEYW
194	| REGISTER_KEYW
195	| STATIC_KEYW
196	| EXTERN_KEYW	{ is_extern = 1; $$ = $1; }
197	| INLINE_KEYW	{ is_extern = 0; $$ = $1; }
198	;
199
200type_specifier:
201	simple_type_specifier
202	| cvar_qualifier
203	| TYPEOF_KEYW '(' decl_specifier_seq '*' ')'
204	| TYPEOF_KEYW '(' decl_specifier_seq ')'
205
206	/* References to s/u/e's defined elsewhere.  Rearrange things
207	   so that it is easier to expand the definition fully later.  */
208	| STRUCT_KEYW IDENT
209		{ remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; }
210	| UNION_KEYW IDENT
211		{ remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; }
212	| ENUM_KEYW IDENT
213		{ remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; }
214
215	/* Full definitions of an s/u/e.  Record it.  */
216	| STRUCT_KEYW IDENT class_body
217		{ struct string_list *s = *$3, *i = *$2, *r;
218		  r = copy_node(i); r->tag = SYM_STRUCT;
219		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
220		  add_symbol(i->string, SYM_STRUCT, s, is_extern);
221		  $$ = $3;
222		}
223	| UNION_KEYW IDENT class_body
224		{ struct string_list *s = *$3, *i = *$2, *r;
225		  r = copy_node(i); r->tag = SYM_UNION;
226		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
227		  add_symbol(i->string, SYM_UNION, s, is_extern);
228		  $$ = $3;
229		}
230	| ENUM_KEYW IDENT BRACE_PHRASE
231		{ struct string_list *s = *$3, *i = *$2, *r;
232		  r = copy_node(i); r->tag = SYM_ENUM;
233		  r->next = (*$1)->next; *$3 = r; (*$1)->next = NULL;
234		  add_symbol(i->string, SYM_ENUM, s, is_extern);
235		  $$ = $3;
236		}
237
238	/* Anonymous s/u/e definitions.  Nothing needs doing.  */
239	| ENUM_KEYW BRACE_PHRASE			{ $$ = $2; }
240	| STRUCT_KEYW class_body			{ $$ = $2; }
241	| UNION_KEYW class_body				{ $$ = $2; }
242	;
243
244simple_type_specifier:
245	CHAR_KEYW
246	| SHORT_KEYW
247	| INT_KEYW
248	| LONG_KEYW
249	| SIGNED_KEYW
250	| UNSIGNED_KEYW
251	| FLOAT_KEYW
252	| DOUBLE_KEYW
253	| VOID_KEYW
254	| BOOL_KEYW
255	| TYPE			{ (*$1)->tag = SYM_TYPEDEF; $$ = $1; }
256	;
257
258ptr_operator:
259	'*' cvar_qualifier_seq_opt
260		{ $$ = $2 ? $2 : $1; }
261	;
262
263cvar_qualifier_seq_opt:
264	/* empty */					{ $$ = NULL; }
265	| cvar_qualifier_seq
266	;
267
268cvar_qualifier_seq:
269	cvar_qualifier
270	| cvar_qualifier_seq cvar_qualifier		{ $$ = $2; }
271	;
272
273cvar_qualifier:
274	CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE
275	| RESTRICT_KEYW
276		{ /* restrict has no effect in prototypes so ignore it */
277		  remove_node($1);
278		  $$ = $1;
279		}
280	;
281
282declarator:
283	ptr_operator declarator			{ $$ = $2; }
284	| direct_declarator
285	;
286
287direct_declarator:
288	IDENT
289		{ if (current_name != NULL) {
290		    error_with_pos("unexpected second declaration name");
291		    YYERROR;
292		  } else {
293		    current_name = (*$1)->string;
294		    $$ = $1;
295		  }
296		}
297	| direct_declarator '(' parameter_declaration_clause ')'
298		{ $$ = $4; }
299	| direct_declarator '(' error ')'
300		{ $$ = $4; }
301	| direct_declarator BRACKET_PHRASE
302		{ $$ = $2; }
303	| '(' declarator ')'
304		{ $$ = $3; }
305	| '(' error ')'
306		{ $$ = $3; }
307	;
308
309/* Nested declarators differ from regular declarators in that they do
310   not record the symbols they find in the global symbol table.  */
311nested_declarator:
312	ptr_operator nested_declarator		{ $$ = $2; }
313	| direct_nested_declarator
314	;
315
316direct_nested_declarator:
317	IDENT
318	| TYPE
319	| direct_nested_declarator '(' parameter_declaration_clause ')'
320		{ $$ = $4; }
321	| direct_nested_declarator '(' error ')'
322		{ $$ = $4; }
323	| direct_nested_declarator BRACKET_PHRASE
324		{ $$ = $2; }
325	| '(' nested_declarator ')'
326		{ $$ = $3; }
327	| '(' error ')'
328		{ $$ = $3; }
329	;
330
331parameter_declaration_clause:
332	parameter_declaration_list_opt DOTS		{ $$ = $2; }
333	| parameter_declaration_list_opt
334	| parameter_declaration_list ',' DOTS		{ $$ = $3; }
335	;
336
337parameter_declaration_list_opt:
338	/* empty */					{ $$ = NULL; }
339	| parameter_declaration_list
340	;
341
342parameter_declaration_list:
343	parameter_declaration
344	| parameter_declaration_list ',' parameter_declaration
345		{ $$ = $3; }
346	;
347
348parameter_declaration:
349	decl_specifier_seq m_abstract_declarator
350		{ $$ = $2 ? $2 : $1; }
351	;
352
353m_abstract_declarator:
354	ptr_operator m_abstract_declarator
355		{ $$ = $2 ? $2 : $1; }
356	| direct_m_abstract_declarator
357	;
358
359direct_m_abstract_declarator:
360	/* empty */					{ $$ = NULL; }
361	| IDENT
362		{ /* For version 2 checksums, we don't want to remember
363		     private parameter names.  */
364		  remove_node($1);
365		  $$ = $1;
366		}
367	/* This wasn't really a typedef name but an identifier that
368	   shadows one.  */
369	| TYPE
370		{ remove_node($1);
371		  $$ = $1;
372		}
373	| direct_m_abstract_declarator '(' parameter_declaration_clause ')'
374		{ $$ = $4; }
375	| direct_m_abstract_declarator '(' error ')'
376		{ $$ = $4; }
377	| direct_m_abstract_declarator BRACKET_PHRASE
378		{ $$ = $2; }
379	| '(' m_abstract_declarator ')'
380		{ $$ = $3; }
381	| '(' error ')'
382		{ $$ = $3; }
383	;
384
385function_definition:
386	decl_specifier_seq_opt declarator BRACE_PHRASE
387		{ struct string_list *decl = *$2;
388		  *$2 = NULL;
389		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
390		  $$ = $3;
391		}
392	;
393
394initializer_opt:
395	/* empty */					{ $$ = NULL; }
396	| initializer
397	;
398
399/* We never care about the contents of an initializer.  */
400initializer:
401	'=' EXPRESSION_PHRASE
402		{ remove_list($2, &(*$1)->next); $$ = $2; }
403	;
404
405class_body:
406	'{' member_specification_opt '}'		{ $$ = $3; }
407	| '{' error '}'					{ $$ = $3; }
408	;
409
410member_specification_opt:
411	/* empty */					{ $$ = NULL; }
412	| member_specification
413	;
414
415member_specification:
416	member_declaration
417	| member_specification member_declaration	{ $$ = $2; }
418	;
419
420member_declaration:
421	decl_specifier_seq_opt member_declarator_list_opt ';'
422		{ $$ = $3; }
423	| error ';'
424		{ $$ = $2; }
425	;
426
427member_declarator_list_opt:
428	/* empty */					{ $$ = NULL; }
429	| member_declarator_list
430	;
431
432member_declarator_list:
433	member_declarator
434	| member_declarator_list ',' member_declarator	{ $$ = $3; }
435	;
436
437member_declarator:
438	nested_declarator attribute_opt			{ $$ = $2 ? $2 : $1; }
439	| IDENT member_bitfield_declarator		{ $$ = $2; }
440	| member_bitfield_declarator
441	;
442
443member_bitfield_declarator:
444	':' EXPRESSION_PHRASE				{ $$ = $2; }
445	;
446
447attribute_opt:
448	/* empty */					{ $$ = NULL; }
449	| attribute_opt ATTRIBUTE_PHRASE
450	;
451
452asm_definition:
453	ASM_PHRASE ';'					{ $$ = $2; }
454	;
455
456asm_phrase_opt:
457	/* empty */					{ $$ = NULL; }
458	| ASM_PHRASE
459	;
460
461export_definition:
462	EXPORT_SYMBOL_KEYW '(' IDENT ')' ';'
463		{ export_symbol((*$3)->string); $$ = $5; }
464	;
465
466
467%%
468
469static void
470yyerror(const char *e)
471{
472  error_with_pos("%s", e);
473}
474