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

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