|
|
1.1 root 1: #include <stdio.h>
2: #include <ctype.h>
3: #include "pico.h"
4: #include "y.tab.h"
5:
6: #define Prompt2 /* if (INPUT == stdin) fprintf(stderr, ":%d ", pline) */
7:
8: extern FILE *INPUT;
9:
10: Symbol *whichcmd(), *lookup(), *getname();
11: char *getstring();
12:
13: int linenumber = 1;
14: int pline = 0;
15: int lexlast = -1;
16: int LO = -1;
17: char lastyy = '\n';
18: char nolf = 1;
19: char nesting = 0;
20: char operator = 0;
21: char lastdepth = 0;
22:
23: /*
24: * if the last token seen was not an operator the next
25: * newline will be interpreted as a statement separator
26: */
27:
28: #define ADDEQ 210
29: #define SUBEQ 211
30: #define MULEQ 212
31: #define DIVEQ 213
32: #define MODEQ 214
33: #define INC 215
34: #define DEC 216
35:
36: yylex()
37: { int c;
38: while ((c = ylexlex()) == SCOM)
39: { do c = ylexlex();
40: while (c != ECOM);
41: }
42: /* fprintf(stderr, "lex: %d [[%c]]\n", c, (isalnum(c))?c:'-');/* */
43: switch (c) {
44: case '+': case '-': case '*':
45: case '/': case '%': case '^':
46: case POW: case GT: case GE:
47: case LT: case LE: case EQ:
48: case NE: case ANDAND: case OROR:
49: case OR: case AND: case LSH:
50: case RSH: case ',': case NOT:
51: case '~': case '?': case ':':
52: case ASSIGN: case '(': case '[':
53: operator = 1;
54: break;
55: case ADDEQ: operator = 1; LO = OADD; return OPER;
56: case SUBEQ: operator = 1; LO = OSUB; return OPER;
57: case MULEQ: operator = 1; LO = OMUL; return OPER;
58: case DIVEQ: operator = 1; LO = DIVV; return OPER;
59: case MODEQ: operator = 1; LO = MODU; return OPER;
60: case INC: operator = 0; LO = OADD; return POST;
61: case DEC: operator = 0; LO = OSUB; return POST;
62: default:
63: operator = 0;
64: break;
65: }
66: return c;
67: }
68:
69: ylexlex()
70: { int c;
71:
72: again: switch (c = getc(INPUT)) {
73: case EOF: undirect(); checkit();
74: case ' ':
75: case 27:
76: case '\t': goto again;
77:
78: case '\\': if ((c = getc(INPUT)) == '\n')
79: goto again;
80: else
81: break;
82: case '\n': if (nesting > 0 && (operator || lastyy == '\n'))
83: { Prompt2;
84: pline++;
85: goto again;
86: }
87: default : break;
88: }
89:
90: nolf = (c != '\n');
91:
92: if (c == '\"')
93: { yylval.resu = (int) getstring();
94: lastyy = '\0';
95: return STRING;
96: }
97: if (isdigit(c))
98: { lexlast = 0;
99: do
100: { lexlast = lexlast*10 + c - '0';
101: c = getc(INPUT);
102: } while (isdigit(c));
103: ungetc(c, INPUT);
104: lastyy = '\0';
105:
106: yylval.resu = lexlast;
107: return VAL;
108: }
109:
110: if (isalpha(c) || c == '_')
111: { yylval.sym = getname(c);
112: lastyy = '\0';
113: return yylval.sym->type;
114: }
115:
116: lastyy = '\0';
117: switch (c) {
118: case '{' : if (++nesting == 1) pline = 1; lastyy = '\n'; return OPEN;
119: case '}' : sympurge();
120: if (nesting-- == 1) pline = 0;
121: else ungetc(';', INPUT);
122: return CLOSE;
123: case '/' : return follow('=', DIVEQ, follow('*', SCOM, '/'));
124: case '%' : return follow('=', MODEQ, '%');
125: case '+' : return follow('+', INC, follow('=', ADDEQ, '+'));
126: case '-' : return follow('-', DEC, follow('=', SUBEQ, '-'));
127: case '*' : return follow('*', POW, follow('=',MULEQ, follow('/',ECOM,'*')));
128: case '>' : return follow('=', GE, follow('>', RSH, GT));
129: case '<' : return follow('=', LE, follow('<', LSH, LT));
130: case '=' : return follow('=', EQ, ASSIGN);
131: case '!' : return follow('=', NE, NOT);
132: case '|' : return follow('|', OROR, OR);
133: case '&' : return follow('&', ANDAND, AND);
134: case '\n': if (nesting == 0)
135: linenumber++; /* fall through */
136: else
137: { Prompt2;
138: pline++;
139: }
140: case ';' : lastyy = '\n';
141: return ';';
142: default : return c;
143: }
144: }
145:
146: follow(expect, ifyes, ifno)
147: {
148: int c = getc(INPUT);
149:
150: if (c == expect)
151: return ifyes;
152:
153: ungetc(c, INPUT);
154: return ifno;
155: }
156:
157: Symbol *
158: getname(cc)
159: char cc;
160: { char c=cc, sbuf[128], *p = sbuf;
161:
162: do
163: { if (p >= sbuf + sizeof(sbuf) - 1)
164: { *p = '\0';
165: yyerror("name too long: %s", sbuf);
166: }
167: *p++ = c;
168: } while ((c=getc(INPUT)) != EOF && (isalnum(c) || c == '_'));
169: ungetc(c, INPUT);
170: *p = '\0';
171:
172: if (nesting == 0 && lastyy == '\n')
173: return whichcmd(sbuf);
174: else
175: return lookup(sbuf);
176: }
177:
178: char *
179: getstring()
180: { char c, *sbuf, *p;
181: sbuf = (char *) Emalloc(512);
182: p = sbuf;
183:
184: while ((c=getc(INPUT)) != EOF && c != '\"')
185: { if (c == '\\')
186: c = follow('n', '\n', follow('t', '\t', '\\'));
187: *p++ = c;
188: if (p >= sbuf + 512 - 1)
189: { *p = '\0';
190: yyerror("string too long: %s", sbuf);
191: }
192: } ;
193: *p = '\0';
194:
195: return sbuf;
196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.