home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OS2-YACC.ZIP / PREP2.C < prev    next >
Text File  |  1986-02-06  |  9KB  |  469 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:     PREP2.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.  *    scanning/copying routines for YACC preprocessor
  37.  *
  38.  *    j van katwijk
  39.  *
  40.  */
  41. static char c;
  42. static int is_digit (x)
  43. register char x;
  44. {
  45.     return '0' <= x && x <= '9';
  46. }
  47.  
  48. static int is_letter(x)
  49. register char x;
  50. {
  51.     return ('A' <= x && x <= 'Z') || ('a' <= x && x <= 'z');
  52. }
  53.  
  54. int is_namelem (x)
  55. register int x;
  56. {
  57.     return (islower(x) ||
  58.         isupper(x) ||
  59.         c == '_'   ||
  60.         c == '.'   ||
  61.         c == '$' );
  62. }
  63.  
  64. int gettok ()
  65. {
  66.     register int i, base;
  67.     static int peekline;
  68.     register int match, reserve;
  69.  
  70. /* :
  71.  */
  72. begin:
  73.     reserve = 0;
  74.     lineno += peekline;
  75.     peekline = 0;
  76.  
  77.     c = unix_getc (finput);
  78.     while (0 <= c && c <= ' ')
  79.     { if (c == '\n')
  80.  
  81.          lineno++;
  82.       c = unix_getc (finput);
  83.     }
  84.  
  85.     if (c == '/')   /* go for comment */
  86.        { lineno += skipcom ();
  87.          goto begin;
  88.        }
  89.  
  90.     switch (c)
  91.     {
  92.     case -1: /* EOF */
  93.         return ENDFILE;
  94.     case ':':
  95.         return COLON;
  96.  
  97.     case ';':
  98.         return SEMI;
  99.  
  100.     case '|':
  101.         return BAR;
  102.  
  103.  
  104.     case '{':
  105.         uungetc (c, finput);
  106.         return (EQ_SYMB);
  107.         /* action .... */
  108.  
  109.     case '<':       /* only for the sake of YACC */
  110.         i = 0;
  111.         while ( (c = unix_getc (finput)) != '>' && c >= 0 && c != '\n')
  112.             { tokname [i] = c;
  113.               if (++i >= NAMESIZE) --i;
  114.             }
  115.  
  116.         if (c!= '>')
  117.            error (FATAL, "unterminated <...> clause");
  118.  
  119.         tokname [i] = '\0';
  120.         return (IDENT);
  121.  
  122.     case ',':
  123.         return COMMA;
  124.  
  125.     case '^':
  126.         return OUTPUT;
  127.  
  128.     case '=':
  129.         return EQ_SYMB;
  130.  
  131.     case '(':
  132.         return LPAR;
  133.  
  134.     case ')':
  135.         return RPAR;
  136.  
  137.  
  138.     case '"':
  139.     case '\'':
  140.         match = c;
  141.         tokname [0] = ' ';
  142.  
  143.         i = 1;
  144.  
  145.         for (;;)
  146.         { c = unix_getc (finput);
  147.           if (c == '\n' || c == EOF)
  148.              error (FATAL, "illegal or missing %c", match);
  149.           if (c == '\\')
  150.              { c = unix_getc (finput);
  151.                tokname [i] = '\\';
  152.                if (++i >= NAMESIZE) --i;
  153.              }
  154.           else
  155.              if (c == match)
  156.             break;
  157.  
  158.           tokname [i] = c;
  159.           if (++i >= NAMESIZE) --i;
  160.         }
  161.  
  162.         break;
  163.  
  164.     case '%':
  165.     case '\\':
  166.         switch (c = unix_getc (finput))
  167.         {
  168.             case '0':       return TERM;
  169.             case '<':       return LEFT;
  170.             case '2':       return (BINARY);
  171.             case '>':       return (RIGHT);
  172.             case '%':
  173.             case '\\':      return (MARK);
  174.             case '=':       return (PREC);
  175.             case '{':       return (LCURL);
  176.  
  177.             default:    reserve = 1;
  178.         }
  179.  
  180. /* bah, johnson falls through, we follow here:
  181.  */
  182.     default:
  183.         if (isdigit(c))
  184.            { i = 0;
  185.              while (isdigit(c))
  186.              { tokname [i] = c;
  187.                if (++i >= NAMESIZE) --i;
  188.                c = unix_getc (finput);
  189.              }
  190.              uungetc (c, finput);
  191.              return (NUMBER);
  192.            }
  193.         else
  194.         if (is_namelem (c))
  195.            { i = 0;
  196.              while (is_namelem (c) || is_digit (c))
  197.              { tokname [i] = c;
  198.                if (reserve && isupper(c))
  199.                   tokname [i] += 'a' - 'A';
  200.                if (++i >= NAMESIZE) --i;
  201.                c = unix_getc (finput);
  202.              }
  203.            }
  204.         else
  205.  
  206.            return c;
  207.  
  208.         uungetc (c, finput);
  209.         }
  210.  
  211. /* look for reserved words */
  212.     tokname [i] = '\0';
  213.  
  214.     if (reserve)
  215.        {
  216.         if (!strcmp (tokname, "term")) return TERM;
  217.         if (!strcmp (tokname, "token")) return TERM;
  218.         if (!strcmp (tokname, "left")) return LEFT;
  219.         if (!strcmp (tokname, "nonassoc")) return BINARY;
  220.         if (!strcmp (tokname, "binary")) return BINARY;
  221.         if (!strcmp (tokname, "right")) return RIGHT;
  222.         if (!strcmp (tokname, "prec")) return RIGHT;
  223.         if (!strcmp (tokname, "start")) return START;
  224.         if (!strcmp (tokname, "type")) return TYPE;
  225.         if (!strcmp (tokname, "union")) return UNION;
  226.         if (!strcmp (tokname, "attributes")) return ATTR_DEF;
  227.         if (!strcmp (tokname, "attribute")) return ATTR_DEF;
  228.         error (FATAL, "non recognized keyword %s", tokname);
  229.        }
  230.  
  231.     return (IDENT);
  232. }
  233.  
  234. /*
  235.  *    copy the union
  236.  *
  237.  */
  238.  
  239. cpyunion ()
  240. {
  241.     int level, c;
  242.     fprintf (foutput, "\n# line %d \"%s\"\n", lineno, infile);
  243.     fprintf (foutput, "%%union");
  244.  
  245.     level = 0;
  246.     for (;;)
  247.     {  if ((c = unix_getc (finput)) <0 )
  248.           error (FATAL, "EOF when parsing %%union");
  249.  
  250.        fprintf (foutput, "%c", c);
  251.        switch (c)
  252.        {
  253.         case '\n':
  254.             ++lineno; break;
  255.  
  256.         case '{':
  257.             ++level;
  258.             break;
  259.  
  260.         case '}':
  261.             level--;
  262.             if (level == 0)
  263.                return;
  264.         }
  265.       }
  266.  
  267. }
  268.  
  269. cpycode ()    /* copies code between { and } */
  270. {
  271.     register int c;
  272.     c = unix_getc (finput);
  273.     if (c == '\n')
  274.        { c = unix_getc (finput);
  275.          lineno ++;
  276.        }
  277.  
  278.     fprintf (foutput, "\\{");
  279.     while (c >= 0)
  280.     {
  281.         if (c == '\\')
  282.            if ( (c = unix_getc (finput)) == '}')
  283.               { fprintf (foutput, "\\}");
  284.             return;
  285.               }
  286.            else
  287.               fprintf (foutput, "\\");
  288.  
  289.         if (c == '%')
  290.            if ( (c = unix_getc (finput)) == '}')
  291.               { fprintf (foutput, "%}");
  292.             return;
  293.               }
  294.            else
  295.               fprintf (foutput, "%");
  296.  
  297.  
  298.         fprintf (foutput, "%c", c);
  299.         if (c == '\n') lineno ++;
  300.         c = unix_getc (finput);
  301.     }
  302.  
  303.     error (FATAL, "error before %%}");
  304. }
  305.  
  306. skipcom ()    /* guess what */
  307. {
  308.     register int c;
  309.     register int i = 0;    /* number of lines skipped */
  310.  
  311.     if (unix_getc (finput) != '*')
  312.        error (FATAL, "illegal comment");
  313.  
  314.     c = unix_getc (finput);
  315.     while (c != EOF)
  316.     {
  317.         while (c == '*')
  318.            if ( (c = unix_getc (finput)) == '/') return i;
  319.         if (c == '\n') i++;
  320.         c = unix_getc (finput);
  321.     }
  322.  
  323.     error (FATAL, "error EOF within comment");
  324. }
  325.  
  326. cpyact ()    /* copy C action to closing ; or } */
  327.  
  328. {
  329.     int brac, c, match, j, s, tok;
  330.  
  331.     pref_stackadjust ();
  332.  
  333.     brac = 0;
  334.  
  335. loop:
  336.     c = unix_getc (finput);
  337.  
  338. swt:
  339.     switch (c)
  340.     {
  341.     case ';':
  342.         if (brac == 0)
  343.            { post_adjuststack ();
  344.              fprintf (foutput, "%c", c);
  345.              return;
  346.            }
  347.         goto lcopy;
  348.  
  349.     case '{':
  350.         brac++;
  351.         goto lcopy;
  352.  
  353.     case '$':
  354.         s = 1;
  355.         tok = -1;
  356.         c = unix_getc (finput);
  357.         if (c == '<')   /* type description */
  358.            { uungetc (c, finput);
  359.              if (gettok () != IDENT)
  360.             error (FATAL, "bad syntax on $<..> clause");
  361.              fprintf (foutput, "<%s>", tokname);
  362.              c = unix_getc (finput);
  363.            }
  364.  
  365.         if (c == '$')
  366.            {  fprintf (foutput, "$$");
  367.               goto loop;
  368.            }
  369.  
  370.         if (c == '-')
  371.            { s = -s;
  372.              c = unix_getc (finput);
  373.            }
  374.         if (isdigit(c))
  375.            { j = 0;
  376.              while (isdigit(c))
  377.              {    j = j * 10 + c - '0';
  378.             c = unix_getc (finput);
  379.              }
  380.              j = j * s;
  381.              fprintf (foutput, "$%d", j);
  382.              goto swt;
  383.            }
  384.  
  385.         if (is_letter (c))
  386.            { uungetc (c, finput);
  387.              tok = gettok ();
  388.              if (tok != IDENT)
  389.             error (FATAL, "illegal $construct");
  390.  
  391.              fprintf (foutput, "%s", address_of(tokname));
  392.              goto loop;
  393.            }
  394.  
  395.         fprintf (foutput, "$");
  396.         if (s < 0)
  397.            fprintf (foutput, "-");
  398.  
  399.         goto swt;
  400.  
  401.     case '}':
  402.         if (--brac > 0)
  403.            goto lcopy;
  404.  
  405.         post_adjuststack ();
  406.         fprintf (foutput, "%c", c);
  407.         return;
  408.  
  409.     case '/':
  410.         /* look for comment */
  411.         fprintf (foutput, "%c", c);
  412.         c = unix_getc (finput);
  413.         if (c != '*') goto swt;
  414.  
  415.         while (c != EOF)
  416.         {
  417.             while (c == '*')
  418.             {
  419.                 fprintf (foutput, "%c", c);
  420.                 if ( (c = unix_getc (finput)) == '/')
  421.                      goto lcopy;
  422.             }
  423.             fprintf (foutput, "%c", c);
  424.             if (c == '\n') lineno++;
  425.             c = unix_getc (finput);
  426.         }
  427.         error (FATAL, "EOF within comment");
  428.  
  429.     case '\'':
  430.         match = '\'';
  431.         goto string;
  432.  
  433.     case '"':
  434.         match = '"';
  435.  
  436. string:
  437.         fprintf (foutput, "%c", c);
  438.         while ( (c = unix_getc (finput)) != EOF)
  439.         {
  440.             if (c == '\\')
  441.             {
  442.                 fprintf (foutput, "%c", c);
  443.                 c = unix_getc (finput);
  444.                 if (c == '\n') lineno ++;
  445.             }
  446.             else
  447.             if (c == match) goto lcopy;
  448.             else
  449.             if (c == '\n')
  450.                error (FATAL, "newline in string or char const");
  451.             fprintf (foutput, "%c", c);
  452.         }
  453.  
  454.         error (FATAL, "EOF in string or character constant");
  455.  
  456.     case -1: /* EOF */
  457.         error ("action does not terminate");
  458.  
  459.     case '\n':
  460.         lineno++;
  461.         goto lcopy;
  462.  
  463.     }
  464.  
  465. lcopy:
  466.     fprintf (foutput, "%c", c);
  467.     goto loop;
  468. }
  469.