home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast2.iso
/
awk
/
awk320sr.zip
/
YYLEX.C
< prev
next >
Wrap
Text File
|
1991-04-25
|
7KB
|
361 lines
/*
* yylex for lex tables
*
* Copyright (C) 1988, 1989, 1990, 1991 by Rob Duff
* All rights reserved
*/
#include <stdio.h>
#include "yylex.h"
#define NBPW 16 /* bits per word */
#define YYSIZE 100 /* size of work buffer */
int yyline = 0;
int yyleng = 0;
char yytext[YYSIZE+1] = "";
static int lleof = 0;
static int llmore = 0;
static unsigned char *llsave[NBPW]; /* Right-context buffer */
static unsigned char llbuf[YYSIZE]; /* work buffer */
static unsigned char *llp1 = llbuf; /* pointer to next avail. in buffer */
static unsigned char *llp2 = llbuf; /* pointer to end of lookahead */
static unsigned char *llend = llbuf;/* pointer to end of buffer */
extern yytab lextab;
static yytab *lltab = &lextab;
extern void exit(int);
extern int yywrap(void);
extern void yyecho(void);
extern void yyerror(char*, ...);
extern int yyinp(void);
extern void yyout(char);
static int llset(void);
static int llinp(void);
static int lltst(int, char*);
static int llmov(yytab*, int, int);
yylex()
{
register yytab *lp;
yyrej *save;
register int c;
int st, l, llk, final;
char *cp;
loop:
if (llset()) {
if (yywrap())
return(0);
}
st = 0;
llk = 0;
lp = lltab;
save = lp->llback;
final = -1;
llend = llbuf + 1;
do {
if (lp->lllook && (l = lp->lllook[st]) != 0) {
for (c=0; c<NBPW; c++)
if (l&(1<<c))
llsave[c] = llp1;
llk++;
}
if ((c = lp->llfinal[st]) != -1) {
save->llfin = final;
save->lllen = llend - llbuf;
save++;
final = c;
if ((l = ((c >> 11) & 037)) != 0)
llend = llsave[l-1];
else
llend = llp1;
}
if ((c = llinp()) <= 0)
break;
if ((cp = lp->llbrk) != 0 && llk == 0 && lltst(c, cp)) {
llp1--;
break;
}
} while ((st = llmov(lp, c, st)) != -1);
if (llp2 < llp1)
llp2 = llp1;
if (final == -1) {
llend = llp1;
if (st == 0 && c <= 0)
goto loop;
if ((cp = lp->llill) != 0 && lltst(c, cp)) {
if (c >= ' ' && c <= '~')
yyerror("Illegal character: %c", c);
else
yyerror("Illegal character: \\%03o", c);
goto loop;
}
}
back:
llp1 = llend;
yyleng = (int)(llend - llbuf);
yytext[yyleng] = '\0';
if (final == -1) {
yyecho();
goto loop;
}
if ((c = (*lp->llactr)(final&03777)) >= 0)
return(c);
if (c == -1 && save-- > lp->llback) {
final = save->llfin;
llend = llbuf + save->lllen;
yytext[yyleng] = llbuf[yyleng];
goto back;
}
goto loop;
}
/*
* check character class table
*/
static
lltst(c, tab)
register int c;
char tab[];
{
return(tab[(c >> 3) & 037] & (1 << (c & 07)) );
}
/*
* Return TRUE if EOF and nothing was moved in the look-ahead buffer
*/
static
llset()
{
register unsigned char *lp1, *lp2;
if (llmore == 0)
llend = llbuf;
llmore = 0;
for (lp1 = llend, lp2 = llp1; lp2 < llp2; lp1++, lp2++)
*lp1 = *lp2;
llp2 = lp1;
llp1 = llend;
return(lleof && llp1 == llp2);
}
static
llmov(lp, c, st)
register yytab *lp;
register int st;
int c;
{
int base;
while ((base = lp->llbase[st]+c) > lp->llnxtmax || lp->llcheck[base] != st)
if (st != lp->llendst)
st = lp->lldefault[st];
else
return(-1);
return(lp->llnext[base]);
}
/*
* Get the next character from the save buffer (if possible)
* If the save buffer's empty, then return EOF or the next
* input character. Ignore the character if it's in the
* ignore class.
*/
static
llinp()
{
register c;
register char *cp;
cp = lltab->llign;
for (;;) {
c = (llp1 < llp2) ? *llp1 : (lleof) ? EOF : yyinp();
if (c != EOF) {
if (cp && lltst(c, cp))
continue;
if (llp1 >= (llbuf+YYSIZE)) {
yyerror("Token buffer overflow");
exit(1);
}
yytext[(int)(llp1 - llbuf)] = c;
*llp1++ = c;
} else
lleof = 1;
return(c);
}
}
/*
* add next token to end of this one
*/
void
yymore()
{
llmore = 1;
}
/*
* switch contexts to lp
*/
yytab *
yyswitch(lp)
yytab *lp;
{
register yytab *olp;
olp = lltab;
lltab = (lp == NULL) ? &lextab : lp;
return(olp);
}
/*
*
*/
void
yyecho()
{
register int cp;
for (cp = 0; cp < yyleng; cp++)
yyout(yytext[cp]);
}
/*
* Look how many characters are backed up
*/
int
yylook()
{
return (int)(llp2 - llp1);
}
/*
* Peek at the next character of input
*/
int
yypeek()
{
int c;
if (llp1 < llp2)
return(*llp1);
if (lleof)
return (EOF);
if (llp1 >= (llbuf+YYSIZE)) {
yyerror("Token buffer overflow");
exit(1);
}
c = yyinp();
if (c == EOF) {
lleof = 1;
return (EOF);
}
*llp1 = c;
llp2 = llp1 + 1;
return (c);
}
/*
* steal next character from input
*/
int
yynext()
{
int c;
c = (llp1 < llp2) ? *llp1++ : (lleof) ? EOF : yyinp();
if (c == EOF)
lleof = 1;
return(c);
}
/*
* put back c on input
*/
void
yyback(c)
{
register unsigned char *lp1, *lp2;
if (llp1 > llend)
llp1--;
else if (llp2 >= (llbuf+YYSIZE)) {
yyerror("Token buffer overflow");
exit(1);
}
else {
for (lp1 = llp1, lp2 = llp2 - 1; lp2 >= lp1; lp2--)
lp2[1] = lp2[0];
llp2++;
}
*llp1 = c;
}
/*
* add character to token
*/
void
yyplus(c)
{
register unsigned char *lp1, *lp2;
if (llp1 == llend) {
if (llp2 >= (llbuf+YYSIZE)) {
yyerror("Token buffer overflow");
exit(1);
}
for (lp1 = llp1, lp2 = llp2 - 1; lp2 >= lp1; lp2--)
lp2[1] = lp2[0];
llp1++;
llp2++;
}
yytext[(int)(llend - llbuf)] = c;
*llend = c;
llend++;
yyleng = (int)(llend - llbuf);
yytext[yyleng] = '\0';
}
/*
* trim token to length n
*/
void
yyless(n)
{
register unsigned char *lp1, *lp2;
for (lp1 = llend, lp2 = llp1; lp2 < llp2; lp1++, lp2++)
*lp1 = *lp2;
llp2 = lp1;
if (n < 0)
n = 0;
else if (n > (int)(llend - llbuf))
n = (int)(llend - llbuf);
yyleng = n;
yytext[n] = '\0';
llend = llp1 = llbuf + n;
}
/*
* Re-initialize yylex() so that it can be re-used on
* another file.
*/
void
yyinit()
{
lleof = llmore = yyline = yyleng = 0;
llp1 = llp2 = llend = llbuf;
lltab = &lextab;
*yytext = '\0';
}