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 >
Wrap
C/C++ Source or Header
|
1991-02-26
|
4KB
|
131 lines
/* Listing 2. lex.c- A Brute-Force Lexical Analyzer */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.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();
}