home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OS2-YACC.ZIP / PREP1.C < prev    next >
C/C++ Source or Header  |  1980-01-04  |  11KB  |  366 lines

  1. /*
  2.   HEADER: CUG     nnn.nn;
  3.   TITLE:     PREP - Preprocessor for YACC
  4.   VERSION:     1.0 for IBM-PC
  5.   DATE:      JAN 28, 1985
  6.   DESCRIPTION:     Preprocessor for YACC Programs
  7.   KEYWORDS:     Preprocessor IBM YACC LEX UNIX
  8.   SYSTEM:     IBM-PC and Compatiables
  9.   FILENAME:      PREP1.C
  10.   WARNINGS:     This program is not for the casual user. It will
  11.          be useful primarily to expert developers.
  12.   CRC:         N/A
  13.   SEE-ALSO:     LEX and YACC
  14.   AUTHORS:     Scott Guthery 11100 leafwood lane Austin, TX 78750
  15.   COMPILERS:     DESMET-C
  16.   REFERENCES:     UNIX Systems Manuals
  17. */
  18.  
  19. #include        <stdio.h>
  20. #include        "prep.h"
  21.  
  22. /*
  23.  *
  24.  *      J van Katwijk
  25.  *      Delft University of Technology,
  26.  *      Department of Mathematics,
  27.  *      132 Julianalaan
  28.  *      Delft, The Netherlands
  29.  *
  30.  *      See for a functional description:
  31.  *
  32.  *      SIGPLAN NOTICES
  33.  *      October 1983, 18 (10) pp 12 .. 16
  34.  */
  35.  
  36. /*
  37.  *
  38.  *      Some notes:
  39.  *
  40.  *
  41.  
  42.         Two stacks are maintained, a working stack and
  43.         a destination stack.
  44.         The latter one is some coding of the situation to
  45.         be achieved after the reduction.
  46.         The working stack is basically used to compute the
  47.         stack layout at the moment of reduction.
  48.         During the way up to get there, the stack is
  49.         used to verify the ordering and typing of the
  50.         input attributes.
  51.         At the reductionpoint two cases must be distinguished:
  52.  
  53.         -       The workstack contains only input attributes,
  54.                 i.e. those attributes inherited from the
  55.                 lhs of the rule
  56.  
  57.                 In this case the runtime stack will be extended
  58.                 to contain the output attributes of the lhs symbol.
  59.                 The output attributes are made addressable on this
  60.                 stack.
  61.                 No end of reduction code is further been generated.
  62.  
  63.         -       The workstack contains also output attributes.
  64.                 In order to avoid temporarily sharing of the
  65.                 stack locations, the output parameters of the
  66.                 lhs symbol of the rule are made addressable as
  67.                 ordinary local variables. (These variables
  68.                 are declared with unusual names etc.). At the
  69.                 end of the reduction code the runtime stack
  70.                 is adjusted and the preprocessor generated
  71.                 temp's are stored on the stack.
  72.  */
  73.  
  74. /*
  75.  * rules:
  76.  *      definitie : attr_def symbol [ ( [[|inputdefs]^outputdefs]) ]
  77.  *
  78.  *      rule : lhs : alternative {|alternative} ;
  79.  
  80.  *
  81.  *
  82.  *      alternative : [ {member} ] [= action]
  83.  *
  84.  *      member : symbol [ ( [|inputlist][^outputlist]) ]
  85.  *
  86.  */
  87. proc_def ()     /* process a definition */
  88. {
  89.         register char *curr_def;
  90.  
  91.         if (tok != ATTR_DEF)
  92.            return;      /* cannot happen */
  93.  
  94.         tok = gettok ();
  95.         if (tok != IDENT)
  96.            error (FATAL, "syntax error in attribute definition");
  97.  
  98.         curr_def = new_def (tokname);
  99.  
  100.         tok = gettok ();
  101.         if (tok != LPAR)
  102.            return;
  103.  
  104.         tok = gettok ();
  105.         if (tok == INPUT)
  106.            proc_intypes (curr_def);
  107.         if (tok == OUTPUT)
  108.            proc_outtypes (curr_def);
  109.  
  110.         if (tok != RPAR)
  111.            error (FATAL, "syntax error in definition for %s",
  112.                                                 curr_def -> nonterm);
  113.         tok = gettok ();
  114.         return;
  115. }
  116.  
  117. proc_intypes (definition)
  118. register struct att_def *definition;
  119. {
  120.         register int i = 0;
  121.         if (tok != INPUT)
  122.            return;      /* cannot happen */
  123.  
  124.         tok = gettok ();
  125.         while (tok == IDENT)
  126.         { set_input (definition, tokname);
  127.           tok = gettok ();
  128.           if (tok == RPAR)
  129.              return;
  130.           if (tok != COMMA)
  131.              error (FATAL, "syntax error (missing comma) in def %s",
  132.                                                         definition -> nonterm);
  133.  
  134.           tok = gettok ();
  135.         }
  136.  
  137.         if (tok != OUTPUT)
  138.            error (FATAL, "syntax error (missing ^) def %s",
  139.                                                 definition -> nonterm);
  140.  
  141.         return;
  142.  
  143. }
  144.  
  145. proc_outtypes (definition)
  146. register struct att_def *definition;
  147. {
  148.         if (tok != OUTPUT)
  149.            return;      /* cannot happen */
  150.  
  151.         tok = gettok ();
  152.         while (tok == IDENT)
  153.         {
  154.            set_output (definition, tokname);
  155.            tok = gettok ();
  156.            if (tok == RPAR)
  157.               return;
  158.            if (tok != COMMA)
  159.               error (FATAL, "syntax error (comma expected) def %s",
  160.                                                 definition -> nonterm);
  161.  
  162.            tok = gettok ();
  163.         }
  164.  
  165.         error (FATAL, "syntax error, identifier expected in def for %s",
  166.                                                 definition -> nonterm);
  167.         return;
  168. }
  169.  
  170. /*
  171.  *      Now for the rule recorgnition, recall that
  172.  *      the symbols of the rules themselves still
  173.  *      have to be processed by YACC.
  174.  */
  175.  
  176. struct att_def *lhs_side ()
  177. {
  178.         register int par_i_cnt =0;
  179.         register int par_o_cnt =0;
  180.  
  181.         register struct att_def *lhs_member;
  182.  
  183.         if (tok != IDENT)
  184.            error (FATAL, "syntax error in lhs");
  185.  
  186.         fprintf (foutput,"%s    :", tokname);
  187.         lhs_member = lookup (tokname);
  188.  
  189.         tok = gettok ();
  190.         if (tok == LPAR)
  191.         {
  192.            if (lhs_member == 0)
  193.               error (FATAL, "illegal left hand side %s", tokname);
  194.  
  195.            setdefined (lhs_member);
  196.            tok = gettok ();
  197.            if (tok != INPUT)
  198.               goto try_output;
  199.  
  200.            tok = gettok ();
  201.            while (tok == IDENT)
  202.            {  par_i_cnt ++;
  203.               push (lhs_member, par_i_cnt, tokname);
  204.               tok = gettok ();
  205.  
  206.               if (tok == RPAR)
  207.                  goto lhs_check;
  208.  
  209.               if (tok != COMMA)
  210.                  error (FATAL, "syntax error (comma expected) lhs %s",
  211.                                                         lhs_member -> nonterm);
  212.               tok = gettok ();
  213.            }
  214.  
  215. try_output:
  216.            if (tok != OUTPUT)
  217.               error (FATAL, "^ expected in lhs %s", lhs_member -> nonterm);
  218.  
  219.            tok = gettok ();
  220.            while (tok == IDENT)
  221.            { par_o_cnt++;
  222.              dest_par (lhs_member, par_o_cnt, tokname);
  223.              tok = gettok ();
  224.              if (tok == RPAR)
  225.                 goto lhs_check;
  226.  
  227.              if (tok != COMMA)
  228.                 error (FATAL, "syntax error (comma expected) lhs %s",
  229.                                                         lhs_member -> nonterm);
  230.              tok = gettok ();
  231.            }
  232.  
  233. lhs_check:
  234.         if (tok != RPAR)
  235.            error (FATAL, ") expected, lhs %s", lhs_member -> nonterm);
  236.         tok = gettok ();
  237.         }
  238.  
  239.         if (par_i_cnt != in_pars (lhs_member) ||
  240.             par_o_cnt != out_pars(lhs_member) )
  241.            error (FATAL, "incorrect number parameters for %s",
  242.                                                 lhs_member -> nonterm);
  243.  
  244.         return lhs_member;
  245. }
  246.  
  247. rule ()
  248. {
  249.         register struct att_def *lhs_def;
  250.  
  251.         init_stack ();
  252.         lhs_def = lhs_side ();
  253.         if (tok != COLON)
  254.            error (FATAL, " `:' expected following %s",
  255.                                         lhs_def -> nonterm);
  256.  
  257.         tok = gettok ();
  258.  
  259.         proc_alternative (lhs_def);
  260.         while (tok == BAR)
  261.             { fprintf (foutput, "\n             |");
  262.               re_init_stack ();
  263.               tok = gettok ();
  264.               proc_alternative (lhs_def);
  265.             }
  266.  
  267.         if (tok != SEMI)
  268.  
  269.            error (FATAL, "`;' expected  %s", lhs_def -> nonterm);
  270.  
  271.         fprintf (foutput, ";\n");
  272. }
  273.  
  274. proc_alternative (lefthand)
  275. register struct stack_elem *lefthand;
  276. {
  277.         while (tok == IDENT)
  278.            { fprintf (foutput, "%s ", tokname);
  279.              proc_member (lefthand);
  280.            }
  281.  
  282.         if (tok == EQ_SYMB)
  283.            { fprintf (foutput, "=\n");
  284.              tok = gettok ();
  285.              cpyact ();
  286.              tok = gettok ();
  287.            }
  288.         else
  289.            adjust_stack ();
  290. }
  291.  
  292. proc_member (ctxt)
  293. register struct stack_elem *ctxt;
  294. {
  295.         register int in_index, out_index;
  296.         register struct att_def *curr_member;
  297.  
  298.         if (tok != IDENT)
  299.            return;      /* cannot happen */
  300.  
  301.         curr_member = lookup (tokname);
  302.  
  303.         tok = gettok ();
  304.         if (tok != LPAR)
  305.            { if (curr_member == (struct att_def *)0)
  306.                 return;
  307.  
  308.              if (in_pars (curr_member) + out_pars (curr_member) != 0)
  309.                 error (FATAL, "incorrect number of parameters %s",
  310.                                                 ctxt -> nonterm);
  311.              return;
  312.            }
  313.  
  314.         if (curr_member == (struct att_def *)0) /* and tok == ( */
  315.            error (FATAL, "parameters with non specified symbol rule %s",
  316.                                                 ctxt -> nonterm);
  317.  
  318.         tok = gettok ();
  319.         in_index = 0;
  320.         out_index = 0;
  321.  
  322.         if (tok == INPUT)
  323.            { tok = gettok ();
  324.              while (tok == IDENT)
  325.              {   in_index++;
  326.                  veri_in (curr_member, in_index, tokname);
  327.                  tok = gettok ();
  328.                  if (tok == RPAR)
  329.                     goto par_check;
  330.  
  331.                  if (tok != COMMA)
  332.                     error (FATAL, "comma expected (member %s)",
  333.                                                 curr_member -> nonterm);
  334.  
  335.                  tok = gettok ();
  336.              }
  337.            }
  338.         if (tok != OUTPUT)
  339.            error (FATAL, "^ expected  (member %s)",
  340.                                                 curr_member -> nonterm);
  341.  
  342.         tok = gettok ();
  343.         while (tok == IDENT)
  344.         {   out_index++;
  345.             veri_out (curr_member, out_index, tokname);
  346.             tok = gettok ();
  347.             if (tok == RPAR)
  348.                break;
  349.             if (tok != COMMA)
  350.                error (FATAL, "`,' expected (member %s)",
  351.                                                 curr_member -> nonterm);
  352.             tok = gettok ();
  353.         }
  354.  
  355. par_check:
  356.         if ( (in_pars (curr_member) != in_index) ||
  357.              (out_pars (curr_member) != out_index) )
  358.            error (FATAL, "incorrect number of parameters (member %s)",
  359.                                                 curr_member -> nonterm);
  360.  
  361.         if (tok != RPAR)
  362.            error (FATAL, "`)' expected (member %s)",
  363.                                                 curr_member -> nonterm);
  364.         tok = gettok ();
  365. }
  366.