|
|
researchv10 Norman
#include <stdio.h>
#include <ctype.h>
#include "pico.h"
#include "y.tab.h"
#define Prompt2 /* if (INPUT == stdin) fprintf(stderr, ":%d ", pline) */
extern FILE *INPUT;
Symbol *whichcmd(), *lookup(), *getname();
char *getstring();
int linenumber = 1;
int pline = 0;
int lexlast = -1;
int LO = -1;
char lastyy = '\n';
char nolf = 1;
char nesting = 0;
char operator = 0;
char lastdepth = 0;
/*
* if the last token seen was not an operator the next
* newline will be interpreted as a statement separator
*/
#define ADDEQ 210
#define SUBEQ 211
#define MULEQ 212
#define DIVEQ 213
#define MODEQ 214
#define INC 215
#define DEC 216
yylex()
{ int c;
while ((c = ylexlex()) == SCOM)
{ do c = ylexlex();
while (c != ECOM);
}
/* fprintf(stderr, "lex: %d [[%c]]\n", c, (isalnum(c))?c:'-');/* */
switch (c) {
case '+': case '-': case '*':
case '/': case '%': case '^':
case POW: case GT: case GE:
case LT: case LE: case EQ:
case NE: case ANDAND: case OROR:
case OR: case AND: case LSH:
case RSH: case ',': case NOT:
case '~': case '?': case ':':
case ASSIGN: case '(': case '[':
operator = 1;
break;
case ADDEQ: operator = 1; LO = OADD; return OPER;
case SUBEQ: operator = 1; LO = OSUB; return OPER;
case MULEQ: operator = 1; LO = OMUL; return OPER;
case DIVEQ: operator = 1; LO = DIVV; return OPER;
case MODEQ: operator = 1; LO = MODU; return OPER;
case INC: operator = 0; LO = OADD; return POST;
case DEC: operator = 0; LO = OSUB; return POST;
default:
operator = 0;
break;
}
return c;
}
ylexlex()
{ int c;
again: switch (c = getc(INPUT)) {
case EOF: undirect(); checkit();
case ' ':
case 27:
case '\t': goto again;
case '\\': if ((c = getc(INPUT)) == '\n')
goto again;
else
break;
case '\n': if (nesting > 0 && (operator || lastyy == '\n'))
{ Prompt2;
pline++;
goto again;
}
default : break;
}
nolf = (c != '\n');
if (c == '\"')
{ yylval.resu = (int) getstring();
lastyy = '\0';
return STRING;
}
if (isdigit(c))
{ lexlast = 0;
do
{ lexlast = lexlast*10 + c - '0';
c = getc(INPUT);
} while (isdigit(c));
ungetc(c, INPUT);
lastyy = '\0';
yylval.resu = lexlast;
return VAL;
}
if (isalpha(c) || c == '_')
{ yylval.sym = getname(c);
lastyy = '\0';
return yylval.sym->type;
}
lastyy = '\0';
switch (c) {
case '{' : if (++nesting == 1) pline = 1; lastyy = '\n'; return OPEN;
case '}' : sympurge();
if (nesting-- == 1) pline = 0;
else ungetc(';', INPUT);
return CLOSE;
case '/' : return follow('=', DIVEQ, follow('*', SCOM, '/'));
case '%' : return follow('=', MODEQ, '%');
case '+' : return follow('+', INC, follow('=', ADDEQ, '+'));
case '-' : return follow('-', DEC, follow('=', SUBEQ, '-'));
case '*' : return follow('*', POW, follow('=',MULEQ, follow('/',ECOM,'*')));
case '>' : return follow('=', GE, follow('>', RSH, GT));
case '<' : return follow('=', LE, follow('<', LSH, LT));
case '=' : return follow('=', EQ, ASSIGN);
case '!' : return follow('=', NE, NOT);
case '|' : return follow('|', OROR, OR);
case '&' : return follow('&', ANDAND, AND);
case '\n': if (nesting == 0)
linenumber++; /* fall through */
else
{ Prompt2;
pline++;
}
case ';' : lastyy = '\n';
return ';';
default : return c;
}
}
follow(expect, ifyes, ifno)
{
int c = getc(INPUT);
if (c == expect)
return ifyes;
ungetc(c, INPUT);
return ifno;
}
Symbol *
getname(cc)
char cc;
{ char c=cc, sbuf[128], *p = sbuf;
do
{ if (p >= sbuf + sizeof(sbuf) - 1)
{ *p = '\0';
yyerror("name too long: %s", sbuf);
}
*p++ = c;
} while ((c=getc(INPUT)) != EOF && (isalnum(c) || c == '_'));
ungetc(c, INPUT);
*p = '\0';
if (nesting == 0 && lastyy == '\n')
return whichcmd(sbuf);
else
return lookup(sbuf);
}
char *
getstring()
{ char c, *sbuf, *p;
sbuf = (char *) Emalloc(512);
p = sbuf;
while ((c=getc(INPUT)) != EOF && c != '\"')
{ if (c == '\\')
c = follow('n', '\n', follow('t', '\t', '\\'));
*p++ = c;
if (p >= sbuf + 512 - 1)
{ *p = '\0';
yyerror("string too long: %s", sbuf);
}
} ;
*p = '\0';
return sbuf;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.