grammar.y revision 1.1.1.3 1 /* $Id: grammar.y,v 1.1.1.3 2011/09/10 21:19:11 christos Exp $
2 *
3 * yacc grammar for C function prototype generator
4 * This was derived from the grammar in Appendix A of
5 * "The C Programming Language" by Kernighan and Ritchie.
6 */
7 %expect 1
8 %token <text> '(' '*' '&'
9 /* identifiers that are not reserved words */
10 T_IDENTIFIER T_TYPEDEF_NAME T_DEFINE_NAME
11
12 /* storage class */
13 T_AUTO T_EXTERN T_REGISTER T_STATIC T_TYPEDEF
14 /* This keyword included for compatibility with C++. */
15 T_INLINE
16 /* This keyword included for compatibility with GCC */
17 T_EXTENSION
18
19 /* type specifiers */
20 T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID
21 T_LONG T_SHORT T_SIGNED T_UNSIGNED
22 T_ENUM T_STRUCT T_UNION
23 /* C9X new types */
24 T_Bool T_Complex T_Imaginary
25
26 /* type qualifiers */
27 T_TYPE_QUALIFIER
28
29 /* paired square brackets and everything between them: [ ... ] */
30 T_BRACKETS
31
32 %token
33 /* left brace */
34 T_LBRACE
35 /* all input to the matching right brace */
36 T_MATCHRBRACE
37
38 /* three periods */
39 T_ELLIPSIS
40
41 /* constant expression or paired braces following an equal sign */
42 T_INITIALIZER
43
44 /* string literal */
45 T_STRING_LITERAL
46
47 /* asm */
48 T_ASM
49 /* ( "string literal" ) following asm keyword */
50 T_ASMARG
51
52 /* va_dcl from <varargs.h> */
53 T_VA_DCL
54
55 %type <decl_spec> decl_specifiers decl_specifier
56 %type <decl_spec> storage_class type_specifier type_qualifier
57 %type <decl_spec> struct_or_union_specifier enum_specifier
58 %type <decl_list> init_declarator_list
59 %type <declarator> init_declarator declarator direct_declarator
60 %type <declarator> abs_declarator direct_abs_declarator
61 %type <param_list> parameter_type_list parameter_list
62 %type <parameter> parameter_declaration
63 %type <param_list> opt_identifier_list identifier_list
64 %type <text> struct_or_union pointer opt_type_qualifiers type_qualifier_list
65 any_id identifier_or_ref
66 %type <text> enumeration
67
68 %{
69 #include <stdio.h>
70 #include <ctype.h>
71 #include <string.h>
72
73 #define OPT_LINTLIBRARY 1
74
75 #ifndef TRUE
76 #define TRUE (1)
77 #endif
78
79 #ifndef FALSE
80 #define FALSE (0)
81 #endif
82
83 /* #include "cproto.h" */
84 #define MAX_TEXT_SIZE 1024
85
86 /* Prototype styles */
87 #if OPT_LINTLIBRARY
88 #define PROTO_ANSI_LLIB -2 /* form ANSI lint-library source */
89 #define PROTO_LINTLIBRARY -1 /* form lint-library source */
90 #endif
91 #define PROTO_NONE 0 /* do not output any prototypes */
92 #define PROTO_TRADITIONAL 1 /* comment out parameters */
93 #define PROTO_ABSTRACT 2 /* comment out parameter names */
94 #define PROTO_ANSI 3 /* ANSI C prototype */
95
96 typedef int PrototypeStyle;
97
98 typedef char boolean;
99
100 extern boolean types_out;
101 extern PrototypeStyle proto_style;
102
103 #define ansiLintLibrary() (proto_style == PROTO_ANSI_LLIB)
104 #define knrLintLibrary() (proto_style == PROTO_LINTLIBRARY)
105 #define lintLibrary() (knrLintLibrary() || ansiLintLibrary())
106
107 #if OPT_LINTLIBRARY
108 #define FUNC_UNKNOWN -1 /* unspecified */
109 #else
110 #define FUNC_UNKNOWN 0 /* unspecified (same as FUNC_NONE) */
111 #endif
112 #define FUNC_NONE 0 /* not a function definition */
113 #define FUNC_TRADITIONAL 1 /* traditional style */
114 #define FUNC_ANSI 2 /* ANSI style */
115 #define FUNC_BOTH 3 /* both styles */
116
117 typedef int FuncDefStyle;
118
119 /* Source file text */
120 typedef struct text {
121 char text[MAX_TEXT_SIZE]; /* source text */
122 long begin; /* offset in temporary file */
123 } Text;
124
125 /* Declaration specifier flags */
126 #define DS_NONE 0 /* default */
127 #define DS_EXTERN 1 /* contains "extern" specifier */
128 #define DS_STATIC 2 /* contains "static" specifier */
129 #define DS_CHAR 4 /* contains "char" type specifier */
130 #define DS_SHORT 8 /* contains "short" type specifier */
131 #define DS_FLOAT 16 /* contains "float" type specifier */
132 #define DS_INLINE 32 /* contains "inline" specifier */
133 #define DS_JUNK 64 /* we're not interested in this declaration */
134
135 /* This structure stores information about a declaration specifier. */
136 typedef struct decl_spec {
137 unsigned short flags; /* flags defined above */
138 char *text; /* source text */
139 long begin; /* offset in temporary file */
140 } DeclSpec;
141
142 /* This is a list of function parameters. */
143 typedef struct _ParameterList {
144 struct parameter *first; /* pointer to first parameter in list */
145 struct parameter *last; /* pointer to last parameter in list */
146 long begin_comment; /* begin offset of comment */
147 long end_comment; /* end offset of comment */
148 char *comment; /* comment at start of parameter list */
149 } ParameterList;
150
151 /* This structure stores information about a declarator. */
152 typedef struct _Declarator {
153 char *name; /* name of variable or function */
154 char *text; /* source text */
155 long begin; /* offset in temporary file */
156 long begin_comment; /* begin offset of comment */
157 long end_comment; /* end offset of comment */
158 FuncDefStyle func_def; /* style of function definition */
159 ParameterList params; /* function parameters */
160 boolean pointer; /* TRUE if it declares a pointer */
161 struct _Declarator *head; /* head function declarator */
162 struct _Declarator *func_stack; /* stack of function declarators */
163 struct _Declarator *next; /* next declarator in list */
164 } Declarator;
165
166 /* This structure stores information about a function parameter. */
167 typedef struct parameter {
168 struct parameter *next; /* next parameter in list */
169 DeclSpec decl_spec;
170 Declarator *declarator;
171 char *comment; /* comment following the parameter */
172 } Parameter;
173
174 /* This is a list of declarators. */
175 typedef struct declarator_list {
176 Declarator *first; /* pointer to first declarator in list */
177 Declarator *last; /* pointer to last declarator in list */
178 } DeclaratorList;
179
180 /* #include "symbol.h" */
181 typedef struct symbol {
182 struct symbol *next; /* next symbol in list */
183 char *name; /* name of symbol */
184 char *value; /* value of symbol (for defines) */
185 short flags; /* symbol attributes */
186 } Symbol;
187
188 /* parser stack entry type */
189 typedef union {
190 Text text;
191 DeclSpec decl_spec;
192 Parameter *parameter;
193 ParameterList param_list;
194 Declarator *declarator;
195 DeclaratorList decl_list;
196 } YYSTYPE;
197
198 /* The hash table length should be a prime number. */
199 #define SYM_MAX_HASH 251
200
201 typedef struct symbol_table {
202 Symbol *bucket[SYM_MAX_HASH]; /* hash buckets */
203 } SymbolTable;
204
205 extern SymbolTable *new_symbol_table /* Create symbol table */
206 (void);
207 extern void free_symbol_table /* Destroy symbol table */
208 (SymbolTable *s);
209 extern Symbol *find_symbol /* Lookup symbol name */
210 (SymbolTable *s, const char *n);
211 extern Symbol *new_symbol /* Define new symbol */
212 (SymbolTable *s, const char *n, const char *v, int f);
213
214 /* #include "semantic.h" */
215 extern void new_decl_spec (DeclSpec *, const char *, long, int);
216 extern void free_decl_spec (DeclSpec *);
217 extern void join_decl_specs (DeclSpec *, DeclSpec *, DeclSpec *);
218 extern void check_untagged (DeclSpec *);
219 extern Declarator *new_declarator (const char *, const char *, long);
220 extern void free_declarator (Declarator *);
221 extern void new_decl_list (DeclaratorList *, Declarator *);
222 extern void free_decl_list (DeclaratorList *);
223 extern void add_decl_list (DeclaratorList *, DeclaratorList *, Declarator *);
224 extern Parameter *new_parameter (DeclSpec *, Declarator *);
225 extern void free_parameter (Parameter *);
226 extern void new_param_list (ParameterList *, Parameter *);
227 extern void free_param_list (ParameterList *);
228 extern void add_param_list (ParameterList *, ParameterList *, Parameter *);
229 extern void new_ident_list (ParameterList *);
230 extern void add_ident_list (ParameterList *, ParameterList *, const char *);
231 extern void set_param_types (ParameterList *, DeclSpec *, DeclaratorList *);
232 extern void gen_declarations (DeclSpec *, DeclaratorList *);
233 extern void gen_prototype (DeclSpec *, Declarator *);
234 extern void gen_func_declarator (Declarator *);
235 extern void gen_func_definition (DeclSpec *, Declarator *);
236
237 extern void init_parser (void);
238 extern void process_file (FILE *infile, char *name);
239 extern char *cur_text (void);
240 extern char *cur_file_name (void);
241 extern char *implied_typedef (void);
242 extern void include_file (char *name, int convert);
243 extern char *supply_parm (int count);
244 extern char *xstrdup (const char *);
245 extern int already_declared (char *name);
246 extern int is_actual_func (Declarator *d);
247 extern int lint_ellipsis (Parameter *p);
248 extern int want_typedef (void);
249 extern void begin_tracking (void);
250 extern void begin_typedef (void);
251 extern void copy_typedef (char *s);
252 extern void ellipsis_varargs (Declarator *d);
253 extern void end_typedef (void);
254 extern void flush_varargs (void);
255 extern void fmt_library (int code);
256 extern void imply_typedef (const char *s);
257 extern void indent (FILE *outf);
258 extern void put_blankline (FILE *outf);
259 extern void put_body (FILE *outf, DeclSpec *decl_spec, Declarator *declarator);
260 extern void put_char (FILE *outf, int c);
261 extern void put_error (void);
262 extern void put_newline (FILE *outf);
263 extern void put_padded (FILE *outf, const char *s);
264 extern void put_string (FILE *outf, const char *s);
265 extern void track_in (void);
266
267 extern boolean file_comments;
268 extern FuncDefStyle func_style;
269 extern char base_file[];
270
271 #define YYMAXDEPTH 150
272
273 extern int yylex (void);
274
275 /* declaration specifier attributes for the typedef statement currently being
276 * scanned
277 */
278 static int cur_decl_spec_flags;
279
280 /* pointer to parameter list for the current function definition */
281 static ParameterList *func_params;
282
283 /* A parser semantic action sets this pointer to the current declarator in
284 * a function parameter declaration in order to catch any comments following
285 * the parameter declaration on the same line. If the lexer scans a comment
286 * and <cur_declarator> is not NULL, then the comment is attached to the
287 * declarator. To ignore subsequent comments, the lexer sets this to NULL
288 * after scanning a comment or end of line.
289 */
290 static Declarator *cur_declarator;
291
292 /* temporary string buffer */
293 static char buf[MAX_TEXT_SIZE];
294
295 /* table of typedef names */
296 static SymbolTable *typedef_names;
297
298 /* table of define names */
299 static SymbolTable *define_names;
300
301 /* table of type qualifiers */
302 static SymbolTable *type_qualifiers;
303
304 /* information about the current input file */
305 typedef struct {
306 char *base_name; /* base input file name */
307 char *file_name; /* current file name */
308 FILE *file; /* input file */
309 unsigned line_num; /* current line number in input file */
310 FILE *tmp_file; /* temporary file */
311 long begin_comment; /* tmp file offset after last written ) or ; */
312 long end_comment; /* tmp file offset after last comment */
313 boolean convert; /* if TRUE, convert function definitions */
314 boolean changed; /* TRUE if conversion done in this file */
315 } IncludeStack;
316
317 static IncludeStack *cur_file; /* current input file */
318
319 /* #include "yyerror.c" */
320
321 static int haveAnsiParam (void);
322
323
324 /* Flags to enable us to find if a procedure returns a value.
325 */
326 static int return_val; /* nonzero on BRACES iff return-expression found */
327
328 static const char *
329 dft_decl_spec (void)
330 {
331 return (lintLibrary() && !return_val) ? "void" : "int";
332 }
333
334 static int
335 haveAnsiParam (void)
336 {
337 Parameter *p;
338 if (func_params != 0) {
339 for (p = func_params->first; p != 0; p = p->next) {
340 if (p->declarator->func_def == FUNC_ANSI) {
341 return TRUE;
342 }
343 }
344 }
345 return FALSE;
346 }
347 %}
348 %%
349
350 program
351 : /* empty */
352 | translation_unit
353 ;
354
355 translation_unit
356 : external_declaration
357 | translation_unit external_declaration
358 ;
359
360 external_declaration
361 : declaration
362 | function_definition
363 | ';'
364 | linkage_specification
365 | T_ASM T_ASMARG ';'
366 | error T_MATCHRBRACE
367 {
368 yyerrok;
369 }
370 | error ';'
371 {
372 yyerrok;
373 }
374 ;
375
376 braces
377 : T_LBRACE T_MATCHRBRACE
378 ;
379
380 linkage_specification
381 : T_EXTERN T_STRING_LITERAL braces
382 {
383 /* Provide an empty action here so bison will not complain about
384 * incompatible types in the default action it normally would
385 * have generated.
386 */
387 }
388 | T_EXTERN T_STRING_LITERAL declaration
389 {
390 /* empty */
391 }
392 ;
393
394 declaration
395 : decl_specifiers ';'
396 {
397 #if OPT_LINTLIBRARY
398 if (types_out && want_typedef()) {
399 gen_declarations(&$1, (DeclaratorList *)0);
400 flush_varargs();
401 }
402 #endif
403 free_decl_spec(&$1);
404 end_typedef();
405 }
406 | decl_specifiers init_declarator_list ';'
407 {
408 if (func_params != NULL) {
409 set_param_types(func_params, &$1, &$2);
410 } else {
411 gen_declarations(&$1, &$2);
412 #if OPT_LINTLIBRARY
413 flush_varargs();
414 #endif
415 free_decl_list(&$2);
416 }
417 free_decl_spec(&$1);
418 end_typedef();
419 }
420 | any_typedef decl_specifiers
421 {
422 cur_decl_spec_flags = $2.flags;
423 free_decl_spec(&$2);
424 }
425 opt_declarator_list ';'
426 {
427 end_typedef();
428 }
429 ;
430
431 any_typedef
432 : T_EXTENSION T_TYPEDEF
433 {
434 begin_typedef();
435 }
436 | T_TYPEDEF
437 {
438 begin_typedef();
439 }
440 ;
441
442 opt_declarator_list
443 : /* empty */
444 | declarator_list
445 ;
446
447 declarator_list
448 : declarator
449 {
450 int flags = cur_decl_spec_flags;
451
452 /* If the typedef is a pointer type, then reset the short type
453 * flags so it does not get promoted.
454 */
455 if (strcmp($1->text, $1->name) != 0)
456 flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
457 new_symbol(typedef_names, $1->name, NULL, flags);
458 free_declarator($1);
459 }
460 | declarator_list ',' declarator
461 {
462 int flags = cur_decl_spec_flags;
463
464 if (strcmp($3->text, $3->name) != 0)
465 flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
466 new_symbol(typedef_names, $3->name, NULL, flags);
467 free_declarator($3);
468 }
469 ;
470
471 function_definition
472 : decl_specifiers declarator
473 {
474 check_untagged(&$1);
475 if ($2->func_def == FUNC_NONE) {
476 yyerror("syntax error");
477 YYERROR;
478 }
479 func_params = &($2->head->params);
480 func_params->begin_comment = cur_file->begin_comment;
481 func_params->end_comment = cur_file->end_comment;
482 }
483 opt_declaration_list T_LBRACE
484 {
485 /* If we're converting to K&R and we've got a nominally K&R
486 * function which has a parameter which is ANSI (i.e., a prototyped
487 * function pointer), then we must override the deciphered value of
488 * 'func_def' so that the parameter will be converted.
489 */
490 if (func_style == FUNC_TRADITIONAL
491 && haveAnsiParam()
492 && $2->head->func_def == func_style) {
493 $2->head->func_def = FUNC_BOTH;
494 }
495
496 func_params = NULL;
497
498 if (cur_file->convert)
499 gen_func_definition(&$1, $2);
500 gen_prototype(&$1, $2);
501 #if OPT_LINTLIBRARY
502 flush_varargs();
503 #endif
504 free_decl_spec(&$1);
505 free_declarator($2);
506 }
507 T_MATCHRBRACE
508 | declarator
509 {
510 if ($1->func_def == FUNC_NONE) {
511 yyerror("syntax error");
512 YYERROR;
513 }
514 func_params = &($1->head->params);
515 func_params->begin_comment = cur_file->begin_comment;
516 func_params->end_comment = cur_file->end_comment;
517 }
518 opt_declaration_list T_LBRACE T_MATCHRBRACE
519 {
520 DeclSpec decl_spec;
521
522 func_params = NULL;
523
524 new_decl_spec(&decl_spec, dft_decl_spec(), $1->begin, DS_NONE);
525 if (cur_file->convert)
526 gen_func_definition(&decl_spec, $1);
527 gen_prototype(&decl_spec, $1);
528 #if OPT_LINTLIBRARY
529 flush_varargs();
530 #endif
531 free_decl_spec(&decl_spec);
532 free_declarator($1);
533 }
534 ;
535
536 opt_declaration_list
537 : /* empty */
538 | T_VA_DCL
539 | declaration_list
540 ;
541
542 declaration_list
543 : declaration
544 | declaration_list declaration
545 ;
546
547 decl_specifiers
548 : decl_specifier
549 | decl_specifiers decl_specifier
550 {
551 join_decl_specs(&$$, &$1, &$2);
552 free($1.text);
553 free($2.text);
554 }
555 ;
556
557 decl_specifier
558 : storage_class
559 | type_specifier
560 | type_qualifier
561 ;
562
563 storage_class
564 : T_AUTO
565 {
566 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
567 }
568 | T_EXTERN
569 {
570 new_decl_spec(&$$, $1.text, $1.begin, DS_EXTERN);
571 }
572 | T_REGISTER
573 {
574 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
575 }
576 | T_STATIC
577 {
578 new_decl_spec(&$$, $1.text, $1.begin, DS_STATIC);
579 }
580 | T_INLINE
581 {
582 new_decl_spec(&$$, $1.text, $1.begin, DS_INLINE);
583 }
584 | T_EXTENSION
585 {
586 new_decl_spec(&$$, $1.text, $1.begin, DS_JUNK);
587 }
588 ;
589
590 type_specifier
591 : T_CHAR
592 {
593 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
594 }
595 | T_DOUBLE
596 {
597 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
598 }
599 | T_FLOAT
600 {
601 new_decl_spec(&$$, $1.text, $1.begin, DS_FLOAT);
602 }
603 | T_INT
604 {
605 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
606 }
607 | T_LONG
608 {
609 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
610 }
611 | T_SHORT
612 {
613 new_decl_spec(&$$, $1.text, $1.begin, DS_SHORT);
614 }
615 | T_SIGNED
616 {
617 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
618 }
619 | T_UNSIGNED
620 {
621 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
622 }
623 | T_VOID
624 {
625 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
626 }
627 | T_Bool
628 {
629 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
630 }
631 | T_Complex
632 {
633 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
634 }
635 | T_Imaginary
636 {
637 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
638 }
639 | T_TYPEDEF_NAME
640 {
641 Symbol *s;
642 s = find_symbol(typedef_names, $1.text);
643 if (s != NULL)
644 new_decl_spec(&$$, $1.text, $1.begin, s->flags);
645 }
646 | struct_or_union_specifier
647 | enum_specifier
648 ;
649
650 type_qualifier
651 : T_TYPE_QUALIFIER
652 {
653 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
654 }
655 | T_DEFINE_NAME
656 {
657 /* This rule allows the <pointer> nonterminal to scan #define
658 * names as if they were type modifiers.
659 */
660 Symbol *s;
661 s = find_symbol(define_names, $1.text);
662 if (s != NULL)
663 new_decl_spec(&$$, $1.text, $1.begin, s->flags);
664 }
665 ;
666
667 struct_or_union_specifier
668 : struct_or_union any_id braces
669 {
670 char *s;
671 if ((s = implied_typedef()) == 0)
672 (void)sprintf(s = buf, "%s %s", $1.text, $2.text);
673 new_decl_spec(&$$, s, $1.begin, DS_NONE);
674 }
675 | struct_or_union braces
676 {
677 char *s;
678 if ((s = implied_typedef()) == 0)
679 (void)sprintf(s = buf, "%s {}", $1.text);
680 new_decl_spec(&$$, s, $1.begin, DS_NONE);
681 }
682 | struct_or_union any_id
683 {
684 (void)sprintf(buf, "%s %s", $1.text, $2.text);
685 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
686 }
687 ;
688
689 struct_or_union
690 : T_STRUCT
691 {
692 imply_typedef($$.text);
693 }
694 | T_UNION
695 {
696 imply_typedef($$.text);
697 }
698 ;
699
700 init_declarator_list
701 : init_declarator
702 {
703 new_decl_list(&$$, $1);
704 }
705 | init_declarator_list ',' init_declarator
706 {
707 add_decl_list(&$$, &$1, $3);
708 }
709 ;
710
711 init_declarator
712 : declarator
713 {
714 if ($1->func_def != FUNC_NONE && func_params == NULL &&
715 func_style == FUNC_TRADITIONAL && cur_file->convert) {
716 gen_func_declarator($1);
717 fputs(cur_text(), cur_file->tmp_file);
718 }
719 cur_declarator = $$;
720 }
721 | declarator '='
722 {
723 if ($1->func_def != FUNC_NONE && func_params == NULL &&
724 func_style == FUNC_TRADITIONAL && cur_file->convert) {
725 gen_func_declarator($1);
726 fputs(" =", cur_file->tmp_file);
727 }
728 }
729 T_INITIALIZER
730 ;
731
732 enum_specifier
733 : enumeration any_id braces
734 {
735 char *s;
736 if ((s = implied_typedef()) == 0)
737 (void)sprintf(s = buf, "enum %s", $2.text);
738 new_decl_spec(&$$, s, $1.begin, DS_NONE);
739 }
740 | enumeration braces
741 {
742 char *s;
743 if ((s = implied_typedef()) == 0)
744 (void)sprintf(s = buf, "%s {}", $1.text);
745 new_decl_spec(&$$, s, $1.begin, DS_NONE);
746 }
747 | enumeration any_id
748 {
749 (void)sprintf(buf, "enum %s", $2.text);
750 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
751 }
752 ;
753
754 enumeration
755 : T_ENUM
756 {
757 imply_typedef("enum");
758 $$ = $1;
759 }
760 ;
761
762 any_id
763 : T_IDENTIFIER
764 | T_TYPEDEF_NAME
765 ;
766
767 declarator
768 : pointer direct_declarator
769 {
770 $$ = $2;
771 (void)sprintf(buf, "%s%s", $1.text, $$->text);
772 free($$->text);
773 $$->text = xstrdup(buf);
774 $$->begin = $1.begin;
775 $$->pointer = TRUE;
776 }
777 | direct_declarator
778 ;
779
780 direct_declarator
781 : identifier_or_ref
782 {
783 $$ = new_declarator($1.text, $1.text, $1.begin);
784 }
785 | '(' declarator ')'
786 {
787 $$ = $2;
788 (void)sprintf(buf, "(%s)", $$->text);
789 free($$->text);
790 $$->text = xstrdup(buf);
791 $$->begin = $1.begin;
792 }
793 | direct_declarator T_BRACKETS
794 {
795 $$ = $1;
796 (void)sprintf(buf, "%s%s", $$->text, $2.text);
797 free($$->text);
798 $$->text = xstrdup(buf);
799 }
800 | direct_declarator '(' parameter_type_list ')'
801 {
802 $$ = new_declarator("%s()", $1->name, $1->begin);
803 $$->params = $3;
804 $$->func_stack = $1;
805 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
806 $$->func_def = FUNC_ANSI;
807 }
808 | direct_declarator '(' opt_identifier_list ')'
809 {
810 $$ = new_declarator("%s()", $1->name, $1->begin);
811 $$->params = $3;
812 $$->func_stack = $1;
813 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
814 $$->func_def = FUNC_TRADITIONAL;
815 }
816 ;
817
818 pointer
819 : '*' opt_type_qualifiers
820 {
821 (void)sprintf($$.text, "*%s", $2.text);
822 $$.begin = $1.begin;
823 }
824 | '*' opt_type_qualifiers pointer
825 {
826 (void)sprintf($$.text, "*%s%s", $2.text, $3.text);
827 $$.begin = $1.begin;
828 }
829 ;
830
831 opt_type_qualifiers
832 : /* empty */
833 {
834 strcpy($$.text, "");
835 $$.begin = 0L;
836 }
837 | type_qualifier_list
838 ;
839
840 type_qualifier_list
841 : type_qualifier
842 {
843 (void)sprintf($$.text, "%s ", $1.text);
844 $$.begin = $1.begin;
845 free($1.text);
846 }
847 | type_qualifier_list type_qualifier
848 {
849 (void)sprintf($$.text, "%s%s ", $1.text, $2.text);
850 $$.begin = $1.begin;
851 free($2.text);
852 }
853 ;
854
855 parameter_type_list
856 : parameter_list
857 | parameter_list ',' T_ELLIPSIS
858 {
859 add_ident_list(&$$, &$1, "...");
860 }
861 ;
862
863 parameter_list
864 : parameter_declaration
865 {
866 new_param_list(&$$, $1);
867 }
868 | parameter_list ',' parameter_declaration
869 {
870 add_param_list(&$$, &$1, $3);
871 }
872 ;
873
874 parameter_declaration
875 : decl_specifiers declarator
876 {
877 check_untagged(&$1);
878 $$ = new_parameter(&$1, $2);
879 }
880 | decl_specifiers abs_declarator
881 {
882 check_untagged(&$1);
883 $$ = new_parameter(&$1, $2);
884 }
885 | decl_specifiers
886 {
887 check_untagged(&$1);
888 $$ = new_parameter(&$1, (Declarator *)0);
889 }
890 ;
891
892 opt_identifier_list
893 : /* empty */
894 {
895 new_ident_list(&$$);
896 }
897 | identifier_list
898 ;
899
900 identifier_list
901 : any_id
902 {
903 new_ident_list(&$$);
904 add_ident_list(&$$, &$$, $1.text);
905 }
906 | identifier_list ',' any_id
907 {
908 add_ident_list(&$$, &$1, $3.text);
909 }
910 ;
911
912 identifier_or_ref
913 : any_id
914 {
915 $$ = $1;
916 }
917 | '&' any_id
918 {
919 #if OPT_LINTLIBRARY
920 if (lintLibrary()) { /* Lint doesn't grok C++ ref variables */
921 $$ = $2;
922 } else
923 #endif
924 (void)sprintf($$.text, "&%s", $2.text);
925 $$.begin = $1.begin;
926 }
927 ;
928
929 abs_declarator
930 : pointer
931 {
932 $$ = new_declarator($1.text, "", $1.begin);
933 }
934 | pointer direct_abs_declarator
935 {
936 $$ = $2;
937 (void)sprintf(buf, "%s%s", $1.text, $$->text);
938 free($$->text);
939 $$->text = xstrdup(buf);
940 $$->begin = $1.begin;
941 }
942 | direct_abs_declarator
943 ;
944
945 direct_abs_declarator
946 : '(' abs_declarator ')'
947 {
948 $$ = $2;
949 (void)sprintf(buf, "(%s)", $$->text);
950 free($$->text);
951 $$->text = xstrdup(buf);
952 $$->begin = $1.begin;
953 }
954 | direct_abs_declarator T_BRACKETS
955 {
956 $$ = $1;
957 (void)sprintf(buf, "%s%s", $$->text, $2.text);
958 free($$->text);
959 $$->text = xstrdup(buf);
960 }
961 | T_BRACKETS
962 {
963 $$ = new_declarator($1.text, "", $1.begin);
964 }
965 | direct_abs_declarator '(' parameter_type_list ')'
966 {
967 $$ = new_declarator("%s()", "", $1->begin);
968 $$->params = $3;
969 $$->func_stack = $1;
970 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
971 $$->func_def = FUNC_ANSI;
972 }
973 | direct_abs_declarator '(' ')'
974 {
975 $$ = new_declarator("%s()", "", $1->begin);
976 $$->func_stack = $1;
977 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
978 $$->func_def = FUNC_ANSI;
979 }
980 | '(' parameter_type_list ')'
981 {
982 Declarator *d;
983
984 d = new_declarator("", "", $1.begin);
985 $$ = new_declarator("%s()", "", $1.begin);
986 $$->params = $2;
987 $$->func_stack = d;
988 $$->head = $$;
989 $$->func_def = FUNC_ANSI;
990 }
991 | '(' ')'
992 {
993 Declarator *d;
994
995 d = new_declarator("", "", $1.begin);
996 $$ = new_declarator("%s()", "", $1.begin);
997 $$->func_stack = d;
998 $$->head = $$;
999 $$->func_def = FUNC_ANSI;
1000 }
1001 ;
1002
1003 %%
1004
1005 /* lex.yy.c */
1006 #define BEGIN yy_start = 1 + 2 *
1007
1008 #define CPP1 1
1009 #define INIT1 2
1010 #define INIT2 3
1011 #define CURLY 4
1012 #define LEXYACC 5
1013 #define ASM 6
1014 #define CPP_INLINE 7
1015
1016 extern char *yytext;
1017 extern FILE *yyin, *yyout;
1018
1019 static int curly; /* number of curly brace nesting levels */
1020 static int ly_count; /* number of occurances of %% */
1021 static int inc_depth; /* include nesting level */
1022 static SymbolTable *included_files; /* files already included */
1023 static int yy_start = 0; /* start state number */
1024
1025 #define grammar_error(s) yaccError(s)
1026
1027 static void
1028 yaccError (const char *msg)
1029 {
1030 func_params = NULL;
1031 put_error(); /* tell what line we're on, and what file */
1032 fprintf(stderr, "%s at token '%s'\n", msg, yytext);
1033 }
1034
1035 /* Initialize the table of type qualifier keywords recognized by the lexical
1036 * analyzer.
1037 */
1038 void
1039 init_parser (void)
1040 {
1041 static const char *keywords[] = {
1042 "const",
1043 "restrict",
1044 "volatile",
1045 "interrupt",
1046 #ifdef vms
1047 "noshare",
1048 "readonly",
1049 #endif
1050 #if defined(MSDOS) || defined(OS2)
1051 "__cdecl",
1052 "__export",
1053 "__far",
1054 "__fastcall",
1055 "__fortran",
1056 "__huge",
1057 "__inline",
1058 "__interrupt",
1059 "__loadds",
1060 "__near",
1061 "__pascal",
1062 "__saveregs",
1063 "__segment",
1064 "__stdcall",
1065 "__syscall",
1066 "_cdecl",
1067 "_cs",
1068 "_ds",
1069 "_es",
1070 "_export",
1071 "_far",
1072 "_fastcall",
1073 "_fortran",
1074 "_huge",
1075 "_interrupt",
1076 "_loadds",
1077 "_near",
1078 "_pascal",
1079 "_saveregs",
1080 "_seg",
1081 "_segment",
1082 "_ss",
1083 "cdecl",
1084 "far",
1085 "huge",
1086 "near",
1087 "pascal",
1088 #ifdef OS2
1089 "__far16",
1090 #endif
1091 #endif
1092 #ifdef __GNUC__
1093 /* gcc aliases */
1094 "__builtin_va_arg",
1095 "__builtin_va_list",
1096 "__const",
1097 "__const__",
1098 "__inline",
1099 "__inline__",
1100 "__restrict",
1101 "__restrict__",
1102 "__volatile",
1103 "__volatile__",
1104 #endif
1105 };
1106 unsigned i;
1107
1108 /* Initialize type qualifier table. */
1109 type_qualifiers = new_symbol_table();
1110 for (i = 0; i < sizeof(keywords)/sizeof(keywords[0]); ++i) {
1111 new_symbol(type_qualifiers, keywords[i], NULL, DS_NONE);
1112 }
1113 }
1114
1115 /* Process the C source file. Write function prototypes to the standard
1116 * output. Convert function definitions and write the converted source
1117 * code to a temporary file.
1118 */
1119 void
1120 process_file (FILE *infile, char *name)
1121 {
1122 char *s;
1123
1124 if (strlen(name) > 2) {
1125 s = name + strlen(name) - 2;
1126 if (*s == '.') {
1127 ++s;
1128 if (*s == 'l' || *s == 'y')
1129 BEGIN LEXYACC;
1130 #if defined(MSDOS) || defined(OS2)
1131 if (*s == 'L' || *s == 'Y')
1132 BEGIN LEXYACC;
1133 #endif
1134 }
1135 }
1136
1137 included_files = new_symbol_table();
1138 typedef_names = new_symbol_table();
1139 define_names = new_symbol_table();
1140 inc_depth = -1;
1141 curly = 0;
1142 ly_count = 0;
1143 func_params = NULL;
1144 yyin = infile;
1145 include_file(strcpy(base_file, name), func_style != FUNC_NONE);
1146 if (file_comments) {
1147 #if OPT_LINTLIBRARY
1148 if (lintLibrary()) {
1149 put_blankline(stdout);
1150 begin_tracking();
1151 }
1152 #endif
1153 put_string(stdout, "/* ");
1154 put_string(stdout, cur_file_name());
1155 put_string(stdout, " */\n");
1156 }
1157 yyparse();
1158 free_symbol_table(define_names);
1159 free_symbol_table(typedef_names);
1160 free_symbol_table(included_files);
1161 }
1162
1163 #ifdef NO_LEAKS
1164 void
1165 free_parser(void)
1166 {
1167 free_symbol_table (type_qualifiers);
1168 #ifdef FLEX_SCANNER
1169 if (yy_current_buffer != 0)
1170 yy_delete_buffer(yy_current_buffer);
1171 #endif
1172 }
1173 #endif
1174