mirror of
https://github.com/PDP-10/its.git
synced 2026-04-05 21:43:12 +00:00
175 lines
3.6 KiB
C
175 lines
3.6 KiB
C
/*
|
|
* yylex for lex tables
|
|
*/
|
|
|
|
/*
|
|
* Bob Denny 28-Aug-82 Remove reference to stdio.h
|
|
* Remove code to default lexin, change to call to
|
|
* llstin(), generated by lex depending upon setting
|
|
* of "-s" switch. Eliminates hardwired dependency
|
|
* on standard I/O library. Moved declaration of
|
|
* lexin to lexgetc().
|
|
*
|
|
* Bob Denny 31-Aug-82 Add call to lexswitch() in
|
|
* the generated file, to switch to the table whose
|
|
* name was given in the "-t" switch (or to "lextab"
|
|
* if "-t" wasn't given). Removed hardwired setting
|
|
* of _tabp --> "lextab" here. Now handled automagically.
|
|
*
|
|
* Bob Denny 21-Oct-82 Add llinit() function to re-initialize
|
|
* yylex(), making it serially reusable.
|
|
*
|
|
* Initialize _tabp to NULL so lexswitch() to real table happens
|
|
* only once.
|
|
*/
|
|
|
|
#include <stdio.h> /* PLB */
|
|
#ifdef vms
|
|
#include "c:lex.h"
|
|
#else
|
|
#include <lex.h>
|
|
#endif
|
|
|
|
/*)LIBRARY
|
|
*/
|
|
|
|
#define ERROR 256 /* yacc's value */
|
|
|
|
#define NBPW 16 /* bits per word */
|
|
|
|
tst__b(c, tab)
|
|
register int c;
|
|
char tab[];
|
|
{
|
|
return(tab[(c >> 3) & 037] & (1 << (c & 07)) );
|
|
}
|
|
|
|
struct lextab *_tabp = 0;
|
|
|
|
extern char *llsave[]; /* Right-context buffer */
|
|
char llbuf[100]; /* work buffer */
|
|
char *llp1 = &llbuf[0]; /* pointer to next avail. in token */
|
|
char *llp2 = &llbuf[0]; /* pointer to end of lookahead */
|
|
char *llend = &llbuf[0]; /* pointer to end of token */
|
|
char *llebuf = &llbuf[sizeof llbuf];
|
|
int lleof;
|
|
int yylval = 0;
|
|
int yyline = 0;
|
|
|
|
yylex()
|
|
{
|
|
register c, st;
|
|
int final, l, llk, i;
|
|
register struct lextab *lp;
|
|
char *cp;
|
|
|
|
/*
|
|
* Call llstin() to default lexin to stdin
|
|
* and assign _tabp to "real" table.
|
|
*/
|
|
llstin(); /* Initialize yylex() variables */
|
|
loop:
|
|
llk = 0;
|
|
if (llset())
|
|
return(0); /* Prevent EOF loop */
|
|
st = 0;
|
|
final = -1;
|
|
lp = _tabp;
|
|
|
|
do {
|
|
if (lp->lllook && (l = lp->lllook[st])) {
|
|
for (c=0; c<NBPW; c++)
|
|
if (l&(1<<c))
|
|
llsave[c] = llp1;
|
|
llk++;
|
|
}
|
|
if ((i = lp->llfinal[st]) != -1) {
|
|
final = i;
|
|
llend = llp1;
|
|
}
|
|
if ((c = llinp()) < 0)
|
|
break;
|
|
if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
|
|
llp1--;
|
|
break;
|
|
}
|
|
} while ((st = (*lp->llmove)(lp, c, st)) != -1);
|
|
|
|
|
|
if (llp2 < llp1)
|
|
llp2 = llp1;
|
|
if (final == -1) {
|
|
llend = llp1;
|
|
if (st == 0 && c < 0)
|
|
return(0);
|
|
if ((cp = lp->llill) && tst__b(c, cp)) {
|
|
lexerror("Illegal (out of range) input character");
|
|
/*
|
|
lexerror("Illegal character: %c (%03o)", c, c);
|
|
*/
|
|
goto loop;
|
|
}
|
|
return(ERROR);
|
|
}
|
|
if (c = (final >> 11) & 037)
|
|
llend = llsave[c-1];
|
|
if ((c = (*lp->llactr)(final&03777)) >= 0)
|
|
return(c);
|
|
goto loop;
|
|
}
|
|
|
|
llinp()
|
|
{
|
|
register c;
|
|
register struct lextab *lp;
|
|
register char *cp;
|
|
|
|
lp = _tabp;
|
|
cp = lp->llign; /* Ignore class */
|
|
for (;;) {
|
|
/*
|
|
* 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.
|
|
*/
|
|
c = (llp1 < llp2) ? *llp1 & 0377 : (lleof) ? EOF : lexgetc();
|
|
if (c >= 0) { /* Got a character? */
|
|
if (cp && tst__b(c, cp))
|
|
continue; /* Ignore it */
|
|
if (llp1 >= llebuf) { /* No, is there room? */
|
|
lexerror("Token buffer overflow");
|
|
exit(1);
|
|
}
|
|
*llp1++ = c; /* Store in token buff */
|
|
} else
|
|
lleof = 1; /* Set EOF signal */
|
|
return(c);
|
|
}
|
|
}
|
|
|
|
llset()
|
|
/*
|
|
* Return TRUE if EOF and nothing was moved in the look-ahead buffer
|
|
*/
|
|
{
|
|
register char *lp1, *lp2;
|
|
|
|
for (lp1 = llbuf, lp2 = llend; lp2 < llp2;)
|
|
*lp1++ = *lp2++;
|
|
llend = llp1 = llbuf;
|
|
llp2 = lp1;
|
|
return(lleof && lp1 == llbuf);
|
|
}
|
|
|
|
/*
|
|
* Re-initialize yylex() so that it can be re-used on
|
|
* another file.
|
|
*/
|
|
llinit()
|
|
{
|
|
llp1 = llp2 = llend = llbuf;
|
|
llebuf = llbuf + sizeof(llbuf);
|
|
lleof = yylval = yyline = 0;
|
|
}
|