home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OS2-YACC.ZIP / PREP3.C < prev    next >
C/C++ Source or Header  |  1980-01-04  |  15KB  |  559 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:      PREP3.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.  *      low level data/stack management routines for
  37.  *      YACC preprocessor.
  38.  *
  39.  */
  40.  
  41. /*
  42.  *      tags:
  43.  */
  44. static char name_array [TAGSIZE];
  45. static char *tag_base = &name_array [0];
  46.  
  47.  
  48. static int eq_tags (x, y)
  49. register char *x, *y;
  50. {
  51.         while (*x == *y && *x != (char)0 && *y != (char)0)
  52.               { x++;
  53.                 y++;
  54.               }
  55.  
  56.         return (*x == *y);
  57. }
  58.  
  59. char *new_tag (t)
  60. register char *t;
  61. {
  62.         register char *l_base = tag_base;
  63.  
  64.         while ( (*tag_base = *t) != (char)0)
  65.         { tag_base ++;
  66.           t++;
  67.         }
  68.  
  69.         tag_base ++;    /* set for next definition */
  70.         return l_base;
  71. }
  72.  
  73. /*
  74.  *      dealing with types and unions
  75.  */
  76.  
  77. struct {
  78.         int el_cnt;
  79.         struct type_elem descr[MAXDEF];
  80.  
  81. } type_descr;
  82.  
  83. /*
  84.  *      somewhere a definition of a union of all
  85.  *      attribute element types is generated:
  86.  */
  87.  
  88. print_union ()
  89. {
  90.         register int i;
  91.         register struct type_elem *x;
  92.  
  93.         if (type_descr.el_cnt == 0) return;    /* nothing */
  94.  
  95.         fprintf (foutput, "\n#ifndef ATT_SIZE\n");
  96.         fprintf (foutput, "#define ATT_SIZE     150\n");
  97.         fprintf (foutput, "#endif\n");
  98.         fprintf (foutput, "\nunion _attr_elem {\n");
  99.  
  100.         for (i = 0; i < type_descr.el_cnt; i++)
  101.         {   x = &type_descr.descr[i];
  102.             fprintf (foutput, "  %s  _t%d;\n",
  103.                                 x -> type_name, x -> un_number);
  104.         }
  105.  
  106.         fprintf (foutput, "} _attr_stack [ATT_SIZE];\n");
  107.         fprintf (foutput, "union _attr_elem *_ap =");
  108.         fprintf (foutput, "      &_attr_stack [ATT_SIZE - 1];\n");
  109. }
  110.  
  111. struct type_elem *add_type (t)
  112. register char *t;
  113. {
  114.         register int i;
  115.         register struct type_elem *x, *y;
  116.  
  117.         for (i = 0; i < type_descr.el_cnt; i++)
  118.             { x = &type_descr.descr[i];
  119.               if (eq_tags (t, x -> type_name))
  120.                  return x;
  121.             }
  122.  
  123.         if (type_descr.el_cnt >= MAXDEF)
  124.            error (FATAL,
  125.                    "too many attribute defs: line %d\n", lineno);
  126.  
  127.         x = &type_descr.descr[type_descr.el_cnt];
  128.         x -> type_name = new_tag (t);
  129.         x -> un_number = type_descr.el_cnt ++;
  130.  
  131.         return x;
  132. }
  133.  
  134. /*
  135.  *      attribute definitions
  136.  */
  137. struct att_def attrib_defs [NONTERM];
  138.  
  139. static int ndefs = 0;
  140. /*
  141.  *      functions to be defined:
  142.  *
  143.  *              set_input       enter input attrib in def
  144.  *              set_output      enter output attrib in def
  145.  *              in_pars         number of inpars
  146.  *              out_pars        number of outpars
  147.  *              new_def         enter new non terminal
  148.  *              lookup          look for nonterm.
  149.  *              checkdefs       check all attributed symbols to be on lhs
  150.  *              setdefined      set non terminal defined as lhs
  151.  */
  152.  
  153. setdefined (t)
  154. struct att_def *t;
  155. {
  156.         if (t != (char)0)
  157.            t-> hasdefinition = (char)1;
  158. }
  159.  
  160. checkdefs ()
  161. {
  162.         register int i;
  163.  
  164.         for (i = 0; i < ndefs; i ++)
  165.             if (attrib_defs[i].hasdefinition == (char) 0)
  166.                error (WARNING, "%s not as lhs", attrib_defs[i].nonterm);
  167. }
  168.  
  169. struct att_def *lookup (t)
  170. register char *t;
  171. {
  172.         register int i;
  173.  
  174.         for (i = 0; i < ndefs; i++)
  175.             if (eq_tags (t, attrib_defs [i].nonterm))
  176.                return &attrib_defs [i];
  177.  
  178.         return (struct att_def *)0;
  179. }
  180.  
  181. struct att_def *new_def (t)
  182. register char *t;
  183. {
  184.         register struct att_def *x;
  185.  
  186.         if (lookup (t) != (struct att_def *)0)
  187.            error (FATAL, "double definition line %d\n", lineno);
  188.  
  189.         if (ndefs >= NONTERM)
  190.            error (FATAL, "too much non terminals line %d\n", lineno);
  191.  
  192.         x = &attrib_defs [ndefs ++];
  193.         x->i_par = 0;
  194.         x->o_par = 0;
  195.         x->nonterm = new_tag (t);
  196.         x->hasdefinition = (char)0;
  197.  
  198.         return x;
  199. }
  200.  
  201. set_input (def, typename)
  202.  
  203. register struct att_def *def;
  204. register char *typename;
  205. {
  206.         register struct att_def *y;
  207.  
  208.         if (def -> i_par >= MAXATTR)
  209.            error (FATAL, "too many input attribs line %d\n", lineno);
  210.  
  211.         def -> i_par++;
  212.         y = &def -> attributes [def -> i_par];
  213.  
  214.         y -> par_no = def -> i_par;
  215.         y -> direction = INPUT;
  216.         y -> par_desc = add_type (typename);
  217. }
  218.  
  219. set_output (def, type_name)
  220. register struct att_def *def;
  221. register char *type_name;
  222. {
  223.         register struct att_def *y;
  224.  
  225.         if (def -> i_par + def -> o_par >= MAXATTR)
  226.            error (FATAL, "too many input/output attr's line %d\n", lineno);
  227.  
  228.         def -> o_par++;
  229.  
  230.         y = &def -> attributes [def -> i_par + def -> o_par];
  231.         y -> par_no = def -> o_par;
  232.         y -> direction = OUTPUT;
  233.         y -> par_desc = add_type (type_name);
  234. }
  235.  
  236. int in_pars (def)
  237. register struct att_def *def;
  238. {
  239.         if (def == (struct att_def *)0) return 0;
  240.         return def -> i_par;
  241. }
  242.  
  243. int out_pars (def)
  244. register struct att_def *def;
  245. {
  246.         if (def == (struct att_def *)0) return 0;
  247.         return def -> o_par;
  248. }
  249.  
  250. /*
  251.  *      during the processing of a rule a stack is maintained
  252.  *      for the simulation of the run time behaviour
  253.  */
  254. struct {
  255.         int i_top;              /* input pars lhs       */
  256.         int o_top;              /* output pars lhs      */
  257.         int w_top;              /* workstack top        */
  258.  
  259.         struct stack_elem work_stack [WSTACKSIZE];
  260.         struct stack_elem out_stack  [OUTSTACKSIZE];
  261. } workstack;
  262. /*
  263.  *
  264.  *      functions available during processing a rule:
  265.  
  266.  *
  267.  *
  268.  *      init_stack ();
  269.  *
  270.  *      push (def, cnt, tag);   /* lhs input param
  271.  *      dest_par (def, cnt, tag)        /* lhs output param
  272.  *
  273.  *      veri_in (member, parno, tag);
  274.  *      veri_out(member, parnp, tag);
  275.  *
  276.  *      address_of (tag)        /* map into a string used for C 
  277.  *
  278.  *      pref_stackadjust ();    /* code for stack adjustment 
  279.  *      post_stackadjust ();    /* code for stack adjustment 
  280.  */
  281. init_stack ()
  282. {
  283.         workstack.i_top = 0;
  284.         workstack.o_top = 0;
  285.         workstack.w_top = 0;
  286. }
  287.  
  288. re_init_stack ()
  289. {
  290.         workstack.w_top = workstack.i_top;
  291. }
  292.  
  293.  
  294. cp_tag (x, y, cnt)
  295. register char *x, *y;
  296. register int cnt;
  297. {
  298.         while (--cnt >= 0)
  299.               *y++ = *x++;
  300. }
  301.  
  302.  
  303. struct type_elem *get_i_type (def, parno)
  304. register struct att_def *def;
  305. register int parno;
  306. {
  307.         if (parno > def -> i_par)
  308.            error (FATAL, "too high input param for %s",
  309.                                         def -> nonterm);
  310.  
  311.         return (def -> attributes [parno].par_desc);
  312. }
  313.  
  314. struct type_elem *get_o_type (def, parno)
  315. register struct att_def *def;
  316. register int parno;
  317. {
  318.         if (parno > def -> o_par)
  319.            error (FATAL, "too high output param number for %s",
  320.                                                 def -> nonterm);
  321.  
  322.         return (def -> attributes [def -> i_par + parno].par_desc);
  323. }
  324.  
  325.  
  326. push (def, parno, tag)
  327. register struct att_def *def;
  328.  
  329. register char *tag;
  330. int parno;
  331. {
  332.         register struct stack_elem *x;
  333.  
  334.         if (workstack.i_top ++ >= WSTACKSIZE)
  335.            error (FATAL, "too much attributes on workstack line %d\n", lineno);
  336.         x = &workstack.work_stack [workstack.i_top];
  337.         cp_tag (tag, &x -> par_name [0], PAR_SIZ);
  338.         x -> par_def = get_i_type (def, parno);
  339.         workstack.w_top = workstack.i_top;
  340. #ifdef DEBUG
  341.         printf ("push: %s %d %s\n",
  342.                                 &x -> par_name [0], workstack.i_top,
  343.                                                 x -> par_def -> type_name);
  344. #endif
  345. }
  346.  
  347. dest_par (def, parno, tag)
  348. register struct att_def *def;
  349. register char *tag;
  350. int parno;
  351. {
  352.         register struct stack_elem *x;
  353.  
  354.         if (workstack.o_top ++ >= OUTSTACKSIZE)
  355.            error (FATAL, "too much lhs out attributes line %d\n", lineno);
  356.  
  357.         x = &workstack.out_stack [workstack.o_top];
  358.         cp_tag (tag, &x -> par_name [0], PAR_SIZ);
  359.         x -> par_def = get_o_type (def, parno);
  360. #ifdef DEBUG
  361.         printf ("dest_par : %s %d %s\n",
  362.                         x -> par_name, workstack.o_top,
  363.                         x -> par_def -> type_name);
  364. #endif
  365. }
  366.  
  367. veri_in (def, parno, tag)
  368. register struct att_def *def;
  369. register char *tag;
  370. int parno;
  371. {
  372.         register struct stack_elem *x;
  373.  
  374.         x = &workstack.work_stack[ workstack.w_top
  375.                                         - in_pars (def) + parno];
  376.         if (!eq_tags (x -> par_name, tag))
  377.            error (FATAL, "non matching input name %s", tag);
  378. #ifdef DEBUG
  379.         printf ("veri_in: %s at offset %d\n", tag, 
  380.                                 workstack.w_top - in_pars (def) + parno);
  381. #endif
  382. }
  383.  
  384. veri_out (def, parno, tag)
  385. register struct att_def *def;
  386. register char *tag;
  387. int parno;
  388. {
  389.         register struct stack_elem *x;
  390.         if (workstack.w_top++ >= WSTACKSIZE)
  391.            error (FATAL, "too much attribute values line %d\n", lineno);
  392.  
  393.         x = &workstack.work_stack [workstack.w_top];
  394.         cp_tag (tag, &x -> par_name [0], PAR_SIZ);
  395.         x -> par_def = get_o_type (def, parno);
  396. #ifdef DEBUG
  397.         printf ("veri_out: %s %d %s\n",
  398.                      x -> par_name, workstack.w_top,
  399.                                         x -> par_def -> type_name);
  400. #endif
  401. }
  402.  
  403. /*
  404.  * given the tag of an attribute, translate it into a string
  405.  * containing the 'C' code to adress the element on the
  406.  * attribute stack (or the local...)
  407.  */
  408. struct stack_elem *search_stck (t)
  409. register char *t;
  410. {
  411.         register int i;
  412.         register struct stack_elem *x;
  413.  
  414.         for (i=1; i <= workstack.o_top; i++)
  415.             { x = &workstack.out_stack [i];
  416. #ifdef DEBUG
  417.                 printf ("search: %s\n", &x -> par_name [0]);
  418. #endif
  419.               if (eq_tags (t, x -> par_name))
  420.                  return x;
  421.             }
  422. /*
  423.  *      now on the input stack
  424.  */
  425.         for (i = workstack.w_top; i > 0; i--)
  426.             { x = &workstack.work_stack [i];
  427. #ifdef DEBUG
  428.                 printf ("search: %s\n", x -> par_name);
  429. #endif
  430.               if (eq_tags (t, x -> par_name))
  431.                  return x;
  432.             }
  433.  
  434.         error (FATAL, "definition of attribute %s not found\n", t);
  435. }
  436.  
  437. char *address_of (tag)
  438. register char *tag;
  439. {
  440.         register struct stack_elem *t;
  441.         static char s [20];     /* most numbers will do */
  442.  
  443.         t = search_stck (tag);
  444.         if (t -> access.how_to_access == AS_LOCAL)
  445.            sprintf (s, LOC_STRING, t -> access.ac_lab);
  446.         else
  447.         sprintf (s, "_ap [%d]._t%d",
  448.                         t -> access.ac_offset, t -> par_def -> un_number);
  449.  
  450.         return s;
  451. }
  452.  
  453. /*
  454.  *      generate code for stack adjustment and to make
  455.  *      output paramers addressable
  456.  */
  457. pref_stackadjust ()
  458. {
  459.         register struct stack_elem *x;
  460.         register int i;
  461.         register int l_top = 0;
  462.  
  463.         fprintf (foutput, "{");
  464.         if (workstack.i_top == workstack.w_top)
  465.            { /* no intermediate results, lengthen
  466.               * the stack
  467.               */
  468.              if (workstack.o_top != 0)
  469.                 fprintf (foutput, "     _ap -= %d;\n",
  470.                                         workstack.o_top);
  471.              l_top = workstack.o_top;
  472.              for (i = workstack.o_top; i >= 1; i--)
  473.                  { x = &workstack.out_stack [i];
  474.                    x -> access.how_to_access = AS_STACK;
  475.                    x -> access.ac_offset = workstack.o_top - i;
  476.                  }
  477.            }
  478.         else
  479.         /* generate for each output parameter a local
  480.          */
  481.         for (i = 1; i <= workstack.o_top; i++)
  482.             { x = &workstack.out_stack [i];
  483.               x->access.how_to_access = AS_LOCAL;
  484.               x->access.ac_lab = i;
  485.  
  486.               fprintf (foutput, "       %s ", x -> par_def -> type_name);
  487.               fprintf (foutput, LOC_STRING, i);
  488.               fprintf (foutput, ";\n");
  489.             }
  490.  
  491.         for (i = workstack.w_top; i > 0; i--)
  492.             { x = &workstack.work_stack [i];
  493.               x -> access.how_to_access = AS_STACK;
  494.               x -> access.ac_offset = 
  495.                                 l_top + workstack.w_top - i;
  496.             }
  497. }
  498.  
  499. /*
  500.  *      after copying the C actions, we possibly have to adjust
  501.  *      the attribute value stack
  502.  */
  503. post_adjuststack ()
  504. {
  505.         register struct stack_elem *x;
  506.         register int i;
  507.  
  508.         if (workstack.i_top == workstack.w_top)
  509.            { /* adjustment already doen, no pushing/popping */
  510.               fprintf(foutput, "}\n");
  511.            }
  512.         else
  513.  
  514.         { /* generate code for adjusting ap */
  515.           fprintf (foutput,"    _ap += %d; \n",
  516.                                 workstack.w_top - workstack.i_top);
  517.           for (i = 1; i <= workstack.o_top; i++)
  518.               { x = &workstack.out_stack [i];
  519.                 fprintf (foutput, "--_ap; _ap[0]._t%d = ",
  520.                                         x -> par_def -> un_number);
  521.                 fprintf (foutput, LOC_STRING,
  522.                                         x -> access.ac_lab);
  523.                 fprintf (foutput, ";\n");
  524.               }
  525.            fprintf (foutput, "  }\n");
  526.         }
  527. }
  528.  
  529. /*
  530.  *      no yacc actions specified, verify the work/output stack,
  531.  *      adjust if necessary
  532.  */
  533. adjust_stack ()
  534. {
  535.         register int diff;
  536.         register int i;
  537.  
  538.         diff = workstack.w_top - workstack.i_top - workstack.o_top;
  539.  
  540.         if (diff != 0)
  541.            {
  542.                 fprintf (foutput, "= {\n");
  543.                 fprintf (foutput, "_ap += %d; }\n", diff);
  544.            }
  545.  
  546.         if (diff < 0)
  547.            { error (WARNING, "garbage on extended attribute stack");
  548.              return;
  549.            }
  550.  
  551.         for (i = 1; i <= workstack.o_top; i++)
  552.             {
  553.                 if (workstack.out_stack [workstack.o_top - i + 1].par_def !=
  554.                     workstack.work_stack [workstack.w_top -i + 1].par_def)
  555.                    error (WARNING, "unequal default transfers %s",
  556.                                         workstack.out_stack [i -1].par_name);
  557.             }
  558. }
  559.