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