grammar.y revision 1.1.1.1 1 /* $NetBSD: grammar.y,v 1.1.1.1 2009/10/29 00:46:53 christos Exp $ */
2
3 /* Id: grammar.y,v 1.1 2004/03/24 21:29:23 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
10 %token <text> '(' '*' '&'
11 /* identifiers that are not reserved words */
12 T_IDENTIFIER T_TYPEDEF_NAME T_DEFINE_NAME
13
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
20
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
27
28 /* type qualifiers */
29 T_TYPE_QUALIFIER
30
31 /* paired square brackets and everything between them: [ ... ] */
32 T_BRACKETS
33
34 %token
35 /* left brace */
36 T_LBRACE
37 /* all input to the matching right brace */
38 T_MATCHRBRACE
39
40 /* three periods */
41 T_ELLIPSIS
42
43 /* constant expression or paired braces following an equal sign */
44 T_INITIALIZER
45
46 /* string literal */
47 T_STRING_LITERAL
48
49 /* asm */
50 T_ASM
51 /* ( "string literal" ) following asm keyword */
52 T_ASMARG
53
54 /* va_dcl from <varargs.h> */
55 T_VA_DCL
56
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
69
70 %{
71 #include <stdio.h>
72 #include <ctype.h>
73 #include "cproto.h"
74 #include "symbol.h"
75 #include "semantic.h"
76
77 #define YYMAXDEPTH 150
78
79 extern int yylex (void);
80
81 /* declaration specifier attributes for the typedef statement currently being
82 * scanned
83 */
84 static int cur_decl_spec_flags;
85
86 /* pointer to parameter list for the current function definition */
87 static ParameterList *func_params;
88
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.
95 */
96 static Declarator *cur_declarator;
97
98 /* temporary string buffer */
99 static char buf[MAX_TEXT_SIZE];
100
101 /* table of typedef names */
102 static SymbolTable *typedef_names;
103
104 /* table of define names */
105 static SymbolTable *define_names;
106
107 /* table of type qualifiers */
108 static SymbolTable *type_qualifiers;
109
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;
122
123 static IncludeStack *cur_file; /* current input file */
124
125 #include "yyerror.c"
126
127 static int haveAnsiParam (void);
128
129
130 /* Flags to enable us to find if a procedure returns a value.
131 */
132 static int return_val, /* nonzero on BRACES iff return-expression found */
133 returned_at; /* marker for token-number to set 'return_val' */
134
135 #if OPT_LINTLIBRARY
136 static char *dft_decl_spec (void);
137
138 static char *
139 dft_decl_spec (void)
140 {
141 return (lintLibrary() && !return_val) ? "void" : "int";
142 }
143
144 #else
145 #define dft_decl_spec() "int"
146 #endif
147
148 static int
149 haveAnsiParam (void)
150 {
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;
156 }
157 }
158 }
159 return FALSE;
160 }
161 %}
162 %%
163
164 program
165 : /* empty */
166 | translation_unit
167 ;
168
169 translation_unit
170 : external_declaration
171 | translation_unit external_declaration
172 ;
173
174 external_declaration
175 : declaration
176 | function_definition
177 | ';'
178 | linkage_specification
179 | T_ASM T_ASMARG ';'
180 | error T_MATCHRBRACE
181 {
182 yyerrok;
183 }
184 | error ';'
185 {
186 yyerrok;
187 }
188 ;
189
190 braces
191 : T_LBRACE T_MATCHRBRACE
192 ;
193
194 linkage_specification
195 : T_EXTERN T_STRING_LITERAL braces
196 {
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.
200 */
201 }
202 | T_EXTERN T_STRING_LITERAL declaration
203 {
204 /* empty */
205 }
206 ;
207
208 declaration
209 : decl_specifiers ';'
210 {
211 #if OPT_LINTLIBRARY
212 if (types_out && want_typedef()) {
213 gen_declarations(&$1, (DeclaratorList *)0);
214 flush_varargs();
215 }
216 #endif
217 free_decl_spec(&$1);
218 end_typedef();
219 }
220 | decl_specifiers init_declarator_list ';'
221 {
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);
230 }
231 free_decl_spec(&$1);
232 end_typedef();
233 }
234 | any_typedef decl_specifiers
235 {
236 cur_decl_spec_flags = $2.flags;
237 free_decl_spec(&$2);
238 }
239 opt_declarator_list ';'
240 {
241 end_typedef();
242 }
243 ;
244
245 any_typedef
246 : T_EXTENSION T_TYPEDEF
247 {
248 begin_typedef();
249 }
250 | T_TYPEDEF
251 {
252 begin_typedef();
253 }
254 ;
255
256 opt_declarator_list
257 : /* empty */
258 | declarator_list
259 ;
260
261 declarator_list
262 : declarator
263 {
264 int flags = cur_decl_spec_flags;
265
266 /* If the typedef is a pointer type, then reset the short type
267 * flags so it does not get promoted.
268 */
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);
273 }
274 | declarator_list ',' declarator
275 {
276 int flags = cur_decl_spec_flags;
277
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);
282 }
283 ;
284
285 function_definition
286 : decl_specifiers declarator
287 {
288 check_untagged(&$1);
289 if ($2->func_def == FUNC_NONE) {
290 yyerror("syntax error");
291 YYERROR;
292 }
293 func_params = &($2->head->params);
294 func_params->begin_comment = cur_file->begin_comment;
295 func_params->end_comment = cur_file->end_comment;
296 }
297 opt_declaration_list T_LBRACE
298 {
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.
303 */
304 if (func_style == FUNC_TRADITIONAL
305 && haveAnsiParam()
306 && $2->head->func_def == func_style) {
307 $2->head->func_def = FUNC_BOTH;
308 }
309
310 func_params = NULL;
311
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);
320 }
321 T_MATCHRBRACE
322 | declarator
323 {
324 if ($1->func_def == FUNC_NONE) {
325 yyerror("syntax error");
326 YYERROR;
327 }
328 func_params = &($1->head->params);
329 func_params->begin_comment = cur_file->begin_comment;
330 func_params->end_comment = cur_file->end_comment;
331 }
332 opt_declaration_list T_LBRACE T_MATCHRBRACE
333 {
334 DeclSpec decl_spec;
335
336 func_params = NULL;
337
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);
347 }
348 ;
349
350 opt_declaration_list
351 : /* empty */
352 | T_VA_DCL
353 | declaration_list
354 ;
355
356 declaration_list
357 : declaration
358 | declaration_list declaration
359 ;
360
361 decl_specifiers
362 : decl_specifier
363 | decl_specifiers decl_specifier
364 {
365 join_decl_specs(&$$, &$1, &$2);
366 free($1.text);
367 free($2.text);
368 }
369 ;
370
371 decl_specifier
372 : storage_class
373 | type_specifier
374 | type_qualifier
375 ;
376
377 storage_class
378 : T_AUTO
379 {
380 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
381 }
382 | T_EXTERN
383 {
384 new_decl_spec(&$$, $1.text, $1.begin, DS_EXTERN);
385 }
386 | T_REGISTER
387 {
388 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
389 }
390 | T_STATIC
391 {
392 new_decl_spec(&$$, $1.text, $1.begin, DS_STATIC);
393 }
394 | T_INLINE
395 {
396 new_decl_spec(&$$, $1.text, $1.begin, DS_INLINE);
397 }
398 | T_EXTENSION
399 {
400 new_decl_spec(&$$, $1.text, $1.begin, DS_JUNK);
401 }
402 ;
403
404 type_specifier
405 : T_CHAR
406 {
407 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
408 }
409 | T_DOUBLE
410 {
411 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
412 }
413 | T_FLOAT
414 {
415 new_decl_spec(&$$, $1.text, $1.begin, DS_FLOAT);
416 }
417 | T_INT
418 {
419 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
420 }
421 | T_LONG
422 {
423 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
424 }
425 | T_SHORT
426 {
427 new_decl_spec(&$$, $1.text, $1.begin, DS_SHORT);
428 }
429 | T_SIGNED
430 {
431 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
432 }
433 | T_UNSIGNED
434 {
435 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
436 }
437 | T_VOID
438 {
439 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
440 }
441 | T_Bool
442 {
443 new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
444 }
445 | T_Complex
446 {
447 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
448 }
449 | T_Imaginary
450 {
451 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
452 }
453 | T_TYPEDEF_NAME
454 {
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);
459 }
460 | struct_or_union_specifier
461 | enum_specifier
462 ;
463
464 type_qualifier
465 : T_TYPE_QUALIFIER
466 {
467 new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
468 }
469 | T_DEFINE_NAME
470 {
471 /* This rule allows the <pointer> nonterminal to scan #define
472 * names as if they were type modifiers.
473 */
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);
478 }
479 ;
480
481 struct_or_union_specifier
482 : struct_or_union any_id braces
483 {
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);
488 }
489 | struct_or_union braces
490 {
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);
495 }
496 | struct_or_union any_id
497 {
498 (void)sprintf(buf, "%s %s", $1.text, $2.text);
499 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
500 }
501 ;
502
503 struct_or_union
504 : T_STRUCT
505 {
506 imply_typedef($$.text);
507 }
508 | T_UNION
509 {
510 imply_typedef($$.text);
511 }
512 ;
513
514 init_declarator_list
515 : init_declarator
516 {
517 new_decl_list(&$$, $1);
518 }
519 | init_declarator_list ',' init_declarator
520 {
521 add_decl_list(&$$, &$1, $3);
522 }
523 ;
524
525 init_declarator
526 : declarator
527 {
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);
532 }
533 cur_declarator = $$;
534 }
535 | declarator '='
536 {
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);
541 }
542 }
543 T_INITIALIZER
544 ;
545
546 enum_specifier
547 : enumeration any_id braces
548 {
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);
553 }
554 | enumeration braces
555 {
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);
560 }
561 | enumeration any_id
562 {
563 (void)sprintf(buf, "enum %s", $2.text);
564 new_decl_spec(&$$, buf, $1.begin, DS_NONE);
565 }
566 ;
567
568 enumeration
569 : T_ENUM
570 {
571 imply_typedef("enum");
572 $$ = $1;
573 }
574 ;
575
576 any_id
577 : T_IDENTIFIER
578 | T_TYPEDEF_NAME
579 ;
580
581 declarator
582 : pointer direct_declarator
583 {
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;
590 }
591 | direct_declarator
592 ;
593
594 direct_declarator
595 : identifier_or_ref
596 {
597 $$ = new_declarator($1.text, $1.text, $1.begin);
598 }
599 | '(' declarator ')'
600 {
601 $$ = $2;
602 (void)sprintf(buf, "(%s)", $$->text);
603 free($$->text);
604 $$->text = xstrdup(buf);
605 $$->begin = $1.begin;
606 }
607 | direct_declarator T_BRACKETS
608 {
609 $$ = $1;
610 (void)sprintf(buf, "%s%s", $$->text, $2.text);
611 free($$->text);
612 $$->text = xstrdup(buf);
613 }
614 | direct_declarator '(' parameter_type_list ')'
615 {
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;
621 }
622 | direct_declarator '(' opt_identifier_list ')'
623 {
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;
629 }
630 ;
631
632 pointer
633 : '*' opt_type_qualifiers
634 {
635 (void)sprintf($$.text, "*%s", $2.text);
636 $$.begin = $1.begin;
637 }
638 | '*' opt_type_qualifiers pointer
639 {
640 (void)sprintf($$.text, "*%s%s", $2.text, $3.text);
641 $$.begin = $1.begin;
642 }
643 ;
644
645 opt_type_qualifiers
646 : /* empty */
647 {
648 strcpy($$.text, "");
649 $$.begin = 0L;
650 }
651 | type_qualifier_list
652 ;
653
654 type_qualifier_list
655 : type_qualifier
656 {
657 (void)sprintf($$.text, "%s ", $1.text);
658 $$.begin = $1.begin;
659 free($1.text);
660 }
661 | type_qualifier_list type_qualifier
662 {
663 (void)sprintf($$.text, "%s%s ", $1.text, $2.text);
664 $$.begin = $1.begin;
665 free($2.text);
666 }
667 ;
668
669 parameter_type_list
670 : parameter_list
671 | parameter_list ',' T_ELLIPSIS
672 {
673 add_ident_list(&$$, &$1, "...");
674 }
675 ;
676
677 parameter_list
678 : parameter_declaration
679 {
680 new_param_list(&$$, $1);
681 }
682 | parameter_list ',' parameter_declaration
683 {
684 add_param_list(&$$, &$1, $3);
685 }
686 ;
687
688 parameter_declaration
689 : decl_specifiers declarator
690 {
691 check_untagged(&$1);
692 $$ = new_parameter(&$1, $2);
693 }
694 | decl_specifiers abs_declarator
695 {
696 check_untagged(&$1);
697 $$ = new_parameter(&$1, $2);
698 }
699 | decl_specifiers
700 {
701 check_untagged(&$1);
702 $$ = new_parameter(&$1, (Declarator *)0);
703 }
704 ;
705
706 opt_identifier_list
707 : /* empty */
708 {
709 new_ident_list(&$$);
710 }
711 | identifier_list
712 ;
713
714 identifier_list
715 : any_id
716 {
717 new_ident_list(&$$);
718 add_ident_list(&$$, &$$, $1.text);
719 }
720 | identifier_list ',' any_id
721 {
722 add_ident_list(&$$, &$1, $3.text);
723 }
724 ;
725
726 identifier_or_ref
727 : any_id
728 {
729 $$ = $1;
730 }
731 | '&' any_id
732 {
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;
740 }
741 ;
742
743 abs_declarator
744 : pointer
745 {
746 $$ = new_declarator($1.text, "", $1.begin);
747 }
748 | pointer direct_abs_declarator
749 {
750 $$ = $2;
751 (void)sprintf(buf, "%s%s", $1.text, $$->text);
752 free($$->text);
753 $$->text = xstrdup(buf);
754 $$->begin = $1.begin;
755 }
756 | direct_abs_declarator
757 ;
758
759 direct_abs_declarator
760 : '(' abs_declarator ')'
761 {
762 $$ = $2;
763 (void)sprintf(buf, "(%s)", $$->text);
764 free($$->text);
765 $$->text = xstrdup(buf);
766 $$->begin = $1.begin;
767 }
768 | direct_abs_declarator T_BRACKETS
769 {
770 $$ = $1;
771 (void)sprintf(buf, "%s%s", $$->text, $2.text);
772 free($$->text);
773 $$->text = xstrdup(buf);
774 }
775 | T_BRACKETS
776 {
777 $$ = new_declarator($1.text, "", $1.begin);
778 }
779 | direct_abs_declarator '(' parameter_type_list ')'
780 {
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;
786 }
787 | direct_abs_declarator '(' ')'
788 {
789 $$ = new_declarator("%s()", "", $1->begin);
790 $$->func_stack = $1;
791 $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
792 $$->func_def = FUNC_ANSI;
793 }
794 | '(' parameter_type_list ')'
795 {
796 Declarator *d;
797
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;
804 }
805 | '(' ')'
806 {
807 Declarator *d;
808
809 d = new_declarator("", "", $1.begin);
810 $$ = new_declarator("%s()", "", $1.begin);
811 $$->func_stack = d;
812 $$->head = $$;
813 $$->func_def = FUNC_ANSI;
814 }
815 ;
816
817 %%
818
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
828
829 static void
830 yaccError (char *msg)
831 {
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);
835 }
836
837 /* Initialize the table of type qualifier keywords recognized by the lexical
838 * analyzer.
839 */
840 void
841 init_parser (void)
842 {
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
907 };
908 unsigned i;
909
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);
914 }
915 }
916
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.
920 */
921 void
922 process_file (FILE *infile, char *name)
923 {
924 char *s;
925
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
936 }
937 }
938
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();
953 }
954 #endif
955 put_string(stdout, "/* ");
956 put_string(stdout, cur_file_name());
957 put_string(stdout, " */\n");
958 }
959 yyparse();
960 free_symbol_table(define_names);
961 free_symbol_table(typedef_names);
962 free_symbol_table(included_files);
963 }
964
965 #ifdef NO_LEAKS
966 void
967 free_parser(void)
968 {
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
974 }
975 #endif
976