home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / awk / awk320sr.zip / YYLEX.C < prev    next >
Text File  |  1991-04-25  |  7KB  |  361 lines

  1. /*
  2.  * yylex for lex tables
  3.  *
  4.  * Copyright (C) 1988, 1989, 1990, 1991 by Rob Duff
  5.  * All rights reserved
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include "yylex.h"
  10.  
  11. #define NBPW    16      /* bits per word */
  12. #define YYSIZE  100     /* size of work buffer */
  13.  
  14. int     yyline  = 0;
  15. int     yyleng  = 0;
  16. char    yytext[YYSIZE+1] = "";
  17.  
  18. static int lleof = 0;
  19. static int llmore = 0;
  20.  
  21. static unsigned char *llsave[NBPW]; /* Right-context buffer                 */
  22. static unsigned char llbuf[YYSIZE]; /* work buffer                          */
  23. static unsigned char *llp1 = llbuf; /* pointer to next avail. in buffer     */
  24. static unsigned char *llp2 = llbuf; /* pointer to end of lookahead          */
  25. static unsigned char *llend = llbuf;/* pointer to end of buffer             */
  26.  
  27. extern yytab lextab;
  28. static yytab *lltab = &lextab;
  29.  
  30. extern void exit(int);
  31. extern int yywrap(void);
  32. extern void yyecho(void);
  33. extern void yyerror(char*, ...);
  34.  
  35. extern int yyinp(void);
  36. extern void yyout(char);
  37.  
  38. static int llset(void);
  39. static int llinp(void);
  40. static int lltst(int, char*);
  41. static int llmov(yytab*, int, int);
  42.  
  43. yylex()
  44. {
  45.     register yytab *lp;
  46.     yyrej   *save;
  47.     register int c;
  48.     int     st, l, llk, final;
  49.     char    *cp;
  50.  
  51. loop:
  52.     if (llset()) {
  53.         if (yywrap())
  54.             return(0);
  55.     }
  56.     st = 0;
  57.     llk = 0;
  58.     lp = lltab;
  59.     save = lp->llback;
  60.     final = -1;
  61.     llend = llbuf + 1;
  62.  
  63.     do {
  64.         if (lp->lllook && (l = lp->lllook[st]) != 0) {
  65.             for (c=0; c<NBPW; c++)
  66.                 if (l&(1<<c))
  67.                     llsave[c] = llp1;
  68.             llk++;
  69.         }
  70.         if ((c = lp->llfinal[st]) != -1) {
  71.             save->llfin = final;
  72.             save->lllen = llend - llbuf;
  73.             save++;
  74.             final = c;
  75.             if ((l = ((c >> 11) & 037)) != 0)
  76.                 llend = llsave[l-1];
  77.             else
  78.                 llend = llp1;
  79.         }
  80.         if ((c = llinp()) <= 0)
  81.             break;
  82.         if ((cp = lp->llbrk) != 0 && llk == 0 && lltst(c, cp)) {
  83.             llp1--;
  84.             break;
  85.         }
  86.     } while ((st = llmov(lp, c, st)) != -1);
  87.  
  88.     if (llp2 < llp1)
  89.         llp2 = llp1;
  90.     if (final == -1) {
  91.         llend = llp1;
  92.         if (st == 0 && c <= 0)
  93.             goto loop;
  94.         if ((cp = lp->llill) != 0 && lltst(c, cp)) {
  95.             if (c >= ' ' && c <= '~')
  96.                 yyerror("Illegal character: %c", c);
  97.             else
  98.                 yyerror("Illegal character: \\%03o", c);
  99.             goto loop;
  100.         }
  101.     }
  102.  
  103. back:
  104.     llp1 = llend;
  105.     yyleng = (int)(llend - llbuf);
  106.     yytext[yyleng] = '\0';
  107.     if (final == -1) {
  108.         yyecho();
  109.         goto loop;
  110.     }
  111.     if ((c = (*lp->llactr)(final&03777)) >= 0)
  112.         return(c);
  113.     if (c == -1 && save-- > lp->llback) {
  114.         final = save->llfin;
  115.         llend = llbuf + save->lllen;
  116.         yytext[yyleng] = llbuf[yyleng];
  117.         goto back;
  118.     }
  119.     goto loop;
  120. }
  121.  
  122. /*
  123.  *  check character class table
  124.  */
  125. static
  126. lltst(c, tab)
  127. register int c;
  128. char tab[];
  129. {
  130.     return(tab[(c >> 3) & 037] & (1 << (c & 07)) );
  131. }
  132.  
  133. /*
  134.  * Return TRUE if EOF and nothing was moved in the look-ahead buffer
  135.  */
  136. static
  137. llset()
  138. {
  139.     register unsigned char *lp1, *lp2;
  140.  
  141.     if (llmore == 0)
  142.         llend = llbuf;
  143.     llmore = 0;
  144.     for (lp1 = llend, lp2 = llp1; lp2 < llp2; lp1++, lp2++)
  145.         *lp1 = *lp2;
  146.     llp2 = lp1;
  147.     llp1 = llend;
  148.     return(lleof && llp1 == llp2);
  149. }
  150.  
  151. static
  152. llmov(lp, c, st)
  153. register yytab *lp;
  154. register int    st;
  155. int    c;
  156. {
  157.     int     base;
  158.  
  159.     while ((base = lp->llbase[st]+c) > lp->llnxtmax || lp->llcheck[base] != st)
  160.         if (st != lp->llendst)
  161.             st = lp->lldefault[st];
  162.         else
  163.             return(-1);
  164.     return(lp->llnext[base]);
  165. }
  166.  
  167. /*
  168.  * Get the next character from the save buffer (if possible)
  169.  * If the save buffer's empty, then return EOF or the next
  170.  * input character.  Ignore the character if it's in the
  171.  * ignore class.
  172.  */
  173. static
  174. llinp()
  175. {
  176.     register c;
  177.     register char *cp;
  178.  
  179.     cp = lltab->llign;
  180.     for (;;) {
  181.         c = (llp1 < llp2) ? *llp1 : (lleof) ? EOF : yyinp();
  182.         if (c != EOF) {
  183.             if (cp && lltst(c, cp))
  184.                 continue;
  185.             if (llp1 >= (llbuf+YYSIZE)) {
  186.                 yyerror("Token buffer overflow");
  187.                 exit(1);
  188.             }
  189.             yytext[(int)(llp1 - llbuf)] = c;
  190.             *llp1++ = c;
  191.         } else
  192.             lleof = 1;
  193.         return(c);
  194.     }
  195. }
  196.  
  197. /*
  198.  *  add next token to end of this one
  199.  */
  200. void
  201. yymore()
  202. {
  203.     llmore = 1;
  204. }
  205.  
  206. /*
  207.  *  switch contexts to lp
  208.  */
  209. yytab *
  210. yyswitch(lp)
  211. yytab *lp;
  212. {
  213.     register yytab *olp;
  214.  
  215.     olp = lltab;
  216.     lltab = (lp == NULL) ? &lextab : lp;
  217.     return(olp);
  218. }
  219.  
  220. /*
  221.  *
  222.  */
  223. void
  224. yyecho()
  225. {
  226.     register int cp;
  227.  
  228.     for (cp = 0; cp < yyleng; cp++)
  229.         yyout(yytext[cp]);
  230. }
  231.  
  232. /*
  233.  *  Look how many characters are backed up
  234.  */
  235. int
  236. yylook()
  237. {
  238.     return (int)(llp2 - llp1);
  239. }
  240.  
  241. /*
  242.  *  Peek at the next character of input
  243.  */
  244. int
  245. yypeek()
  246. {
  247.     int     c;
  248.  
  249.     if (llp1 < llp2)
  250.         return(*llp1);
  251.     if (lleof)
  252.         return (EOF);
  253.     if (llp1 >= (llbuf+YYSIZE)) {
  254.         yyerror("Token buffer overflow");
  255.         exit(1);
  256.     }
  257.     c = yyinp();
  258.     if (c == EOF) {
  259.         lleof = 1;
  260.         return (EOF);
  261.     }
  262.     *llp1 = c;
  263.     llp2 = llp1 + 1;
  264.     return (c);
  265. }
  266.  
  267. /*
  268.  *  steal next character from input
  269.  */
  270. int
  271. yynext()
  272. {
  273.     int     c;
  274.  
  275.     c = (llp1 < llp2) ? *llp1++ : (lleof) ? EOF : yyinp();
  276.     if (c == EOF)
  277.         lleof = 1;
  278.     return(c);
  279. }
  280.  
  281. /*
  282.  *  put back c on input
  283.  */
  284. void
  285. yyback(c)
  286. {
  287.     register unsigned char *lp1, *lp2;
  288.  
  289.     if (llp1 > llend)
  290.         llp1--;
  291.     else if (llp2 >= (llbuf+YYSIZE)) {
  292.         yyerror("Token buffer overflow");
  293.         exit(1);
  294.     }
  295.     else {
  296.         for (lp1 = llp1, lp2 = llp2 - 1; lp2 >= lp1; lp2--)
  297.             lp2[1] = lp2[0];
  298.         llp2++;
  299.     }
  300.     *llp1 = c;
  301. }
  302.  
  303. /*
  304.  *  add character to token
  305.  */
  306. void
  307. yyplus(c)
  308. {
  309.     register unsigned char *lp1, *lp2;
  310.  
  311.     if (llp1 == llend) {
  312.         if (llp2 >= (llbuf+YYSIZE)) {
  313.             yyerror("Token buffer overflow");
  314.             exit(1);
  315.         }
  316.         for (lp1 = llp1, lp2 = llp2 - 1; lp2 >= lp1; lp2--)
  317.             lp2[1] = lp2[0];
  318.         llp1++;
  319.         llp2++;
  320.     }
  321.     yytext[(int)(llend - llbuf)] = c;
  322.     *llend = c;
  323.     llend++;
  324.     yyleng = (int)(llend - llbuf);
  325.     yytext[yyleng] = '\0';
  326. }
  327.  
  328. /*
  329.  *  trim token to length n
  330.  */
  331. void
  332. yyless(n)
  333. {
  334.     register unsigned char *lp1, *lp2;
  335.  
  336.     for (lp1 = llend, lp2 = llp1; lp2 < llp2; lp1++, lp2++)
  337.         *lp1 = *lp2;
  338.     llp2 = lp1;
  339.     if (n < 0)
  340.         n = 0;
  341.     else if (n > (int)(llend - llbuf))
  342.         n = (int)(llend - llbuf);
  343.     yyleng = n;
  344.     yytext[n] = '\0';
  345.     llend = llp1 = llbuf + n;
  346. }
  347.  
  348. /*
  349.  * Re-initialize yylex() so that it can be re-used on
  350.  * another file.
  351.  */
  352. void
  353. yyinit()
  354. {
  355.     lleof = llmore = yyline = yyleng = 0;
  356.     llp1 = llp2 = llend = llbuf;
  357.     lltab = &lextab;
  358.     *yytext = '\0';
  359. }
  360. 
  361.