This commit is contained in:
Oliver Lehmann 1989-08-30 12:28:30 +00:00
parent de63467a29
commit 1e4ac310c6
5 changed files with 559 additions and 0 deletions

View File

@ -0,0 +1,54 @@
/*
** --- RC_CMT.C -------- COMMENT SCANNER ------------------------------------
**
** Scans comments (as delimited by the tokens 'Tokens.bgncmnt'
** and 'Tokens.endcmnt') and removes them from the query text.
**
** Version: @(#)rc_cmt.c 4.0 02/05/89
**
*/
# include "rc.h"
rc_comment()
{
register int i;
register int l;
register struct optab *op;
char buf[5];
/* find the end_of_comment operator */
for (op = Optab; op->term; op++)
if (op->token == Tokens.endcmnt)
break;
/* scan for the end of the comment */
l = AAlength(op->term);
for (i = 0; i < l; i++)
{
/* set up window on input */
if (!(buf[i] = rc_gtchar()))
{
/* non-terminated comment */
rc_error(10);
return (0);
}
}
while (!AAbequal(buf, op->term, l))
{
/* move window on input */
for (i = 0; i < l - 1; i++)
buf[i] = buf[i + 1];
if (!(buf[l - 1] = rc_gtchar()))
{
/* non terminated comment */
rc_error(10);
}
}
# ifdef RC_TRACE
if (TR_LEX)
printf("COMMENT:\n");
# endif
return (0);
}

View File

@ -0,0 +1,93 @@
/*
** --- RC_NAME.C ------- NAME SCANNER ---------------------------------------
**
** A name is defined to be a sequence of MAX_NAME or fewer alphanumeric
** characters, starting with an alphabetic (underscore "_" is considered
** an alphabetic). If it is not a keyword, each name is entered into
** the symbol table, indexed by 'yylval'. A token is then returned for
** that name.
**
** Version: @(#)rc_name.c 4.0 02/05/89
**
*/
# include "rc.h"
rc_name(chr)
int chr;
{
register int hi;
register int lo;
register int curr;
register struct macro *mac;
char namebuf[MAX_NAME + 1];
extern char *yylval;
extern char *rc_syment();
/* fill in the name */
yylval = namebuf;
*yylval = chr;
do
{
*++yylval = curr = rc_gtchar();
if ((yylval - namebuf) > MAX_NAME)
{
/* name too long */
*yylval = '\0';
rc_error(17, namebuf);
break;
}
} while (CMAP(curr) == ALPHA || CMAP(curr) == NUMBR);
rc_backup(curr);
*yylval = '\0';
/* is it a keyword ? */
lo = 0;
hi = Keyent - 1;
while (lo <= hi)
{
curr = (lo + hi) / 2;
switch (AAscompare(Keyword[curr].term, MAX_NAME, namebuf, MAX_NAME))
{
case 1:
hi = curr - 1;
continue;
case -1:
lo = curr + 1;
continue;
case 0:
yylval = (char *) Keyword[curr].opcode;
# ifdef RC_TRACE
if (TR_LEX)
printf("NAME: keyword %s\n", namebuf);
# endif
return (Keyword[curr].token);
}
}
/* lookup MACRO's */
for (curr = 0, mac = Macro; curr < Macro_no; curr++, mac++)
{
if (AAsequal(mac->templt, namebuf))
{
# ifdef RC_TRACE
if (TR_LEX)
printf("MACRO: %s=%d\n", namebuf, mac->subst);
# endif
yylval = (char *) mac->subst;
return (Tokens.iconst);
}
}
/* else, USER DEFINED NAME */
yylval = rc_syment(namebuf, AAlength(namebuf) + 1);
# ifdef RC_TRACE
if (TR_LEX)
printf("NAME: %s\n", yylval);
# endif
return (Tokens.name);
}

View File

