home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CGAZV5N3.ZIP / LEX.C < prev    next >
C/C++ Source or Header  |  1991-02-27  |  4KB  |  128 lines

  1. /* Listing 2. LEX.C -- A Brute-Force Lexical Analyzer */
  2.  
  3. #include <stdio.h>
  4. #include "lex.h"
  5.  
  6. char    *yytext = "";           /* holds the lexeme (not \0 terminated) */
  7. int     yyleng  = 0;            /* number of valid characters in lexeme */
  8. FILE    *yyinp  = stdin;        /* Input FILE.                          */
  9. #define LINELEN 128             /* Maximum input-line length.           */
  10.  
  11. #if ( defined(DEBUG) || defined(PTRACE) )
  12.  
  13. char *tokstr( token t )
  14. {
  15.     switch( t )
  16.     {
  17.     case NO_TOKEN:      return "NO_TOKEN";
  18.     case EOI:           return "EOI";
  19.     case EQUAL:         return "EQUAL";
  20.     case ID:            return "ID";
  21.     case LP:            return "LP";
  22.     case MINUS:         return "MINUS";
  23.     case NUMBER:        return "NUMBER";
  24.     case PLUS:          return "PLUS";
  25.     case RP:            return "RP";
  26.     case SEMI:          return "SEMI";
  27.     case SLASH:         return "SLASH";
  28.     case STAR:          return "STAR";
  29.     case WHILE:         return "WHILE";
  30.     }
  31.  
  32.     return "UNKNOWN";
  33. }
  34. #endif
  35.  
  36. /*----------------------------------------------------------------------*/
  37.  
  38. static token yylex()
  39. {
  40.     /* A brute-force, line oriented lexical analyzer */
  41.  
  42.     static char input_buf[ LINELEN ];   /* Initialized to 0's by default. */
  43.     static char *p = input_buf;         /* *p is initially '\0'.         */
  44.  
  45.     int rval = NO_TOKEN;                /* Returned token                 */
  46.  
  47.     do
  48.     {
  49.         if( !*p )                                    /* If buffer empty, */
  50.         {
  51.             if( !fgets(input_buf, LINELEN, yyinp) )  /* get a new line.  */
  52.                 return EOI;                          /* End of input.    */
  53.             p = input_buf;
  54.         }
  55.  
  56.         while( isspace( *p ) )          /* Skip leading white space */
  57.             ++p;
  58.  
  59.     } while( !*p );             /* Until you find a nonempty line.  */
  60.  
  61.     /* At this juncture, p is pointing at a nonspace character; either
  62.      * at the first character on the line or at the first nonspace
  63.      * character following the last lexeme we recognized.
  64.      */
  65.  
  66.     yytext = p;         /* pointer to current lexeme    */
  67.     yyleng = 1;         /* default lexeme length        */
  68.  
  69.     switch( *p++ )
  70.     {
  71.     case '=':   rval = EQUAL;   break;
  72.     case '+':   rval = PLUS;    break;
  73.     case '-':   rval = MINUS;   break;
  74.     case '*':   rval = STAR;    break;
  75.     case '/':   rval = SLASH;   break;
  76.     case ';':   rval = SEMI;    break;
  77.     case '(':   rval = LP;      break;
  78.     case ')':   rval = RP;      break;
  79.     default:
  80.         if( isdigit(*yytext) )
  81.         {
  82.             for(; isdigit(*p); ++p, ++yyleng )
  83.                 ;
  84.             rval = NUMBER;
  85.         }
  86.         else if( isalpha(*yytext) )
  87.         {
  88.             for(; isalnum(*p); ++p, ++yyleng )
  89.                 ;
  90.  
  91.             rval = !strncmp("while", yytext, yyleng) ? WHILE
  92.                                                      : ID;
  93.         }
  94.         else
  95.         {
  96.             fprintf(stderr,"Ignoring bad input char. (%c)\n", *yytext);
  97.             exit(1);
  98.         }
  99.     }
  100. #   ifdef DEBUG
  101.         printf("yylex returning %s (%1.*s)\n", tokstr(rval), yyleng, yytext);
  102. #   endif
  103.  
  104.     return rval;
  105. }
  106. /*------------------------------------------------------------------*/
  107. static token Lookahead = NO_TOKEN;
  108.  
  109. int match( token t )
  110. {
  111.     if( Lookahead == NO_TOKEN )
  112.         Lookahead = yylex();
  113.  
  114.     return Lookahead == t;
  115. }
  116. /*------------------------------------------------------------------*/
  117. void advance()
  118. {
  119.     #ifdef PTRACE               /* Debugging diagnostic, print     */
  120.                                 /* current lexeme before advancing */
  121.         extern int rdepth(void);        /* declared in topdown.c */
  122.  
  123.         printf("%*s%s (%1.*s)\n", rdepth(), "", tokstr(Lookahead),
  124.                                                 yyleng, yytext );
  125.     #endif;
  126.  
  127.     Lookahead = yylex();
  128. }