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 >
Wrap
C/C++ Source or Header
|
1991-02-27
|
4KB
|
128 lines
/* Listing 2. LEX.C -- A Brute-Force Lexical Analyzer */
#include <stdio.h>
#include "lex.h"
char *yytext = ""; /* holds the lexeme (not \0 terminated) */
int yyleng = 0; /* number of valid characters in lexeme */
FILE *yyinp = stdin; /* Input FILE. */
#define LINELEN 128 /* Maximum input-line length. */
#if ( defined(DEBUG) || defined(PTRACE) )
char *tokstr( token t )
{
switch( t )
{
case NO_TOKEN: return "NO_TOKEN";
case EOI: return "EOI";
case EQUAL: return "EQUAL";
case ID: return "ID";
case LP: return "LP";
case MINUS: return "MINUS";
case NUMBER: return "NUMBER";
case PLUS: return "PLUS";
case RP: return "RP";
case SEMI: return "SEMI";
case SLASH: return "SLASH";
case STAR: return "STAR";
case WHILE: return "WHILE";
}
return "UNKNOWN";
}
#endif
/*----------------------------------------------------------------------*/
static token yylex()
{
/* A brute-force, line oriented lexical analyzer */
static char input_buf[ LINELEN ]; /* Initialized to 0's by default. */
static char *p = input_buf; /* *p is initially '\0'. */
int rval = NO_TOKEN; /* Returned token */
do
{
if( !*p ) /* If buffer empty, */
{
if( !fgets(input_buf, LINELEN, yyinp) ) /* get a new line. */
return EOI; /* End of input. */
p = input_buf;
}
while( isspace( *p ) ) /* Skip leading white space */
++p;
} while( !*p ); /* Until you find a nonempty line. */
/* At this juncture, p is pointing at a nonspace character; either
* at the first character on the line or at the first nonspace
* character following the last lexeme we recognized.
*/
yytext = p; /* pointer to current lexeme */
yyleng = 1; /* default lexeme length */
switch( *p++ )
{
case '=': rval = EQUAL; break;
case '+': rval = PLUS; break;
case '-': rval = MINUS; break;
case '*': rval = STAR; break;
case '/': rval = SLASH; break;
case ';': rval = SEMI; break;
case '(': rval = LP; break;
case ')': rval = RP; break;
default:
if( isdigit(*yytext) )
{
for(; isdigit(*p); ++p, ++yyleng )
;
rval = NUMBER;
}
else if( isalpha(*yytext) )
{
for(; isalnum(*p); ++p, ++yyleng )
;
rval = !strncmp("while", yytext, yyleng) ? WHILE
: ID;
}
else
{
fprintf(stderr,"Ignoring bad input char. (%c)\n", *yytext);
exit(1);
}
}
# ifdef DEBUG
printf("yylex returning %s (%1.*s)\n", tokstr(rval), yyleng, yytext);
# endif
return rval;
}
/*------------------------------------------------------------------*/
static token Lookahead = NO_TOKEN;
int match( token t )
{
if( Lookahead == NO_TOKEN )
Lookahead = yylex();
return Lookahead == t;
}
/*------------------------------------------------------------------*/
void advance()
{
#ifdef PTRACE /* Debugging diagnostic, print */
/* current lexeme before advancing */
extern int rdepth(void); /* declared in topdown.c */
printf("%*s%s (%1.*s)\n", rdepth(), "", tokstr(Lookahead),
yyleng, yytext );
#endif;
Lookahead = yylex();
}