@ -0,0 +1,144 @@
/*
** --- RC_NUM.C -------- NUMBER SCANNER -------------------------------------
**
** Scans numerical constants (both integer and floating). Each
** constant is converted from ascii to its numerical representation
** and is entered into the symbol table, indexed by 'yylval'.
** A token is returned for the number type.
**
** Due to the current atof in the utility library, floating overflow
** is not checked.
**
** Version: @(#)rc_num.c 4.0 02/05/89
**
*/
# include "rc.h"
rc_number(chr)
register int chr;
{
register char *ptr;
register int lsave;
register int toktyp;
double ftemp;
long ltemp;
char buf[MAX_FIELD];
extern char *rc_syment();
extern char *yylval;
lsave = Lcase;
Lcase = 0;
ptr = buf;
if ((*ptr = toktyp = chr) != '.')
{
do
{
/* get integer portion */
if ((ptr - buf) >= MAX_FIELD)
{
/* buffer overflow */
rc_error(14);
break;
}
*++ptr = toktyp = rc_gtchar();
} while (CMAP(toktyp) == NUMBR);
}
/* do rest of type determination */
switch (toktyp)
{
case '.':
/* floating point */
do
{
/* fill into ptr with up to next non-digit */
if ((ptr - buf) >= MAX_FIELD)
{
/* buffer overflow */
rc_error(14);
break;
}
*++ptr = toktyp = rc_gtchar();
} while (CMAP(toktyp) == NUMBR);
if (toktyp != 'e' && toktyp != 'E')
{
rc_backup(toktyp);
*ptr = 0;
goto convr;
}
case 'e':
case 'E':
if ((ptr - buf) >= MAX_FIELD)
{
/* buffer overflow */
rc_error(14);
goto convb;
}
*++ptr = toktyp = rc_gtchar();
if (CMAP(toktyp) == NUMBR || toktyp == '-' || toktyp == '+')
{
do
{
/* get exponent */
if ((ptr - buf) >= MAX_FIELD)
{
/* buffer overflow */
rc_error(14);
break;
}
*++ptr = toktyp = rc_gtchar();
} while (CMAP(toktyp) == NUMBR);
}
rc_backup(toktyp);
*ptr = 0;
convr:
if (AA_atof(buf, &ftemp))
{
rc_error(15, buf); /* floating conversion error */
convb:
ftemp = 0;
}
yylval = rc_syment(&ftemp, sizeof (double));
toktyp = Tokens.rconst;
# ifdef RC_TRACE
if (TR_LEX)
printf("NUMBER: rconst=%10.3f\n", ftemp);
# endif
break;
default:
/* integer */
rc_backup(*ptr);
*ptr = 0;
if (AA_atol(buf, &ltemp))
{
rc_error(16, buf); /* integer conversion error */
ltemp = 0;
}
if (ltemp < MIN_I2 || ltemp > MAX_I2)
{
yylval = rc_syment(&ltemp, sizeof (long));
toktyp = Tokens.lconst;
# ifdef RC_TRACE
if (TR_LEX)
printf("NUMBER: lconst=%ld\n", ltemp);
# endif
}
else
{
yylval = (char *) ltemp;
toktyp = Tokens.iconst;
# ifdef RC_TRACE
if (TR_LEX)
printf("NUMBER: iconst=%ld\n", ltemp);
# endif
}
break;
}
Lcase = lsave;
return (toktyp);
}

View File

@ -0,0 +1,82 @@
/*
** --- RC_OP.C --------- OPERATOR SCANNER -----------------------------------
**
** An operator is defined as any 1-3 character sequence of
** non-alphanumerics. It looks up each operator in 'Optab'
** and returns the appropriate token.
**
** Version: @(#)rc_op.c 4.0 02/05/89
**
*/
# include "rc.h"
rc_operator(chr)
register int chr;
{
register struct optab *op;
register int toktyp;
register int save;
char buf[4];
extern char *rc_syment();
extern char *yylval;
save = Lcase;
Lcase = 0;
/* get lookahead character */
buf[0] = chr;
buf[1] = toktyp = rc_gtchar();
buf[2] = rc_gtchar();
buf[3] = '\0';
/* is it a floating fraction without leading zero ? */
/* or an integer < 0 */
if ((buf[0] == '.' || buf[0] == '-') && CMAP(toktyp) == NUMBR)
{
Lcase = save;
rc_backup(buf[2]);
rc_backup(toktyp);
return (rc_number(chr));
}
/* three character operator ? */
for (op = &Optab[0]; op->term; op++)
if (AAsequal(op->term, buf))
break;
if (!op->term)
{
/* two character operator ? */
rc_backup(buf[2]);
buf[2] = '\0';
for (op = &Optab[0]; op->term; op++)
if (AAsequal(op->term, buf))
break;
if (!op->term)
{
rc_backup(toktyp);
buf[1] = '\0';
for (op = &Optab[0]; op->term; op++)
if (AAsequal(op->term, buf))
break;
if (!op->term)
{
/* invalid operator */
rc_error(13, buf);
return (1);
}
}
}
Lcase = save;
if(op->token == Tokens.bgncmnt)
return (rc_comment());
if(op->token == Tokens.sconst)
return (rc_string(op));
yylval = (char *) op->opcode;
# ifdef RC_TRACE
if (TR_LEX)
printf("OPERATOR: op=%s\n", op->term);
# endif
return (op->token);
}

