home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CPROTOS.ZIP / GRAM.Y next >
Text File  |  1991-02-19  |  18KB  |  885 lines

  1. /*   
  2.    This is a grammar for parsing ANSI C.  Its not in a finished
  3.    state, but its pretty close.   This is all covered under the 
  4.    GNU Public lic. -- that means its free software, period.
  5.  
  6.    mtr (mtr@ai.mit.edu)
  7. */
  8.  
  9.  
  10. /*  Tokens for C.  */
  11.  
  12. %token IDENTIFIER CONSTANT STRING_LITERAL SIZEOF
  13. %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
  14. %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
  15. %token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
  16. %token XOR_ASSIGN OR_ASSIGN TYPE_NAME
  17.  
  18. %token TYPEDEF EXTERN STATIC AUTO REGISTER
  19. %token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
  20. %token STRUCT UNION ENUM ELIPSIS
  21.  
  22. /*  Reserved words.  */
  23. %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
  24.  
  25. %start translation_unit
  26. %%
  27.  
  28. primary_expr
  29.     : identifier
  30.     | CONSTANT
  31.     | STRING_LITERAL
  32.     | '(' expr ')'
  33.     ;
  34.  
  35. postfix_expr
  36.     : primary_expr
  37.     | postfix_expr '[' expr ']'
  38.     | postfix_expr '(' ')'
  39.     | postfix_expr '(' argument_expr_list ')'
  40.     | postfix_expr '.' identifier
  41.     | postfix_expr PTR_OP identifier
  42.     | postfix_expr INC_OP
  43.     | postfix_expr DEC_OP
  44.     ;
  45.  
  46. argument_expr_list
  47.     : assignment_expr
  48.     | argument_expr_list ',' assignment_expr
  49.     ;
  50.  
  51. unary_expr
  52.     : postfix_expr
  53.     | INC_OP unary_expr
  54.     | DEC_OP unary_expr
  55.     | unary_operator cast_expr
  56.     | SIZEOF unary_expr
  57.     | SIZEOF '(' type_name ')'
  58.     ;
  59.  
  60. unary_operator
  61.     : '&' | '*' | '+' | '-' | '~' | '!'
  62.     ;
  63.  
  64. cast_expr
  65.     : unary_expr
  66.     | '(' type_name ')' cast_expr
  67.     ;
  68.  
  69. multiplicative_expr
  70.     : cast_expr
  71.     | multiplicative_expr '*' cast_expr
  72.     | multiplicative_expr '/' cast_expr
  73.     | multiplicative_expr '%' cast_expr
  74.     ;
  75.  
  76. additive_expr
  77.     : multiplicative_expr
  78.     | additive_expr '+' multiplicative_expr
  79.     | additive_expr '-' multiplicative_expr
  80.     ;
  81.  
  82. shift_expr
  83.     : additive_expr
  84.     | shift_expr LEFT_OP additive_expr
  85.     | shift_expr RIGHT_OP additive_expr
  86.     ;
  87.  
  88. relational_expr
  89.     : shift_expr
  90.     | relational_expr '<' shift_expr
  91.     | relational_expr '>' shift_expr
  92.     | relational_expr LE_OP shift_expr
  93.     | relational_expr GE_OP shift_expr
  94.     ;
  95.  
  96. equality_expr
  97.     : relational_expr
  98.     | equality_expr EQ_OP relational_expr
  99.     | equality_expr NE_OP relational_expr
  100.     ;
  101.  
  102. and_expr
  103.     : equality_expr
  104.     | and_expr '&' equality_expr
  105.     ;
  106.  
  107. exclusive_or_expr
  108.     : and_expr
  109.     | exclusive_or_expr '^' and_expr
  110.     ;
  111.  
  112. inclusive_or_expr
  113.     : exclusive_or_expr
  114.     | inclusive_or_expr '|' exclusive_or_expr
  115.     ;
  116.  
  117. logical_and_expr
  118.     : inclusive_or_expr
  119.     | logical_and_expr AND_OP inclusive_or_expr
  120.     ;
  121.  
  122. logical_or_expr
  123.     : logical_and_expr
  124.     | logical_or_expr OR_OP logical_and_expr
  125.     ;
  126.  
  127. conditional_expr
  128.     : logical_or_expr
  129.     | logical_or_expr '?' expr ':' conditional_expr
  130.     ;
  131.  
  132. assignment_expr
  133.     : conditional_expr
  134.     | unary_expr assignment_operator assignment_expr
  135.     ;
  136.  
  137. assignment_operator
  138.     : '=' | MUL_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | ADD_ASSIGN | SUB_ASSIGN
  139.     | LEFT_ASSIGN | RIGHT_ASSIGN | AND_ASSIGN | XOR_ASSIGN | OR_ASSIGN
  140.     ;
  141.  
  142. expr
  143.     : assignment_expr
  144.     | expr ',' assignment_expr
  145.     ;
  146.  
  147. constant_expr
  148.     : conditional_expr
  149.     ;
  150.  
  151. declaration
  152.     : declaration_specifiers ';'
  153.             {
  154.           $$ = $1;
  155.         }
  156.     | declaration_specifiers  /* { reset_is_a_type = is_a_type; } */ init_declarator_list ';'
  157.             {
  158.           reset_is_a_type = 0;
  159.           $$ = make_root ("nop", NOP);
  160.           ((TRnode *) $$)->left = $1;
  161.           ((TRnode *) $$)->right = $2;
  162.  
  163.           /*  This is such a hack.  In the case for a list of 
  164.           typedefs (eg "typedef int i, j, k; ") or a list of
  165.           structure tags (eg "struct { int i; } node, *ptr; ").  */
  166.  
  167.           if (0 == strcmp (((TRnode *) $$)->left->pc, "struct") ||
  168.           (0 == strcmp (((TRnode *) $$)->left->pc, "typedef")))
  169.         make_types ($2);
  170.  
  171.         }
  172.     ;
  173.  
  174. declaration_specifiers
  175.     : storage_class_specifier
  176.             {
  177.           $$ = $1;
  178.         }
  179.     | storage_class_specifier declaration_specifiers 
  180.             {
  181.           $$ = $1;
  182.           if ($1 != 0)
  183.         ((TRnode *) $1)->right = $2;
  184.         }
  185.     | type_specifier
  186.             {
  187.           $$ = $1;
  188.         }
  189.     | type_specifier declaration_specifiers
  190.             { 
  191.           $$ = $1;
  192.  
  193.           if ($1 != 0)
  194.         ((TRnode *) $1)->right = $2;
  195.         }
  196.     | type_qualifier
  197.             {
  198.           $$ = $1;
  199.         }
  200.     | type_qualifier declaration_specifiers
  201.             { 
  202.           $$ = $1;
  203.           if ($1 != 0)
  204.         ((TRnode *) $1)->right = $2;
  205.         }
  206.     ;
  207.  
  208. init_declarator_list
  209.      : init_declarator
  210.         {
  211.           $$ = $1;
  212.         }
  213.     | init_declarator_list ',' init_declarator
  214.         {
  215.           $$ = make_root ("nop", NOP);
  216.           ((TRnode *) $$)->left = $1;
  217.           ((TRnode *) $$)->right = $3;
  218.         }
  219.     ;
  220.  
  221. init_declarator
  222.     : declarator
  223.         {
  224.           $$ = $1;
  225.         }
  226.     | declarator '=' initializer
  227.         {
  228.           $$ = make_root ("=", OP);
  229.  
  230.           ((TRnode *) $$)->left = $1;
  231.           ((TRnode *) $$)->right = $3;
  232.         }
  233.     ;
  234.  
  235. storage_class_specifier
  236.     : TYPEDEF 
  237.             {
  238.           set_type ();
  239.           $$ = make_root ("typedef", STORAGE_CLASS);
  240.         }
  241.         | EXTERN 
  242.             {
  243.           $$ = make_root ("extern", STORAGE_CLASS);
  244.         }
  245.         | STATIC 
  246.             {
  247.           $$ = make_root ("static", STORAGE_CLASS);
  248.         }
  249.         | AUTO 
  250.             {
  251.           $$ = make_root ("auto", STORAGE_CLASS);
  252.         }
  253.  
  254.         | REGISTER
  255.             {
  256.           $$ = make_root ("register", STORAGE_CLASS);
  257.         }
  258.     ;
  259.  
  260. type_specifier
  261.     : VOID 
  262.             {
  263.           $$ = make_root ("void", TYPE);
  264.         }
  265.         | CHAR 
  266.             {
  267.           $$ = make_root ("char", TYPE);
  268.         }
  269.         | SHORT 
  270.             {
  271.           $$ = make_root ("short", TYPE);
  272.         }
  273.         | INT 
  274.             {
  275.           $$ = make_root ("int", TYPE);
  276.         }
  277.         | LONG
  278.             {
  279.           $$ = make_root ("long", TYPE);
  280.         }
  281.     | FLOAT 
  282.             {
  283.           $$ = make_root ("float", TYPE);
  284.         }
  285.         | DOUBLE 
  286.             {
  287.           $$ = make_root ("double", TYPE);
  288.         }
  289.         | SIGNED 
  290.             {
  291.           $$ = make_root ("signed", TYPE);
  292.         }
  293.         | UNSIGNED
  294.             {
  295.           $$ = make_root ("unsigned", TYPE);
  296.         }
  297.     | struct_or_union_specifier 
  298.             {
  299.           $$ = $1;
  300.         }
  301.     | enum_specifier
  302.             { 
  303.           $$ = $1;
  304.               set_type (); 
  305.             }
  306.     | TYPE_NAME 
  307.             {
  308.           $$ = make_root (yytext, TYPE);
  309.         }
  310.     ;
  311.  
  312. struct_or_union_specifier
  313.     : struct_or_union 
  314.             { 
  315.           /* unset_type ();  */
  316.           reset_is_a_type = is_a_type;
  317.           unset_type ();
  318.         } 
  319.           '{' { ++in_struct; } struct_declaration_list { --in_struct; } '}' 
  320.             { 
  321.           if (reset_is_a_type)
  322.         set_type (); 
  323.         }
  324.     | struct_or_union  identifier 
  325.             { 
  326.           /* add_type (((TRnode *) $2)->pc); */
  327.           reset_is_a_type = is_a_type;
  328.           unset_type (); 
  329.         } 
  330.           '{' { ++in_struct; } struct_declaration_list { --in_struct; } '}' 
  331.             {
  332.           if (reset_is_a_type)
  333.         set_type (); 
  334.         }
  335.     | struct_or_union identifier 
  336.             {
  337.           /* POSSIBLY... */
  338.           /* set_type ();  */
  339.           $$ = $2;
  340.           if (0 != $$)
  341.         ((TRnode *) $$)->left = $1;
  342.         }
  343.     ;
  344.  
  345. struct_or_union
  346.     : STRUCT
  347.             {
  348.           $$ = make_root ("struct", LABEL);
  349.         }
  350.         | UNION
  351.             {
  352.           $$ = make_root ("union", LABEL);
  353.         }
  354.     ;
  355.  
  356. struct_declaration_list
  357.     : struct_declaration
  358.     | struct_declaration_list struct_declaration
  359.     ;
  360.  
  361. struct_declaration
  362.     : specifier_qualifier_list struct_declarator_list ';'
  363.     ;
  364.  
  365. specifier_qualifier_list
  366.     : type_specifier
  367.     | type_specifier specifier_qualifier_list
  368.     | type_qualifier
  369.     | type_qualifier specifier_qualifier_list
  370.     ;
  371.  
  372. struct_declarator_list
  373.     : struct_declarator
  374.     | struct_declarator_list ',' struct_declarator
  375.     ;
  376.  
  377. struct_declarator
  378.     : declarator
  379.     | ':' constant_expr
  380.     | declarator ':' constant_expr
  381.     ;
  382.  
  383. enum_specifier
  384.     : ENUM '{' enumerator_list '}'
  385.         | ENUM '{' enumerator_list ',' '}'
  386.     | ENUM identifier '{' enumerator_list '}'
  387.         | ENUM identifier '{' enumerator_list ',' '}'
  388.     | ENUM identifier
  389.     ;
  390.  
  391. enumerator_list
  392.     : enumerator
  393. /*        | enumerator ',' */
  394.     | enumerator_list ',' enumerator
  395.     ;
  396.  
  397. enumerator
  398.     : identifier
  399.     | identifier '=' constant_expr
  400.     ;
  401.  
  402. type_qualifier
  403.     : CONST
  404.             {
  405.           $$ = make_root ("const", LABEL);
  406.         }
  407.         | VOLATILE
  408.             {
  409.           $$ = make_root ("volatile", LABEL);
  410.         }
  411.     ;
  412.  
  413. declarator
  414.         : direct_declarator
  415.             { 
  416.           $$ = $1; 
  417.         }
  418.         | pointer direct_declarator
  419.             {
  420.           $$ = make_root ("nop", NOP);
  421.           ((TRnode *) $$)->left = $1;
  422.           ((TRnode *) $$)->right = $2; 
  423.         }
  424.     ;
  425.  
  426. direct_declarator
  427.     : identifier
  428.               {  
  429.         $$ = make_root (yytext, IDENT);
  430.         add_type_maybe (yytext); 
  431.           }
  432.     | '(' declarator ')'
  433.     | direct_declarator '[' ']'
  434.     | direct_declarator '[' constant_expr ']'
  435.     | direct_declarator '(' parameter_type_list ')'
  436.             {
  437.           $$ = $1;
  438.           if ($$ != 0)
  439.         ((TRnode *) $$)->right = $3;
  440.         }
  441.     | direct_declarator '(' ')'
  442.             {
  443.           $$ = $1;
  444.         }
  445.     | direct_declarator '(' identifier_list ')'
  446.             {
  447.           $$ = $1;
  448.           if ($$ != 0)
  449.         ((TRnode *) $$)->right = $3;
  450.         }
  451.     ;
  452.  
  453. pointer
  454.     : '*'
  455.             {
  456.           $$ = make_root ("*", PTR);
  457.         }
  458. /*  FIX */
  459.     | '*' specifier_qualifier_list
  460.     | '*' pointer
  461.             {
  462.           $$ = make_root ("*", PTR);
  463.           ((TRnode *) $$)->left = $2;
  464.         }
  465. /*  FIX  */
  466.     | '*' specifier_qualifier_list pointer
  467.     ;
  468.  
  469. parameter_type_list
  470.     : parameter_list
  471.             {
  472.           $$ = $1;
  473.         }
  474.     | parameter_list ',' ELIPSIS
  475.     ;
  476.  
  477. parameter_list
  478.     : parameter_declaration
  479.             {
  480.           $$ = $1;
  481.         }
  482.     | parameter_list ',' parameter_declaration
  483.             {
  484.           $$ = make_root ("nop", NOP);
  485.           ((TRnode *) $$)->left = $1;
  486.           ((TRnode *) $$)->right = $3;
  487.         }
  488.     ;
  489.  
  490. parameter_declaration
  491.     : declaration_specifiers declarator
  492.             {
  493.           $$ = make_root ("nop", NOP);
  494.           ((TRnode *) $$)->left = $1;
  495.           ((TRnode *) $$)->right = $2;
  496.         }
  497.     | declaration_specifiers
  498.             {
  499.           $$ = $1;
  500.         }
  501.     | declaration_specifiers abstract_declarator
  502.             {
  503.           $$ = make_root ("nop", NOP);
  504.           ((TRnode *) $$)->left = $1;
  505.           ((TRnode *) $$)->right = $2;
  506.         }
  507.           
  508.     ;
  509.  
  510. identifier_list
  511.         : identifier
  512.             {
  513.           $$ = $1;
  514.         }
  515.  
  516.     | identifier_list ',' identifier
  517.             {
  518.           $$ = make_root ("nop", NOP);
  519.           ((TRnode *) $$)->left = $1;
  520.           ((TRnode *) $$)->right = $3;
  521.         }
  522.     ;
  523.  
  524. type_name
  525.     : specifier_qualifier_list
  526.     | specifier_qualifier_list abstract_declarator
  527.     ;
  528.  
  529. abstract_declarator
  530.     : pointer
  531.             {
  532.           $$ = $1;
  533.         }
  534.     | direct_abstract_declarator
  535.             {
  536.           $$ = $1;
  537.         }
  538.     | pointer direct_abstract_declarator
  539.             {
  540.           $$ = make_root ("nop", NOP);
  541.           ((TRnode *) $$)->left = $1;
  542.           ((TRnode *) $$)->right = $2;
  543.         }
  544.     ;
  545.  
  546. /* STOPED HERE */
  547. direct_abstract_declarator
  548.     : '(' abstract_declarator ')'
  549.     | '[' ']'
  550.     | '[' constant_expr ']'
  551.     | direct_abstract_declarator '[' ']'
  552.     | direct_abstract_declarator '[' constant_expr ']'
  553.     | '(' ')'
  554.     | '(' parameter_type_list ')'
  555.     | direct_abstract_declarator '(' ')'
  556.     | direct_abstract_declarator '(' parameter_type_list ')'
  557.     ;
  558.  
  559. initializer
  560.     : assignment_expr
  561.     | '{' initializer_list '}'
  562.     | '{' initializer_list ',' '}'
  563.     ;
  564.  
  565. initializer_list
  566.     : initializer
  567.     | initializer_list ',' initializer
  568.     ;
  569.  
  570. statement
  571.     : labeled_statement
  572.     | compound_statement
  573.     | expression_statement
  574.     | selection_statement
  575.     | iteration_statement
  576.     | jump_statement
  577. /*        | ';' */
  578.     ;
  579.  
  580. labeled_statement
  581.     : identifier ':' statement
  582.     | CASE constant_expr ':' statement
  583.     | DEFAULT ':' statement
  584.     ;
  585.  
  586. compound_statement
  587.     : '{' '}'
  588.     | '{' statement_list '}'
  589.     | '{' declaration_list '}'
  590.     | '{' declaration_list statement_list '}'
  591.     ;
  592.  
  593. declaration_list
  594.     : declaration
  595.             { 
  596.           $$ = $1; 
  597.         }
  598.     | declaration_list declaration
  599.             { 
  600.  
  601.           $$ = make_root ("nop", NOP);
  602.           ((TRnode *) $$)->left = $1;
  603.           ((TRnode *) $$)->right = $2;
  604.         }
  605.     ;
  606.  
  607. statement_list
  608.     : statement
  609.     | statement_list statement
  610.     ;
  611.  
  612. expression_statement
  613.     : ';'
  614.     | expr ';'
  615.     ;
  616.  
  617. selection_statement
  618.     : IF '(' expr ')' statement
  619.     | IF '(' expr ')' statement ELSE statement
  620.     | SWITCH '(' expr ')' statement
  621.     ;
  622.  
  623. iteration_statement
  624.     : WHILE '(' expr ')' statement
  625.     | DO statement WHILE '(' expr ')' ';'
  626.     | FOR '(' ';' ';' ')' statement
  627.     | FOR '(' ';' ';' expr ')' statement
  628.     | FOR '(' ';' expr ';' ')' statement
  629.     | FOR '(' ';' expr ';' expr ')' statement
  630.     | FOR '(' expr ';' ';' ')' statement
  631.     | FOR '(' expr ';' ';' expr ')' statement
  632.     | FOR '(' expr ';' expr ';' ')' statement
  633.     | FOR '(' expr ';' expr ';' expr ')' statement
  634.     ;
  635.  
  636. jump_statement
  637.     : GOTO identifier ';'
  638.     | CONTINUE ';'
  639.     | BREAK ';'
  640.     | RETURN ';'
  641.     | RETURN expr ';'
  642.     ;
  643.  
  644. translation_unit
  645.     : external_declaration
  646. { is_a_type = in_struct = 0; }
  647.     | translation_unit external_declaration
  648. { is_a_type = in_struct = 0; }
  649.     ;
  650.  
  651. external_declaration
  652.     : function_definition
  653.             {
  654.           comment_counter = 0;
  655.         }
  656.     | declaration 
  657.             { 
  658.           comment_counter = 0;
  659.         }
  660.     ;
  661.  
  662. function_definition
  663.     : declarator 
  664.             { 
  665.           LIadd (0, $1, 0);;
  666.         }
  667.           compound_statement
  668.     | declarator declaration_list 
  669.             { 
  670.           LIadd (0, $1, $2);
  671.         }
  672.           compound_statement
  673.     | declaration_specifiers declarator 
  674.             { 
  675.           LIadd ($1, $2, 0);
  676.         }
  677.           compound_statement
  678.     | declaration_specifiers declarator declaration_list 
  679.             {
  680.           LIadd ($1, $2, $3);
  681.         }
  682.           compound_statement
  683.     ;
  684.  
  685. identifier
  686.     : IDENTIFIER
  687.             {
  688.           $$ = make_root (yytext, IDENT);
  689.         }
  690.     ;
  691. %%
  692. #include <stdio.h> 
  693. #include "tr.h"
  694.  
  695. int xxxx;
  696. int is_a_type = 0;
  697. int reset_is_a_type = 0;
  698. int number_user_defined_types;
  699. int type_list_size;
  700. char **user_defined_types;
  701. int in_struct = 0;
  702. extern char yytext[];
  703. extern int comment_counter;
  704. int print_level;
  705. int stop_level;
  706.  
  707. dump_types ()
  708. {
  709.   int i;
  710.  
  711. printf ("TYPES\n");
  712.  
  713.   for (i = 0; i < number_user_defined_types; i++)
  714.     printf ("%s\n", user_defined_types[i]);
  715.   printf ("\n\n");
  716. }
  717.  
  718. char *
  719. make_string (pc)
  720.      char *pc;
  721. {
  722.   char *new_pc;
  723.  
  724.   new_pc = (char *) malloc (strlen (pc) + 1);
  725.   if (0 == new_pc)
  726.     {
  727.       fprintf (stderr, "Memory error in make_string\n");
  728.       exit (2);
  729.     }
  730.   strcpy (new_pc, pc);
  731.   return new_pc;
  732. }
  733.  
  734.  
  735. set_type ()
  736. {
  737.   is_a_type = 1;
  738.   reset_is_a_type = 0;
  739. }
  740.  
  741. unset_type ()
  742. {
  743.   is_a_type = 0;
  744. }
  745.  
  746. add_type (type)
  747.   char *type;
  748. {
  749.   is_a_type = 1;
  750.   add_type_maybe (type);
  751. }
  752.  
  753. add_type_maybe (type)
  754.   char *type;
  755. {
  756.   static int init = 0;
  757.   char *pc;
  758.  
  759.   if (!is_a_type || in_struct)
  760.     return;
  761.  
  762.   if (!init)
  763.     {
  764.       init = 1;
  765.       type_list_size = 1024;
  766.       number_user_defined_types = 0;
  767.       user_defined_types = (char **) malloc (sizeof (char *) * type_list_size);
  768.       if (0 == user_defined_types)
  769.     {
  770.        fprintf (stderr, "Memory error\n"); 
  771.       exit (2);
  772.     }
  773.     }
  774.   if (type_list_size == number_user_defined_types)
  775.     {
  776.       type_list_size *= 2;
  777.       user_defined_types = (char **) realloc (user_defined_types, type_list_size);
  778.       if (0 == user_defined_types)
  779.     {
  780.       fprintf (stderr, "Memory error\n");
  781.       exit (2);
  782.     }
  783.     }
  784. /* printf ("\nADD TYPE <%s>\n", type);*/
  785.   user_defined_types[number_user_defined_types++] = make_string (type);
  786.   reset_is_a_type = is_a_type = 0;
  787.  
  788. }
  789.  
  790. int
  791. output_tree (node, mode)
  792.      TRnode *node;
  793.      int mode;
  794. {
  795.   if (0 == node )
  796.     return;
  797.  
  798.   /*  Inorder: Left-Root-Right. */
  799.   if (0 != node->left)
  800.     output_tree (node->left, mode);
  801.  
  802. /*  if (NOP != node->type)  */
  803.     {
  804.   char *lc;
  805.   switch (node->type) {
  806.   case NOP:  lc = "NOP"; break;
  807.   case LABEL:lc = "LABEL"; break;
  808.   case IDENT:lc = "IDENT"; break;
  809.   case PTR:  lc = "PTR"; break;
  810.   case STORAGE_CLASS: lc = "STORAGE_CLASS"; break;
  811.   case TYPE: lc = "TYPE"; break;
  812.   default: lc = "UNKNOWN"; break;
  813.   }
  814.       printf (" %s (%s)", node->pc, lc);
  815.      /* tladd (node);*/
  816.     }
  817.  
  818.   if (0 != node->right)
  819.     output_tree (node->right, mode);
  820. }
  821.  
  822. int
  823. output_param_tree (node)
  824.      TRnode *node;
  825. {
  826.   if (0 != node->left)
  827.     output_param_tree (node->left);
  828.  
  829.   if (NOP != node->type)
  830.     {
  831.       printf (" %s", node->pc);
  832.       if (node->type == IDENT)
  833.     printf (";\n\t");
  834.       else
  835.     printf ("  ");
  836.     }
  837.  
  838.   if (0 != node->right)
  839.     output_param_tree (node->right);
  840. }
  841.  
  842.  
  843. TRnode *
  844. make_root (pc, type)
  845.      char *pc;
  846.      int type;
  847. {
  848.   TRnode *node;
  849.     
  850.   node = malloc (sizeof (TRnode));
  851.   if (0 == node)
  852.     {
  853.       fprintf (stderr, "Memory problems with syntax tree\n");
  854.       exit (2);
  855.     }
  856.   node->left = 0;
  857.   node->right = 0;
  858.   node->pc = make_string (pc);
  859.   node->type = type;
  860.   return node;
  861. }
  862.  
  863. make_types (node)
  864.      TRnode *node;
  865. {
  866.  
  867.   if (0 == node)
  868.     return;
  869.  
  870.   if (0 != node->left)
  871.     make_types (node->left);
  872.   
  873.   
  874.   if (IDENT == node->type && TYPE_NAME != check_type (node->pc))
  875.     { 
  876.       add_type (node->pc);
  877.     }
  878.  
  879.   if (0 != node->right)
  880.     make_types (node->right);
  881.  
  882. }
  883.  
  884.  
  885.