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