home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / pascal / src / yylex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-16  |  7.8 KB  |  379 lines

  1. /*-
  2.  * Copyright (c) 1980 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)yylex.c    5.2 (Berkeley) 4/16/91";
  36. #endif /* not lint */
  37.  
  38. #include "whoami.h"
  39. #include "0.h"
  40. #include "tree_ty.h"    /* must be included for yy.h */
  41. #include "yy.h"
  42.  
  43. /*
  44.  * Scanner
  45.  */
  46. int    yylacnt;
  47.  
  48. #define    YYLASIZ    10
  49.  
  50. struct    yytok Yla[YYLASIZ];
  51.  
  52. unyylex(y)
  53.     struct yytok *y;
  54. {
  55.  
  56.     if (yylacnt == YYLASIZ)
  57.         panic("unyylex");
  58.     copy((char *) &Yla[yylacnt], (char *) y, sizeof Yla[0]);
  59.     yylacnt++;
  60.  
  61. }
  62.  
  63. yylex()
  64. {
  65.     register c;
  66.     register int **ip;
  67.     register char *cp;
  68.     int f;
  69.     char delim;
  70.  
  71.     if (yylacnt != 0) {
  72.         yylacnt--;
  73.         copy((char *) &Y, (char *) &Yla[yylacnt], sizeof Y);
  74.         return (yychar);
  75.     }
  76.     if (c = yysavc)
  77.         yysavc = 0;
  78.     else
  79.         c = readch();
  80. #ifdef PXP
  81.     yytokcnt++;
  82. #endif
  83.  
  84. next:
  85.     /*
  86.      * skip white space
  87.      */
  88. #ifdef PXP
  89.     yywhcnt = 0;
  90. #endif
  91.     while (c == ' ' || c == '\t') {
  92. #ifdef PXP
  93.         if (c == '\t')
  94.             yywhcnt++;
  95.         yywhcnt++;
  96. #endif
  97.         c = readch();
  98.     }
  99.     yyecol = yycol;
  100.     yyeline = yyline;
  101.     yyefile = filename;
  102.     yyeseqid = yyseqid;
  103.     yyseekp = yylinpt;
  104.     cp = token;
  105.     yylval = yyline;
  106.     switch (c) {
  107.         case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': 
  108.         case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 
  109.         case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': 
  110.         case 'v': case 'w': case 'x': case 'y': case 'z': 
  111.         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 
  112.         case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 
  113.         case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 
  114.         case 'V': case 'W': case 'X': case 'Y': case 'Z': 
  115.             do {
  116.                 *cp++ = c;
  117.                 c = readch();
  118.             } while (alph(c) || digit(c));
  119.             *cp = 0;
  120.             if (opt('s'))
  121.                 for (cp = token; *cp; cp++)
  122.                     if (*cp >= 'A' && *cp <= 'Z') {
  123.                         *cp |= ' ';
  124.                     }
  125.             yysavc = c;
  126.             ip = (int **) hash((char *) 0, 1);
  127.             if (*ip < (int *) yykey || *ip >= (int *) lastkey) {
  128.                 yylval = (int) *ip;
  129.                 return (YID);
  130.             }
  131.             yylval = yyline;
  132.             /*
  133.              * For keywords
  134.              * the lexical token
  135.              * is magically retrieved
  136.              * from the keyword table.
  137.              */
  138.             return ((*ip)[1]);
  139.         case '0': case '1': case '2': case '3': case '4':
  140.         case '5': case '6': case '7': case '8': case '9':
  141.             f = 0;
  142.             do {
  143.                 *cp++ = c;
  144.                 c = readch();
  145.             } while (digit(c));
  146.             if (c == 'b' || c == 'B') {
  147.                 /*
  148.                  * nonstandard - octal constants
  149.                  */
  150.                 if (opt('s')) {
  151.                     standard();
  152.                     yerror("Octal constants are non-standard");
  153.                 }
  154.                 *cp = 0;
  155.                 yylval = copystr(token);
  156.                 return (YBINT);
  157.             }
  158.             if (c == '.') {
  159.                 c = readch();
  160.                 if (c == '.') {
  161.                     *cp = 0;
  162.                     yysavc = YDOTDOT;
  163.                     yylval = copystr(token);
  164.                     return (YINT);
  165.                 }
  166. infpnumb:
  167.                 f++;
  168.                 *cp++ = '.';
  169.                 if (!digit(c)) {
  170.                     yyset();
  171.                     recovered();
  172.                     yerror("Digits required after decimal point");
  173.                     *cp++ = '0';
  174.                 } else
  175.                     while (digit(c)) {
  176.                         *cp++ = c;
  177.                         c = readch();
  178.                     }
  179.             }
  180.             if (c == 'e' || c == 'E') {
  181.                 f++;
  182.                 *cp++ = c;
  183.                 if ((c = yysavc) == 0)
  184.                     c = readch();
  185.                 if (c == '+' || c == '-') {
  186.                     *cp++ = c;
  187.                     c = readch();
  188.                 }
  189.                 if (!digit(c)) {
  190.                     yyset();
  191.                     yerror("Digits required in exponent");
  192.                     *cp++ = '0';
  193.                 } else
  194.                     while (digit(c)) {
  195.                         *cp++ = c;
  196.                         c = readch();
  197.                     }
  198.             }
  199.             *cp = 0;
  200.             yysavc = c;
  201.             yylval = copystr(token);
  202.             if (f)
  203.                 return (YNUMB);
  204.             return (YINT);
  205.         case '"':
  206.         case '`':
  207.         case '#':
  208.             if (!any(bufp + 1, c))
  209.                 goto illch;
  210.             if (!dquote) {
  211.                 recovered();
  212.                 dquote++;
  213.                 yerror("Character/string delimiter is '");
  214.             }
  215.         case '\'':
  216.             delim = c;
  217.             do {
  218.                 do {
  219.                     c = readch();
  220.                     if (c == '\n') {
  221.                         yerror("Unmatched %c for string", (char *) delim);
  222.                         if (cp == token)
  223.                             *cp++ = ' ', cp++;
  224.                         break;
  225.                     }
  226.                     *cp++ = c;
  227.                 } while (c != delim);
  228.                 c = readch();
  229.             } while (c == delim);
  230.             *--cp = 0;
  231.             if (cp == token) {
  232.                 yerror("Null string not allowed");
  233.                 *cp++ = ' ';
  234.                 *cp++ = 0;
  235.             }
  236.             yysavc = c;
  237.             yylval = copystr(token);
  238.             return (YSTRING);
  239.         case '.':
  240.             c = readch();
  241.             if (c == '.')
  242.                 return (YDOTDOT);
  243.             if (digit(c)) {
  244.                 recovered();
  245.                 yerror("Digits required before decimal point");
  246.                 *cp++ = '0';
  247.                 goto infpnumb;
  248.             }
  249.             yysavc = c;
  250.             return ('.');
  251.         case '{':
  252.             /*
  253.              * { ... } comment
  254.              */
  255. #ifdef PXP
  256.             getcm(c);
  257. #endif
  258. #ifdef PI
  259.             c = options();
  260.             while (c != '}') {
  261.                 if (c <= 0)
  262.                     goto nonterm;
  263.                 if (c == '{') {
  264.                     warning();
  265.                     yyset();
  266.                     yerror("{ in a { ... } comment");
  267.                 }
  268.                 c = readch();
  269.             }
  270. #endif
  271.             c = readch();
  272.             goto next;
  273.         case '(':
  274.             if ((c = readch()) == '*') {
  275.                 /*
  276.                  * (* ... *) comment
  277.                  */
  278. #ifdef PXP
  279.                 getcm(c);
  280.                 c = readch();
  281.                 goto next;
  282. #endif
  283. #ifdef PI
  284.                 c = options();
  285.                 for (;;) {
  286.                     if (c < 0) {
  287. nonterm:
  288.                         yerror("Comment does not terminate - QUIT");
  289.                         pexit(ERRS);
  290.                     }
  291.                     if (c == '(' && (c = readch()) == '*') {
  292.                         warning();
  293.                         yyset();
  294.                         yerror("(* in a (* ... *) comment");
  295.                     }
  296.                     if (c == '*') {
  297.                         if ((c = readch()) != ')')
  298.                             continue;
  299.                         c = readch();
  300.                         goto next;
  301.                     }
  302.                     c = readch();
  303.                 }
  304. #endif
  305.             }
  306.             yysavc = c;
  307.             c = '(';
  308.         case ';':
  309.         case ',':
  310.         case ':':
  311.         case '=':
  312.         case '*':
  313.         case '+':
  314.         case '/':
  315.         case '-':
  316.         case ')':
  317.         case '[':
  318.         case ']':
  319.         case '<':
  320.         case '>':
  321.         case '^':
  322.             return (c);
  323.         case '~':
  324.         case '|':
  325.         case '&':
  326.             if ( opt('s') ) {
  327.                 yyset();
  328.                 standard();
  329.                 yerror("%c is non-standard", (char *) c);
  330.             }
  331.             return c;
  332.         default:
  333.             switch (c) {
  334.                 case YDOTDOT:
  335.                     return (c);
  336.                 case '\n':
  337.                     c = readch();
  338. #ifdef PXP
  339.                     yytokcnt++;
  340. #endif
  341.                     goto next;
  342.                 case '\f':
  343.                     c = readch();
  344.                     goto next;
  345.             }
  346.             if (c <= 0)
  347.                 return (YEOF);
  348. illch:
  349.             do
  350.                 yysavc = readch();
  351.             while (yysavc == c);
  352.             yylval = c;
  353.             return (YILLCH);
  354.     }
  355. }
  356.  
  357. yyset()
  358. {
  359.  
  360.     yyecol = yycol;
  361.     yyeline = yyline;
  362.     yyefile = filename;
  363.     yyseekp = yylinpt;
  364. }
  365.  
  366. /*
  367.  * Setuflg trims the current
  368.  * input line to at most 72 chars
  369.  * for the u option.
  370.  */
  371. setuflg()
  372. {
  373.  
  374.     if (charbuf[71] != '\n') {
  375.         charbuf[72] = '\n';
  376.         charbuf[73] = 0;
  377.     }
  378. }
  379.