home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / cproto-3.0 / grammar.y < prev    next >
Encoding:
Text File  |  1995-05-03  |  15.7 KB  |  764 lines

  1. /* $Id: grammar.y 3.8 1993/05/26 01:48:42 cthuang 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.  
  17.     /* type specifiers */
  18.     T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID
  19.     T_LONG T_SHORT T_SIGNED T_UNSIGNED
  20.     T_ENUM T_STRUCT T_UNION
  21.  
  22.     /* type qualifiers */
  23.     T_TYPE_QUALIFIER
  24.  
  25.     /* paired square brackets and everything between them: [ ... ] */
  26.     T_BRACKETS
  27.  
  28. %token
  29.     /* left brace */
  30.     T_LBRACE
  31.     /* all input to the matching right brace */
  32.     T_MATCHRBRACE
  33.  
  34.     /* three periods */
  35.     T_ELLIPSIS
  36.  
  37.     /* constant expression or paired braces following an equal sign */
  38.     T_INITIALIZER
  39.  
  40.     /* string literal */
  41.     T_STRING_LITERAL
  42.  
  43.     /* asm */
  44.     T_ASM
  45.     /* ( "string literal" ) following asm keyword */
  46.     T_ASMARG
  47.  
  48.     /* va_dcl from <varargs.h> */
  49.     T_VA_DCL
  50.  
  51. %type <decl_spec> decl_specifiers decl_specifier
  52. %type <decl_spec> storage_class type_specifier type_qualifier
  53. %type <decl_spec> struct_or_union_specifier enum_specifier
  54. %type <decl_list> init_declarator_list
  55. %type <declarator> init_declarator declarator direct_declarator
  56. %type <declarator> abs_declarator direct_abs_declarator
  57. %type <param_list> parameter_type_list parameter_list
  58. %type <parameter> parameter_declaration
  59. %type <param_list> opt_identifier_list identifier_list
  60. %type <text> struct_or_union pointer opt_type_qualifiers type_qualifier_list
  61.     any_id
  62.  
  63. %{
  64. #include <stdio.h>
  65. #include "cproto.h"
  66. #include "symbol.h"
  67. #include "semantic.h"
  68.  
  69. #define YYMAXDEPTH 150
  70.  
  71. /* declaration specifier attributes for the typedef statement currently being
  72.  * scanned
  73.  */
  74. static int cur_decl_spec_flags;
  75.  
  76. /* pointer to parameter list for the current function definition */
  77. static ParameterList *func_params;
  78.  
  79. /* A parser semantic action sets this pointer to the current declarator in
  80.  * a function parameter declaration in order to catch any comments following
  81.  * the parameter declaration on the same line.  If the lexer scans a comment
  82.  * and <cur_declarator> is not NULL, then the comment is attached to the
  83.  * declarator.  To ignore subsequent comments, the lexer sets this to NULL
  84.  * after scanning a comment or end of line.
  85.  */
  86. static Declarator *cur_declarator;
  87.  
  88. /* temporary string buffer */
  89. static char buf[MAX_TEXT_SIZE];
  90.  
  91. /* table of typedef names */
  92. static SymbolTable *typedef_names;
  93.  
  94. /* table of define names */
  95. static SymbolTable *define_names;
  96.  
  97. /* table of type qualifiers */
  98. static SymbolTable *type_qualifiers;
  99.  
  100. /* information about the current input file */
  101. typedef struct {
  102.     char *base_name;        /* base input file name */
  103.     char *file_name;        /* current file name */
  104.     FILE *file;         /* input file */
  105.     unsigned line_num;        /* current line number in input file */
  106.     FILE *tmp_file;        /* temporary file */
  107.     long begin_comment;     /* tmp file offset after last written ) or ; */
  108.     long end_comment;        /* tmp file offset after last comment */
  109.     boolean convert;        /* if TRUE, convert function definitions */
  110.     boolean changed;        /* TRUE if conversion done in this file */
  111. } IncludeStack;
  112.  
  113. static IncludeStack *cur_file;    /* current input file */
  114.  
  115. extern void yyerror();
  116. %}
  117. %%
  118.  
  119. program
  120.     : /* empty */
  121.     | translation_unit
  122.     ;
  123.  
  124. translation_unit
  125.     : external_declaration
  126.     | translation_unit external_declaration
  127.     ;
  128.  
  129. external_declaration
  130.     : declaration
  131.     | function_definition
  132.     | function_definition ';'
  133.     | linkage_specification
  134.     | T_ASM T_ASMARG ';'
  135.     | error ';'
  136.     {
  137.         yyerrok;
  138.     }
  139.     | error T_MATCHRBRACE
  140.     {
  141.         yyerrok;
  142.     }
  143.     ;
  144.  
  145. braces
  146.     : T_LBRACE T_MATCHRBRACE
  147.     ;
  148.  
  149. linkage_specification
  150.     : T_EXTERN T_STRING_LITERAL braces
  151.     {
  152.         /* Provide an empty action here so bison will not complain about
  153.          * incompatible types in the default action it normally would
  154.          * have generated.
  155.          */
  156.     }
  157.     | T_EXTERN T_STRING_LITERAL declaration
  158.     {
  159.         /* empty */
  160.     }
  161.     ;
  162.  
  163. declaration
  164.     : decl_specifiers ';'
  165.     {
  166.         free_decl_spec(&$1);
  167.     }
  168.     | decl_specifiers init_declarator_list ';'
  169.     {
  170.         if (func_params != NULL) {
  171.         set_param_types(func_params, &$1, &$2);
  172.         } else {
  173.         gen_declarations(&$1, &$2);
  174.         free_decl_list(&$2);
  175.         }
  176.         free_decl_spec(&$1);
  177.     }
  178.     | T_TYPEDEF decl_specifiers
  179.     {
  180.         cur_decl_spec_flags = $2.flags;
  181.         free_decl_spec(&$2);
  182.     }
  183.       opt_declarator_list ';'
  184.     ;
  185.  
  186. opt_declarator_list
  187.     : /* empty */
  188.     | declarator_list
  189.     ;
  190.  
  191. declarator_list
  192.     : declarator
  193.     {
  194.         int flags = cur_decl_spec_flags;
  195.  
  196.         /* If the typedef is a pointer type, then reset the short type
  197.          * flags so it does not get promoted.
  198.          */
  199.         if (strcmp($1->text, $1->name) != 0)
  200.         flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
  201.         new_symbol(typedef_names, $1->name, NULL, flags);
  202.         free_declarator($1);
  203.     }
  204.     | declarator_list ',' declarator
  205.     {
  206.         int flags = cur_decl_spec_flags;
  207.  
  208.         if (strcmp($3->text, $3->name) != 0)
  209.         flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT);
  210.         new_symbol(typedef_names, $3->name, NULL, flags);
  211.         free_declarator($3);
  212.     }
  213.     ;
  214.  
  215. function_definition
  216.     : decl_specifiers declarator
  217.     {
  218.         check_untagged(&$1);
  219.         if ($2->func_def == FUNC_NONE) {
  220.         yyerror("syntax error");
  221.         YYERROR;
  222.         }
  223.         func_params = &($2->head->params);
  224.         func_params->begin_comment = cur_file->begin_comment;
  225.         func_params->end_comment = cur_file->end_comment;
  226.     }
  227.       opt_declaration_list T_LBRACE
  228.     {
  229.         func_params = NULL;
  230.  
  231.         if (cur_file->convert)
  232.         gen_func_definition(&$1, $2);
  233.         gen_prototype(&$1, $2);
  234.         free_decl_spec(&$1);
  235.         free_declarator($2);
  236.     }
  237.       T_MATCHRBRACE
  238.     | declarator
  239.     {
  240.         if ($1->func_def == FUNC_NONE) {
  241.         yyerror("syntax error");
  242.         YYERROR;
  243.         }
  244.         func_params = &($1->head->params);
  245.         func_params->begin_comment = cur_file->begin_comment;
  246.         func_params->end_comment = cur_file->end_comment;
  247.     }
  248.       opt_declaration_list T_LBRACE
  249.     {
  250.         DeclSpec decl_spec;
  251.  
  252.         func_params = NULL;
  253.  
  254.         new_decl_spec(&decl_spec, "int", $1->begin, DS_NONE);
  255.         if (cur_file->convert)
  256.         gen_func_definition(&decl_spec, $1);
  257.         gen_prototype(&decl_spec, $1);
  258.         free_decl_spec(&decl_spec);
  259.         free_declarator($1);
  260.     }
  261.       T_MATCHRBRACE
  262.     ;
  263.  
  264. opt_declaration_list
  265.     : /* empty */
  266.     | T_VA_DCL
  267.     | declaration_list
  268.     ;
  269.  
  270. declaration_list
  271.     : declaration
  272.     | declaration_list declaration
  273.     ;
  274.  
  275. decl_specifiers
  276.     : decl_specifier
  277.     | decl_specifiers decl_specifier
  278.     {
  279.         join_decl_specs(&$$, &$1, &$2);
  280.         free($1.text);
  281.         free($2.text);
  282.     }
  283.     ;
  284.  
  285. decl_specifier
  286.     : storage_class
  287.     | type_specifier
  288.     | type_qualifier
  289.     ;
  290.  
  291. storage_class
  292.     : T_AUTO
  293.     {
  294.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  295.     }
  296.     | T_EXTERN
  297.     {
  298.         new_decl_spec(&$$, $1.text, $1.begin, DS_EXTERN);
  299.     }
  300.     | T_REGISTER
  301.     {
  302.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  303.     }
  304.     | T_STATIC
  305.     {
  306.         new_decl_spec(&$$, $1.text, $1.begin, DS_STATIC);
  307.     }
  308.     | T_INLINE
  309.     {
  310.         new_decl_spec(&$$, $1.text, $1.begin, DS_JUNK);
  311.     }
  312.     ;
  313.  
  314. type_specifier
  315.     : T_CHAR
  316.     {
  317.         new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR);
  318.     }
  319.     | T_DOUBLE
  320.     {
  321.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  322.     }
  323.     | T_FLOAT
  324.     {
  325.         new_decl_spec(&$$, $1.text, $1.begin, DS_FLOAT);
  326.     }
  327.     | T_INT
  328.     {
  329.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  330.     }
  331.     | T_LONG
  332.     {
  333.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  334.     }
  335.     | T_SHORT
  336.     {
  337.         new_decl_spec(&$$, $1.text, $1.begin, DS_SHORT);
  338.     }
  339.     | T_SIGNED
  340.     {
  341.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  342.     }
  343.     | T_UNSIGNED
  344.     {
  345.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  346.     }
  347.     | T_VOID
  348.     {
  349.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  350.     }
  351.     | T_TYPEDEF_NAME
  352.     {
  353.         Symbol *s;
  354.         s = find_symbol(typedef_names, $1.text);
  355.         if (s != NULL)
  356.         new_decl_spec(&$$, $1.text, $1.begin, s->flags);
  357.     }
  358.     | struct_or_union_specifier
  359.     | enum_specifier
  360.     ;
  361.  
  362. type_qualifier
  363.     : T_TYPE_QUALIFIER
  364.     {
  365.         new_decl_spec(&$$, $1.text, $1.begin, DS_NONE);
  366.     }
  367.     | T_DEFINE_NAME
  368.     {
  369.         /* This rule allows the <pointer> nonterminal to scan #define
  370.          * names as if they were type modifiers.
  371.          */
  372.         Symbol *s;
  373.         s = find_symbol(define_names, $1.text);
  374.         if (s != NULL)
  375.         new_decl_spec(&$$, $1.text, $1.begin, s->flags);
  376.     }
  377.     ;
  378.  
  379. struct_or_union_specifier
  380.     : struct_or_union any_id braces
  381.     {
  382.         sprintf(buf, "%s %s", $1.text, $2.text);
  383.         new_decl_spec(&$$, buf, $1.begin, DS_NONE);
  384.     }
  385.     | struct_or_union braces
  386.     {
  387.         sprintf(buf, "%s {}", $1.text);
  388.         new_decl_spec(&$$, buf, $1.begin, DS_NONE);
  389.     }
  390.     | struct_or_union any_id
  391.     {
  392.         sprintf(buf, "%s %s", $1.text, $2.text);
  393.         new_decl_spec(&$$, buf, $1.begin, DS_NONE);
  394.     }
  395.     ;
  396.  
  397. struct_or_union
  398.     : T_STRUCT
  399.     | T_UNION
  400.     ;
  401.  
  402. init_declarator_list
  403.     : init_declarator
  404.     {
  405.         new_decl_list(&$$, $1);
  406.     }
  407.     | init_declarator_list ',' init_declarator
  408.     {
  409.         add_decl_list(&$$, &$1, $3);
  410.     }
  411.     ;
  412.  
  413. init_declarator
  414.     : declarator
  415.     {
  416.         if ($1->func_def != FUNC_NONE && func_params == NULL &&
  417.         func_style == FUNC_TRADITIONAL && cur_file->convert) {
  418.         gen_func_declarator($1);
  419.         fputs(cur_text(), cur_file->tmp_file);
  420.         }
  421.         cur_declarator = $$;
  422.     }
  423.     | declarator '='
  424.     {
  425.         if ($1->func_def != FUNC_NONE && func_params == NULL &&
  426.         func_style == FUNC_TRADITIONAL && cur_file->convert) {
  427.         gen_func_declarator($1);
  428.         fputs(" =", cur_file->tmp_file);
  429.         }
  430.     }
  431.       T_INITIALIZER
  432.     ;
  433.  
  434. enum_specifier
  435.     : T_ENUM any_id braces
  436.     {
  437.         sprintf(buf, "enum %s", $2.text);
  438.         new_decl_spec(&$$, buf, $1.begin, DS_NONE);
  439.     }
  440.     | T_ENUM braces
  441.     {
  442.         new_decl_spec(&$$, "enum {}", $1.begin, DS_NONE);
  443.     }
  444.     | T_ENUM any_id
  445.     {
  446.         sprintf(buf, "enum %s", $2.text);
  447.         new_decl_spec(&$$, buf, $1.begin, DS_NONE);
  448.     }
  449.     ;
  450.  
  451. any_id
  452.     : T_IDENTIFIER
  453.     | T_TYPEDEF_NAME
  454.     ;
  455.  
  456. declarator
  457.     : pointer direct_declarator
  458.     {
  459.         $$ = $2;
  460.         sprintf(buf, "%s%s", $1.text, $$->text);
  461.         free($$->text);
  462.         $$->text = xstrdup(buf);
  463.         $$->begin = $1.begin;
  464.         $$->pointer = TRUE;
  465.     }
  466.     | direct_declarator
  467.     ;
  468.  
  469. direct_declarator
  470.     : T_IDENTIFIER
  471.     {
  472.         $$ = new_declarator($1.text, $1.text, $1.begin);
  473.     }
  474.     | '(' declarator ')'
  475.     {
  476.         $$ = $2;
  477.         sprintf(buf, "(%s)", $$->text);
  478.         free($$->text);
  479.         $$->text = xstrdup(buf);
  480.         $$->begin = $1.begin;
  481.     }
  482.     | direct_declarator T_BRACKETS
  483.     {
  484.         $$ = $1;
  485.         sprintf(buf, "%s%s", $$->text, $2.text);
  486.         free($$->text);
  487.         $$->text = xstrdup(buf);
  488.     }
  489.     | direct_declarator '(' parameter_type_list ')'
  490.     {
  491.         $$ = new_declarator("%s()", $1->name, $1->begin);
  492.         $$->params = $3;
  493.         $$->func_stack = $1;
  494.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  495.         $$->func_def = FUNC_ANSI;
  496.     }
  497.     | direct_declarator '(' opt_identifier_list ')'
  498.     {
  499.         $$ = new_declarator("%s()", $1->name, $1->begin);
  500.         $$->params = $3;
  501.         $$->func_stack = $1;
  502.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  503.         $$->func_def = FUNC_TRADITIONAL;
  504.     }
  505.     ;
  506.  
  507. pointer
  508.     : '*' opt_type_qualifiers
  509.     {
  510.         sprintf($$.text, "*%s", $2.text);
  511.         $$.begin = $1.begin;
  512.     }
  513.     | '*' opt_type_qualifiers pointer
  514.     {
  515.         sprintf($$.text, "*%s%s", $2.text, $3.text);
  516.         $$.begin = $1.begin;
  517.     }
  518.     ;
  519.  
  520. opt_type_qualifiers
  521.     : /* empty */
  522.     {
  523.         strcpy($$.text, "");
  524.         $$.begin = 0L;
  525.     }
  526.     | type_qualifier_list
  527.     ;
  528.  
  529. type_qualifier_list
  530.     : type_qualifier
  531.     {
  532.         sprintf($$.text, "%s ", $1.text);
  533.         $$.begin = $1.begin;
  534.         free($1.text);
  535.     }
  536.     | type_qualifier_list type_qualifier
  537.     {
  538.         sprintf($$.text, "%s%s ", $1.text, $2.text);
  539.         $$.begin = $1.begin;
  540.         free($2.text);
  541.     }
  542.     ;
  543.  
  544. parameter_type_list
  545.     : parameter_list
  546.     | parameter_list ',' T_ELLIPSIS
  547.     {
  548.         add_ident_list(&$$, &$1, "...");
  549.     }
  550.     ;
  551.  
  552. parameter_list
  553.     : parameter_declaration
  554.     {
  555.         new_param_list(&$$, $1);
  556.     }
  557.     | parameter_list ',' parameter_declaration
  558.     {
  559.         add_param_list(&$$, &$1, $3);
  560.     }
  561.     ;
  562.  
  563. parameter_declaration
  564.     : decl_specifiers declarator
  565.     {
  566.         check_untagged(&$1);
  567.         $$ = new_parameter(&$1, $2);
  568.     }
  569.     | decl_specifiers abs_declarator
  570.     {
  571.         check_untagged(&$1);
  572.         $$ = new_parameter(&$1, $2);
  573.     }
  574.     | decl_specifiers
  575.     {
  576.         check_untagged(&$1);
  577.         $$ = new_parameter(&$1, NULL);
  578.     }
  579.     ;
  580.  
  581. opt_identifier_list
  582.     : /* empty */
  583.     {
  584.         new_ident_list(&$$);
  585.     }
  586.     | identifier_list
  587.     ;
  588.  
  589. identifier_list
  590.     : T_IDENTIFIER
  591.     {
  592.         new_ident_list(&$$);
  593.         add_ident_list(&$$, &$$, $1.text);
  594.     }
  595.     | identifier_list ',' T_IDENTIFIER
  596.     {
  597.         add_ident_list(&$$, &$1, $3.text);
  598.     }
  599.     ;
  600.  
  601. abs_declarator
  602.     : pointer
  603.     {
  604.         $$ = new_declarator($1.text, "", $1.begin);
  605.     }
  606.     | pointer direct_abs_declarator
  607.     {
  608.         $$ = $2;
  609.         sprintf(buf, "%s%s", $1.text, $$->text);
  610.         free($$->text);
  611.         $$->text = xstrdup(buf);
  612.         $$->begin = $1.begin;
  613.     }
  614.     | direct_abs_declarator
  615.     ;
  616.  
  617. direct_abs_declarator
  618.     : '(' abs_declarator ')'
  619.     {
  620.         $$ = $2;
  621.         sprintf(buf, "(%s)", $$->text);
  622.         free($$->text);
  623.         $$->text = xstrdup(buf);
  624.         $$->begin = $1.begin;
  625.     }
  626.     | direct_abs_declarator T_BRACKETS
  627.     {
  628.         $$ = $1;
  629.         sprintf(buf, "%s%s", $$->text, $2.text);
  630.         free($$->text);
  631.         $$->text = xstrdup(buf);
  632.     }
  633.     | T_BRACKETS
  634.     {
  635.         $$ = new_declarator($1.text, "", $1.begin);
  636.     }
  637.     | direct_abs_declarator '(' parameter_type_list ')'
  638.     {
  639.         $$ = new_declarator("%s()", "", $1->begin);
  640.         $$->params = $3;
  641.         $$->func_stack = $1;
  642.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  643.         $$->func_def = FUNC_ANSI;
  644.     }
  645.     | direct_abs_declarator '(' ')'
  646.     {
  647.         $$ = new_declarator("%s()", "", $1->begin);
  648.         $$->func_stack = $1;
  649.         $$->head = ($1->func_stack == NULL) ? $$ : $1->head;
  650.         $$->func_def = FUNC_ANSI;
  651.     }
  652.     | '(' parameter_type_list ')'
  653.     {
  654.         Declarator *d;
  655.         
  656.         d = new_declarator("", "", $1.begin);
  657.         $$ = new_declarator("%s()", "", $1.begin);
  658.         $$->params = $2;
  659.         $$->func_stack = d;
  660.         $$->head = $$;
  661.         $$->func_def = FUNC_ANSI;
  662.     }
  663.     | '(' ')'
  664.     {
  665.         Declarator *d;
  666.         
  667.         d = new_declarator("", "", $1.begin);
  668.         $$ = new_declarator("%s()", "", $1.begin);
  669.         $$->func_stack = d;
  670.         $$->head = $$;
  671.         $$->func_def = FUNC_ANSI;
  672.     }
  673.     ;
  674.  
  675. %%
  676.  
  677. #if defined(MSDOS) || defined(OS2)
  678. #include "lex_yy.c"
  679. #else
  680. #include "lex.yy.c"
  681. #endif
  682.  
  683. void
  684. yyerror (msg)
  685. char *msg;
  686. {
  687.     func_params = NULL;
  688.     put_error();
  689.     fprintf(stderr, "%s\n", msg);
  690. }
  691.  
  692. /* Initialize the table of type qualifier keywords recognized by the lexical
  693.  * analyzer.
  694.  */
  695. void
  696. init_parser ()
  697. {
  698.     static char *keywords[] = {
  699.     "const", "volatile", "interrupt",
  700. #if defined(MSDOS) || defined(OS2)
  701.     "cdecl", "far", "huge", "near", "pascal",
  702.     "_cdecl", "_export", "_far", "_fastcall", "_fortran", "_huge",
  703.     "_interrupt", "_loadds", "_near", "_pascal", "_saveregs", "_segment",
  704.     "_cs", "_ds", "_es", "_ss", "_seg",
  705.     "__cdecl", "__export", "__far", "__fastcall", "__fortran", "__huge",
  706.     "__inline", "__interrupt", "__loadds", "__near", "__pascal",
  707.     "__saveregs", "__segment", "__stdcall", "__syscall",
  708. #ifdef OS2
  709.     "__far16",
  710. #endif
  711. #else
  712.     "__const", "__inline__",
  713. #endif
  714.     };
  715.     int i;
  716.  
  717.     /* Initialize type qualifier table. */
  718.     type_qualifiers = new_symbol_table();
  719.     for (i = 0; i < sizeof(keywords)/sizeof(keywords[0]); ++i) {
  720.     new_symbol(type_qualifiers, keywords[i], NULL, DS_NONE);
  721.     }
  722. }
  723.  
  724. /* Process the C source file.  Write function prototypes to the standard
  725.  * output.  Convert function definitions and write the converted source
  726.  * code to a temporary file.
  727.  */
  728. void
  729. process_file (infile, name)
  730. FILE *infile;
  731. char *name;
  732. {
  733.     char *s;
  734.  
  735.     if (strlen(name) > 2) {
  736.     s = name + strlen(name) - 2;
  737.     if (*s == '.') {
  738.         ++s;
  739.         if (*s == 'l' || *s == 'y')
  740.         BEGIN LEXYACC;
  741. #if defined(MSDOS) || defined(OS2)
  742.         if (*s == 'L' || *s == 'Y')
  743.         BEGIN LEXYACC;
  744. #endif
  745.     }
  746.     }
  747.  
  748.     included_files = new_symbol_table();
  749.     typedef_names = new_symbol_table();
  750.     define_names = new_symbol_table();
  751.     inc_depth = -1;
  752.     curly = 0;
  753.     ly_count = 0;
  754.     func_params = NULL;
  755.     yyin = infile;
  756.     include_file(name, func_style != FUNC_NONE);
  757.     if (file_comments)
  758.     printf("/* %s */\n", cur_file_name());
  759.     yyparse();
  760.     free_symbol_table(define_names);
  761.     free_symbol_table(typedef_names);
  762.     free_symbol_table(included_files);
  763. }
  764.