Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / byacc / dist / test / grammar.y
blobfb94ad18ba8555065c0ab8fc848cc0f9b0004d67
1 /* $NetBSD$ */
3 /* Id: grammar.y,v 1.1 2004/03/24 21:29:23 tom Exp
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 */
10 %token <text> '(' '*' '&'
11 /* identifiers that are not reserved words */
12 T_IDENTIFIER T_TYPEDEF_NAME T_DEFINE_NAME
14 /* storage class */
15 T_AUTO T_EXTERN T_REGISTER T_STATIC T_TYPEDEF
16 /* This keyword included for compatibility with C++. */
17 T_INLINE
18 /* This keyword included for compatibility with GCC */
19 T_EXTENSION
21 /* type specifiers */
22 T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID
23 T_LONG T_SHORT T_SIGNED T_UNSIGNED
24 T_ENUM T_STRUCT T_UNION
25 /* C9X new types */
26 T_Bool T_Complex T_Imaginary
28 /* type qualifiers */
29 T_TYPE_QUALIFIER
31 /* paired square brackets and everything between them: [ ... ] */
32 T_BRACKETS
34 %token
35 /* left brace */
36 T_LBRACE
37 /* all input to the matching right brace */
38 T_MATCHRBRACE
40 /* three periods */
41 T_ELLIPSIS
43 /* constant expression or paired braces following an equal sign */
44 T_INITIALIZER
46 /* string literal */
47 T_STRING_LITERAL
49 /* asm */
50 T_ASM
51 /* ( "string literal" ) following asm keyword */
52 T_ASMARG
54 /* va_dcl from <varargs.h> */
55 T_VA_DCL
57 %type <decl_spec> decl_specifiers decl_specifier
58 %type <decl_spec> storage_class type_specifier type_qualifier
59 %type <decl_spec> struct_or_union_specifier enum_specifier
60 %type <decl_list> init_declarator_list
61 %type <declarator> init_declarator declarator direct_declarator
62 %type <declarator> abs_declarator direct_abs_declarator
63 %type <param_list> parameter_type_list parameter_list
64 %type <parameter> parameter_declaration
65 %type <param_list> opt_identifier_list identifier_list
66 %type <text> struct_or_union pointer opt_type_qualifiers type_qualifier_list
67 any_id identifier_or_ref
68 %type <text> enumeration
71 #include <stdio.h>
72 #include <ctype.h>
73 #include "cproto.h"
74 #include "symbol.h"
75 #include "semantic.h"
77 #define YYMAXDEPTH 150
79 extern int yylex (void);
81 /* declaration specifier attributes for the typedef statement currently being
82 * scanned
84 static int cur_decl_spec_flags;
86 /* pointer to parameter list for the current function definition */
87 static ParameterList *func_params;
89 /* A parser semantic action sets this pointer to the current declarator in
90 * a function parameter declaration in order to catch any comments following
91 * the parameter declaration on the same line. If the lexer scans a comment
92 * and <cur_declarator> is not NULL, then the comment is attached to the
93 * declarator. To ignore subsequent comments, the lexer sets this to NULL
94 * after scanning a comment or end of line.
96 static Declarator *cur_declarator;
98 /* temporary string buffer */
99 static char buf[MAX_TEXT_SIZE];
101 /* table of typedef names */
102 static SymbolTable *typedef_names;
104 /* table of define names */
105 static SymbolTable *define_names;
107 /* table of type qualifiers */
108 static SymbolTable *type_qualifiers;
110 /* information about the current input file */
111 typedef struct {
112 char *base_name; /* base input file name */
113 char *file_name; /* current file name */
114 FILE *file; /* input file */
115 unsigned line_num; /* current line number in input file */
116 FILE *tmp_file; /* temporary file */
117 long begin_comment; /* tmp file offset after last written ) or ; */
118 long end_comment; /* tmp file offset after last comment */
119 boolean convert; /* if TRUE, convert function definitions */
120 boolean changed; /* TRUE if conversion done in this file */
121 } IncludeStack;
123 static IncludeStack *cur_file; /* current input file */
125 #include "yyerror.c"
127 static int haveAnsiParam (void);
130 /* Flags to enable us to find if a procedure returns a value.
132 static int return_val, /* nonzero on BRACES iff return-expression found */
133 returned_at; /* marker for token-number to set 'return_val' */
135 #if OPT_LINTLIBRARY
136 static char *dft_decl_spec (void);
138 static char *
139 dft_decl_spec (void)
141 return (lintLibrary() && !return_val) ? "void" : "int";
144 #else
145 #define dft_decl_spec() "int"
146 #endif
148 static int
149 haveAnsiParam (void)
151 Parameter *p;
152 if (func_params != 0) {
153 for (p = func_params->first; p != 0; p = p->next) {
154 if (p->declarator->func_def == FUNC_ANSI) {
155 return TRUE;
159 return FALSE;
164 program
165 : /* empty */
166 | translation_unit
169 translation_unit
170 : external_declaration
171 | translation_unit external_declaration
174 external_declaration
175 : declaration
176 | function_definition
177 | ';'
178 | linkage_specification
179 | T_ASM T_ASMARG ';'
180 | error T_MATCHRBRACE
182 yyerrok;
184 | error ';'
186 yyerrok;
190 braces
191 : T_LBRACE T_MATCHRBRACE
194 linkage_specification
195 : T_EXTERN T_STRING_LITERAL braces
197 /* Provide an empty action here so bison will not complain about
198 * incompatible types in the default action it normally would
199 * have generated.
202 | T_EXTERN T_STRING_LITERAL declaration
204 /* empty */
208 declaration
209 : decl_specifiers ';'
211 #if OPT_LINTLIBRARY
212 if (types_out && want_typedef()) {
213 gen_declarations(&$1, (DeclaratorList *)0);
214 flush_varargs();
216 #endif
217 free_decl_spec(&$1);
218 end_typedef();
220 | decl_specifiers init_declarator_list ';'
222 if (func_params != NULL) {
223 set_param_types(func_params, &$1, &$2);
224 } else {
225 gen_declarations(&$1, &$2);
226 #if OPT_LINTLIBRARY
227 flush_varargs();
228 #endif
229 free_decl_list(&$2);
231 free_decl_spec(&$1);
232 end_typedef();
234 | any_typedef decl_specifiers
236 cur_decl_spec_flags = $2.flags;
237 free_decl_spec(&$2);
239 opt_declarator_list ';'
241 end_typedef();
245 any_typedef
246 : T_EXTENSION T_TYPEDEF
248 begin_typedef();
250 | T_TYPEDEF
252 begin_typedef();
256 opt_declarator_list
257 : /* empty */
258 | declarator_list
261 declarator_list
262 : declarator
264 int flags = cur_decl_spec_flags;
266 /* If the typedef is a pointer type, then reset the short type
267 * flags so it does not get promoted.
269 if (strcmp($1->text, $1->name) != 0)
270 flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
271 new_symbol(typedef_names, $1->name, NULL, flags);
272 free_declarator($1);
274 | declarator_list ',' declarator
276 int flags = cur_decl_spec_flags;
278 if (strcmp($3->text, $3->name) != 0)
279 flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
280 new_symbol(typedef_names, $3->name, NULL, flags);
281 free_declarator($3);
285 function_definition
286 : decl_specifiers declarator
288 check_untagged(&$1);
289 if ($2->func_def == FUNC_NONE) {
290 yyerror("syntax error");
291 YYERROR;
293 func_params = &($2->head->params);
294 func_params->begin_comment = cur_file->begin_comment;
295 func_params->end_comment = cur_file->end_comment;
297 opt_declaration_list T_LBRACE
299 /* If we're converting to K&R and we've got a nominally K&R
300 * function which has a parameter which is ANSI (i.e., a prototyped
301 * function pointer), then we must override the deciphered value of
302 * 'func_def' so that the parameter will be converted.
304 if (func_style == FUNC_TRADITIONAL
305 && haveAnsiParam()
306 && $2->head->func_def == func_style) {
307 $2->head->func_def = FUNC_BOTH;
310 func_params = NULL;
312 if (cur_file->convert)
313 gen_func_definition(&$1, $2);
314 gen_prototype(&$1, $2);
315 #if OPT_LINTLIBRARY
316 flush_varargs();
317 #endif
318 free_decl_spec(&$1);
319 free_declarator($2);
321 T_MATCHRBRACE
322 | declarator
324 if ($1->func_def == FUNC_NONE) {
325 yyerror("syntax error");
326 YYERROR;
328 func_params = &($1->head->params);
329 func_params->begin_comment = cur_file->begin_comment;
330 func_params->end_comment = cur_file->end_comment;
332 opt_declaration_list T_LBRACE T_MATCHRBRACE
334 DeclSpec decl_spec;
336 func_params = NULL;
338 new_decl_spec(&decl_spec, dft_decl_spec(), $1->begin, DS_NONE);
339 if (cur_file->convert)
340 gen_func_definition(&decl_spec, $1);
341 gen_prototype(&decl_spec, $1);
342 #if OPT_LINTLIBRARY
343 flush_varargs();
344 #endif
345 free_decl_spec(&decl_spec);
346 free_declarator($1);
350 opt_declaration_list
351 : /* empty */
352 | T_VA_DCL
353 | declaration_list
356 declaration_list
357 : declaration
358 | declaration_list declaration
361 decl_specifiers
362 : decl_specifier
363 | decl_specifiers decl_specifier
365 join_decl_specs(&$$, &$1, &$2);
366 free($1.text);
367 free($2.text);
371 decl_specifier
372 : storage_class
373 | type_specifier
374 | type_qualifier
377 storage_class
378 : T_AUTO
380 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
382 | T_EXTERN
384 new_decl_spec(&$$, $1.text, $1.begin, DS_EXTERN);
386 | T_REGISTER
388 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
390 | T_STATIC
392 new_decl_spec(&$$, $1.text, $1.begin, DS_STATIC);
394 | T_INLINE
396 new_decl_spec(&$$, $1.text, $1.begin, DS_INLINE);
398 | T_EXTENSION
400 new_decl_spec(&$$, $1.text, $1.begin, DS_JUNK);
404 type_specifier
405 : T_CHAR
407 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
409 | T_DOUBLE
411 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
413 | T_FLOAT
415 new_decl_spec(&$$, $1.text, $1.begin, DS_FLOAT);
417 | T_INT
419 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
421 | T_LONG
423 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
425 | T_SHORT
427 new_decl_spec(&$$, $1.text, $1.begin, DS_SHORT);
429 | T_SIGNED
431 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
433 | T_UNSIGNED
435 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
437 | T_VOID
439 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
441 | T_Bool
443 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
445 | T_Complex
447 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
449 | T_Imaginary
451 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
453 | T_TYPEDEF_NAME
455 Symbol *s;
456 s = find_symbol(typedef_names, $1.text);
457 if (s != NULL)
458 new_decl_spec(&$$, $1.text, $1.begin, s->flags);
460 | struct_or_union_specifier
461 | enum_specifier
464 type_qualifier
465 : T_TYPE_QUALIFIER
467 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
469 | T_DEFINE_NAME
471 /* This rule allows the <pointer> nonterminal to scan #define
472 * names as if they were type modifiers.
474 Symbol *s;
475 s = find_symbol(define_names, $1.text);
476 if (s != NULL)
477 new_decl_spec(&$$, $1.text, $1.begin, s->flags);
481 struct_or_union_specifier
482 : struct_or_union any_id braces
484 char *s;
485 if ((s = implied_typedef()) == 0)
486 (void)sprintf(s = buf, "%s %s", $1.text, $2.text);
487 new_decl_spec(&$$, s, $1.begin, DS_NONE);
489 | struct_or_union braces
491 char *s;
492 if ((s = implied_typedef()) == 0)
493 (void)sprintf(s = buf, "%s {}", $1.text);
494 new_decl_spec(&$$, s, $1.begin, DS_NONE);
496 | struct_or_union any_id
498 (void)sprintf(buf, "%s %s", $1.text, $2.text);
499 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
503 struct_or_union
504 : T_STRUCT
506 imply_typedef($$.text);
508 | T_UNION
510 imply_typedef($$.text);
514 init_declarator_list
515 : init_declarator
517 new_decl_list(&$$, $1);
519 | init_declarator_list ',' init_declarator
521 add_decl_list(&$$, &$1, $3);
525 init_declarator
526 : declarator
528 if ($1->func_def != FUNC_NONE && func_params == NULL &&
529 func_style == FUNC_TRADITIONAL && cur_file->convert) {
530 gen_func_declarator($1);
531 fputs(cur_text(), cur_file->tmp_file);
533 cur_declarator = $$;
535 | declarator '='
537 if ($1->func_def != FUNC_NONE && func_params == NULL &&
538 func_style == FUNC_TRADITIONAL && cur_file->convert) {
539 gen_func_declarator($1);
540 fputs(" =", cur_file->tmp_file);
543 T_INITIALIZER
546 enum_specifier
547 : enumeration any_id braces
549 char *s;
550 if ((s = implied_typedef()) == 0)
551 (void)sprintf(s = buf, "enum %s", $2.text);
552 new_decl_spec(&$$, s, $1.begin, DS_NONE);
554 | enumeration braces
556 char *s;
557 if ((s = implied_typedef()) == 0)
558 (void)sprintf(s = buf, "%s {}", $1.text);
559 new_decl_spec(&$$, s, $1.begin, DS_NONE);
561 | enumeration any_id
563 (void)sprintf(buf, "enum %s", $2.text);
564 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
568 enumeration
569 : T_ENUM
571 imply_typedef("enum");
572 $$ = $1;
576 any_id
577 : T_IDENTIFIER
578 | T_TYPEDEF_NAME
581 declarator
582 : pointer direct_declarator
584 $$ = $2;
585 (void)sprintf(buf, "%s%s", $1.text, $$->text);
586 free($$->text);
587 $$->text = xstrdup(buf);
588 $$->begin = $1.begin;
589 $$->pointer = TRUE;
591 | direct_declarator
594 direct_declarator
595 : identifier_or_ref
597 $$ = new_declarator($1.text, $1.text, $1.begin);
599 | '(' declarator ')'
601 $$ = $2;
602 (void)sprintf(buf, "(%s)", $$->text);
603 free($$->text);
604 $$->text = xstrdup(buf);
605 $$->begin = $1.begin;
607 | direct_declarator T_BRACKETS
609 $$ = $1;
610 (void)sprintf(buf, "%s%s", $$->text, $2.text);
611 free($$->text);
612 $$->text = xstrdup(buf);
614 | direct_declarator '(' parameter_type_list ')'
616 $$ = new_declarator("%s()", $1->name, $1->begin);
617 $$->params = $3;
618 $$->func_stack = $1;
619 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
620 $$->func_def = FUNC_ANSI;
622 | direct_declarator '(' opt_identifier_list ')'
624 $$ = new_declarator("%s()", $1->name, $1->begin);
625 $$->params = $3;
626 $$->func_stack = $1;
627 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
628 $$->func_def = FUNC_TRADITIONAL;
632 pointer
633 : '*' opt_type_qualifiers
635 (void)sprintf($$.text, "*%s", $2.text);
636 $$.begin = $1.begin;
638 | '*' opt_type_qualifiers pointer
640 (void)sprintf($$.text, "*%s%s", $2.text, $3.text);
641 $$.begin = $1.begin;
645 opt_type_qualifiers
646 : /* empty */
648 strcpy($$.text, "");
649 $$.begin = 0L;
651 | type_qualifier_list
654 type_qualifier_list
655 : type_qualifier
657 (void)sprintf($$.text, "%s ", $1.text);
658 $$.begin = $1.begin;
659 free($1.text);
661 | type_qualifier_list type_qualifier
663 (void)sprintf($$.text, "%s%s ", $1.text, $2.text);
664 $$.begin = $1.begin;
665 free($2.text);
669 parameter_type_list
670 : parameter_list
671 | parameter_list ',' T_ELLIPSIS
673 add_ident_list(&$$, &$1, "...");
677 parameter_list
678 : parameter_declaration
680 new_param_list(&$$, $1);
682 | parameter_list ',' parameter_declaration
684 add_param_list(&$$, &$1, $3);
688 parameter_declaration
689 : decl_specifiers declarator
691 check_untagged(&$1);
692 $$ = new_parameter(&$1, $2);
694 | decl_specifiers abs_declarator
696 check_untagged(&$1);
697 $$ = new_parameter(&$1, $2);
699 | decl_specifiers
701 check_untagged(&$1);
702 $$ = new_parameter(&$1, (Declarator *)0);
706 opt_identifier_list
707 : /* empty */
709 new_ident_list(&$$);
711 | identifier_list
714 identifier_list
715 : any_id
717 new_ident_list(&$$);
718 add_ident_list(&$$, &$$, $1.text);
720 | identifier_list ',' any_id
722 add_ident_list(&$$, &$1, $3.text);
726 identifier_or_ref
727 : any_id
729 $$ = $1;
731 | '&' any_id
733 #if OPT_LINTLIBRARY
734 if (lintLibrary()) { /* Lint doesn't grok C++ ref variables */
735 $$ = $2;
736 } else
737 #endif
738 (void)sprintf($$.text, "&%s", $2.text);
739 $$.begin = $1.begin;
743 abs_declarator
744 : pointer
746 $$ = new_declarator($1.text, "", $1.begin);
748 | pointer direct_abs_declarator
750 $$ = $2;
751 (void)sprintf(buf, "%s%s", $1.text, $$->text);
752 free($$->text);
753 $$->text = xstrdup(buf);
754 $$->begin = $1.begin;
756 | direct_abs_declarator
759 direct_abs_declarator
760 : '(' abs_declarator ')'
762 $$ = $2;
763 (void)sprintf(buf, "(%s)", $$->text);
764 free($$->text);
765 $$->text = xstrdup(buf);
766 $$->begin = $1.begin;
768 | direct_abs_declarator T_BRACKETS
770 $$ = $1;
771 (void)sprintf(buf, "%s%s", $$->text, $2.text);
772 free($$->text);
773 $$->text = xstrdup(buf);
775 | T_BRACKETS
777 $$ = new_declarator($1.text, "", $1.begin);
779 | direct_abs_declarator '(' parameter_type_list ')'
781 $$ = new_declarator("%s()", "", $1->begin);
782 $$->params = $3;
783 $$->func_stack = $1;
784 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
785 $$->func_def = FUNC_ANSI;
787 | direct_abs_declarator '(' ')'
789 $$ = new_declarator("%s()", "", $1->begin);
790 $$->func_stack = $1;
791 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
792 $$->func_def = FUNC_ANSI;
794 | '(' parameter_type_list ')'
796 Declarator *d;
798 d = new_declarator("", "", $1.begin);
799 $$ = new_declarator("%s()", "", $1.begin);
800 $$->params = $2;
801 $$->func_stack = d;
802 $$->head = $$;
803 $$->func_def = FUNC_ANSI;
805 | '(' ')'
807 Declarator *d;
809 d = new_declarator("", "", $1.begin);
810 $$ = new_declarator("%s()", "", $1.begin);
811 $$->func_stack = d;
812 $$->head = $$;
813 $$->func_def = FUNC_ANSI;
819 #if defined(__EMX__) || defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(vms)
820 # ifdef USE_flex
821 # include "lexyy.c"
822 # else
823 # include "lex_yy.c"
824 # endif
825 #else
826 # include "lex.yy.c"
827 #endif
829 static void
830 yaccError (char *msg)
832 func_params = NULL;
833 put_error(); /* tell what line we're on, and what file */
834 fprintf(stderr, "%s at token '%s'\n", msg, yytext);
837 /* Initialize the table of type qualifier keywords recognized by the lexical
838 * analyzer.
840 void
841 init_parser (void)
843 static char *keywords[] = {
844 "const",
845 "restrict",
846 "volatile",
847 "interrupt",
848 #ifdef vms
849 "noshare",
850 "readonly",
851 #endif
852 #if defined(MSDOS) || defined(OS2)
853 "__cdecl",
854 "__export",
855 "__far",
856 "__fastcall",
857 "__fortran",
858 "__huge",
859 "__inline",
860 "__interrupt",
861 "__loadds",
862 "__near",
863 "__pascal",
864 "__saveregs",
865 "__segment",
866 "__stdcall",
867 "__syscall",
868 "_cdecl",
869 "_cs",
870 "_ds",
871 "_es",
872 "_export",
873 "_far",
874 "_fastcall",
875 "_fortran",
876 "_huge",
877 "_interrupt",
878 "_loadds",
879 "_near",
880 "_pascal",
881 "_saveregs",
882 "_seg",
883 "_segment",
884 "_ss",
885 "cdecl",
886 "far",
887 "huge",
888 "near",
889 "pascal",
890 #ifdef OS2
891 "__far16",
892 #endif
893 #endif
894 #ifdef __GNUC__
895 /* gcc aliases */
896 "__builtin_va_arg",
897 "__builtin_va_list",
898 "__const",
899 "__const__",
900 "__inline",
901 "__inline__",
902 "__restrict",
903 "__restrict__",
904 "__volatile",
905 "__volatile__",
906 #endif
908 unsigned i;
910 /* Initialize type qualifier table. */
911 type_qualifiers = new_symbol_table();
912 for (i = 0; i < sizeof(keywords)/sizeof(keywords[0]); ++i) {
913 new_symbol(type_qualifiers, keywords[i], NULL, DS_NONE);
917 /* Process the C source file. Write function prototypes to the standard
918 * output. Convert function definitions and write the converted source
919 * code to a temporary file.
921 void
922 process_file (FILE *infile, char *name)
924 char *s;
926 if (strlen(name) > 2) {
927 s = name + strlen(name) - 2;
928 if (*s == '.') {
929 ++s;
930 if (*s == 'l' || *s == 'y')
931 BEGIN LEXYACC;
932 #if defined(MSDOS) || defined(OS2)
933 if (*s == 'L' || *s == 'Y')
934 BEGIN LEXYACC;
935 #endif
939 included_files = new_symbol_table();
940 typedef_names = new_symbol_table();
941 define_names = new_symbol_table();
942 inc_depth = -1;
943 curly = 0;
944 ly_count = 0;
945 func_params = NULL;
946 yyin = infile;
947 include_file(strcpy(base_file, name), func_style != FUNC_NONE);
948 if (file_comments) {
949 #if OPT_LINTLIBRARY
950 if (lintLibrary()) {
951 put_blankline(stdout);
952 begin_tracking();
954 #endif
955 put_string(stdout, "/* ");
956 put_string(stdout, cur_file_name());
957 put_string(stdout, " */\n");
959 yyparse();
960 free_symbol_table(define_names);
961 free_symbol_table(typedef_names);
962 free_symbol_table(included_files);
965 #ifdef NO_LEAKS
966 void
967 free_parser(void)
969 free_symbol_table (type_qualifiers);
970 #ifdef FLEX_SCANNER
971 if (yy_current_buffer != 0)
972 yy_delete_buffer(yy_current_buffer);
973 #endif
975 #endif