version 1.10, 2008/06/04 14:04:42 |
version 1.11, 2008/10/06 20:38:33 |
|
|
{ "xor", FXOR, BLTIN }, |
{ "xor", FXOR, BLTIN }, |
}; |
}; |
|
|
#define DEBUG |
|
#ifdef DEBUG |
|
#define RET(x) { if(dbg)printf("lex %s\n", tokname(x)); return(x); } |
#define RET(x) { if(dbg)printf("lex %s\n", tokname(x)); return(x); } |
#else |
|
#define RET(x) return(x) |
|
#endif |
|
|
|
int peek(void); |
int peek(void); |
int gettok(char **, int *); |
int gettok(char **, int *); |
|
|
if (isalpha(c) || c == '_') { /* it's a varname */ |
if (isalpha(c) || c == '_') { /* it's a varname */ |
for ( ; (c = input()) != 0; ) { |
for ( ; (c = input()) != 0; ) { |
if (bp-buf >= sz) |
if (bp-buf >= sz) |
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, 0)) |
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, "gettok")) |
FATAL( "out of space for name %.10s...", buf ); |
FATAL( "out of space for name %.10s...", buf ); |
if (isalnum(c) || c == '_') |
if (isalnum(c) || c == '_') |
*bp++ = c; |
*bp++ = c; |
|
|
} |
} |
*bp = 0; |
*bp = 0; |
retc = 'a'; /* alphanumeric */ |
retc = 'a'; /* alphanumeric */ |
} else { /* it's a number */ |
} else { /* maybe it's a number, but could be . */ |
char *rem; |
char *rem; |
/* read input until can't be a number */ |
/* read input until can't be a number */ |
for ( ; (c = input()) != 0; ) { |
for ( ; (c = input()) != 0; ) { |
if (bp-buf >= sz) |
if (bp-buf >= sz) |
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, 0)) |
if (!adjbuf(&buf, &sz, bp-buf+2, 100, &bp, "gettok")) |
FATAL( "out of space for number %.10s...", buf ); |
FATAL( "out of space for number %.10s...", buf ); |
if (isdigit(c) || c == 'e' || c == 'E' |
if (isdigit(c) || c == 'e' || c == 'E' |
|| c == '.' || c == '+' || c == '-') |
|| c == '.' || c == '+' || c == '-') |
|
|
} |
} |
*bp = 0; |
*bp = 0; |
strtod(buf, &rem); /* parse the number */ |
strtod(buf, &rem); /* parse the number */ |
unputstr(rem); /* put rest back for later */ |
|
/* printf("unputstr [%s], buf [%s]\n", rem, buf); */ |
|
if (rem == buf) { /* it wasn't a valid number at all */ |
if (rem == buf) { /* it wasn't a valid number at all */ |
buf[1] = 0; /* so return one character as token */ |
buf[1] = 0; /* return one character as token */ |
retc = buf[0]; /* character is its own type */ |
retc = buf[0]; /* character is its own type */ |
|
unputstr(rem+1); /* put rest back for later */ |
} else { /* some prefix was a number */ |
} else { /* some prefix was a number */ |
rem[0] = 0; /* so truncate where failure started */ |
unputstr(rem); /* put rest back for later */ |
retc = '0'; /* number */ |
rem[0] = 0; /* truncate buf after number part */ |
|
retc = '0'; /* type is number */ |
} |
} |
} |
} |
*pbuf = buf; |
*pbuf = buf; |
|
|
{ |
{ |
int c; |
int c; |
static char *buf = 0; |
static char *buf = 0; |
static int bufsize = 500; |
static int bufsize = 5; /* BUG: setting this small causes core dump! */ |
|
|
if (buf == 0 && (buf = (char *) malloc(bufsize)) == NULL) |
if (buf == 0 && (buf = (char *) malloc(bufsize)) == NULL) |
FATAL( "out of space in yylex" ); |
FATAL( "out of space in yylex" ); |
|
|
reg = 0; |
reg = 0; |
return regexpr(); |
return regexpr(); |
} |
} |
/* printf("top\n"); */ |
|
for (;;) { |
for (;;) { |
c = gettok(&buf, &bufsize); |
c = gettok(&buf, &bufsize); |
/* printf("gettok [%s]\n", buf); */ |
|
if (c == 0) |
if (c == 0) |
return 0; |
return 0; |
if (isalpha(c) || c == '_') |
if (isalpha(c) || c == '_') |
|
|
if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL) |
if (buf == 0 && (buf = (char *) malloc(bufsz)) == NULL) |
FATAL("out of space for strings"); |
FATAL("out of space for strings"); |
for (bp = buf; (c = input()) != '"'; ) { |
for (bp = buf; (c = input()) != '"'; ) { |
if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, 0)) |
if (!adjbuf(&buf, &bufsz, bp-buf+2, 500, &bp, "string")) |
FATAL("out of space for string %.10s...", buf); |
FATAL("out of space for string %.10s...", buf); |
switch (c) { |
switch (c) { |
case '\n': |
case '\n': |
|
|
int c, n; |
int c, n; |
|
|
n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0])); |
n = binsearch(w, keywords, sizeof(keywords)/sizeof(keywords[0])); |
|
/* BUG: this ought to be inside the if; in theory could fault (daniel barrett) */ |
kp = keywords + n; |
kp = keywords + n; |
if (n != -1) { /* found in table */ |
if (n != -1) { /* found in table */ |
yylval.i = kp->sub; |
yylval.i = kp->sub; |
switch (kp->type) { /* special handling */ |
switch (kp->type) { /* special handling */ |
case FSYSTEM: |
case BLTIN: |
if (safe) |
if (kp->sub == FSYSTEM && safe) |
SYNTAX( "system is unsafe" ); |
SYNTAX( "system is unsafe" ); |
RET(kp->type); |
RET(kp->type); |
case FUNC: |
case FUNC: |
|
|
FATAL("out of space for rex expr"); |
FATAL("out of space for rex expr"); |
bp = buf; |
bp = buf; |
for ( ; ((c = input()) != '/' || openclass == 1) && c != 0; ) { |
for ( ; ((c = input()) != '/' || openclass == 1) && c != 0; ) { |
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, 0)) |
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr")) |
FATAL("out of space for reg expr %.10s...", buf); |
FATAL("out of space for reg expr %.10s...", buf); |
if (c == '\n') { |
if (c == '\n') { |
SYNTAX( "newline in regular expression %.10s...", buf ); |
SYNTAX( "newline in regular expression %.10s...", buf ); |