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