home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cproto.zip / cproto46 / grammar.y < prev    next >
Text File  |  1998-01-20  |  19KB  |  910 lines

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