View File

@ -0,0 +1,186 @@
/*
** --- RC_PARSE.C ------ PARSER FOR YACC OUTPUT -----------------------------
**
** Version: @(#)rc_parse.c 4.0 02/05/89
**
*/
# include "rc.h"
# define ACTION(state) (state & 07777)
# define OPERATION(state) (state >> 12)
/* the OPERATIONS */
# define SHIFT_ON_ERROR 010400
# define ERROR 0
# define SKIP 1
# define SHIFT 2
# define REDUCE 3
# define ACCEPT 4
/* SIZE for state and value stack */
# define MAXDEPTH 150
extern char *yyval; /* defined in the table file */
extern char *yylval; /* defined in the table file */
extern char **yypv; /* defined in the table file */
extern short yygo[]; /* defined in the table file */
extern short yypgo[]; /* defined in the table file */
extern short yyr1[]; /* defined in the table file */
extern short yyr2[]; /* defined in the table file */
extern short yyact[]; /* defined in the table file */
extern short yypact[]; /* defined in the table file */
# ifdef RC_TRACE
int rc_debug = 0; /* TR_PARSE for debugging (rc.h) */
# endif
rc_parse()
{
char *values[MAXDEPTH]; /* value stack */
short states[MAXDEPTH]; /* state stack */
register short *yyps; /* pointer to state stack */
register short *act; /* pointer to performing action */
register int state; /* current parser state */
register int next_state;
register int token; /* current input token number */
register int i;
register int errorflag; /* error recovery flag */
state = 0;
token = -1;
errorflag = 0;
yyps = &states[-1];
yypv = &values[-1];
stack:
*++yyps = state; /* push state into state stack */
*++yypv = yyval; /* push value into value stack */
# ifdef RC_TRACE
if (TR_PARSE)
printf("STATE %d value %d char %d\n", state, yyval, token);
# endif
new_state:
/* set act to point to the parsing actions for the new state */
i = yypact[state + 1];
act = &yyact[i];
next_action: /* get the next action, and perform it */
next_state = ACTION(*act);
switch (OPERATION(*act++)) /* switch on operation */
{
case SKIP:
if (token < 0)
{
/* get next token */
token = rc_lex();
# ifdef RC_TRACE
if (TR_PARSE)
printf( "CHARACTER %d read\n", token);
# endif
}
if (next_state != token)
act++;
goto next_action; /* get next action */
case SHIFT: /* goto next_state */
state = next_state;
yyval = yylval; /* $i = value of last token */
token = -1;
if (errorflag)
errorflag--;
goto stack; /* stack new state and value */
case REDUCE: /* rule next_state */
# ifdef RC_TRACE
if (TR_PARSE)
printf("REDUCE %d\n", next_state);
# endif
yyps -= yyr2[next_state]; /* pop state stack */
yypv -= yyr2[next_state]; /* pop value stack */
yyval = yypv[1]; /* $$ = $1 */
if (Compile && yyactr(next_state))
goto abort;
/* consult goto table to find next state */
i = yyr1[next_state];
i = yypgo[i];
act = &yygo[i];
next_state = *yyps;
for ( ; *act != next_state && *act >= 0; act += 2)
continue;
state = act[1];
goto stack; /* stack new state and value */
case ACCEPT:
return (0);
case ERROR: /* attempt to resume parsing */
switch (errorflag)
{
case 0: /* brand new syntax error */
rc_error(0);
case 1: /* incompletely recovered error, try again */
errorflag = 2;
/* find a state where "error" is a legal SHIFT */
while (yyps >= states)
{
/* search yyps actions */
i = *yyps;
i = yypact[i + 1];
act = &yyact[i];
for ( ; OPERATION(*act) == SKIP; act += 2)
if (*act == SHIFT_ON_ERROR)
goto found;
/* the current yyps has no shift */
/* on "error", pop stack */
# ifdef RC_TRACE
if (TR_PARSE)
{
printf("ERROR recovery poyyps state %d",
yyps[0]);
printf(", uncovers %d\n", yyps[-1]);
}
# endif
yyps--;
yypv--;
}
/* there is no state on the stack */
/* with an error shift ... abort */
abort:
return (1);
found: /* we have a state with a shift on "error", resume parsing */
state = act[1] & 07777;
goto stack;
case 2: /* no shift yet; clobber input char */
# ifdef RC_TRACE
if (TR_PARSE)
printf("err recov discards char %d\n", token);
# endif
/* don't discard EOF; quit */
if (!token)
goto abort;
token = -1;
goto new_state; /* try again in the same state */
}
}
return (1);
}