BSD 3 development
[unix-history] / usr / src / cmd / pi / yylex.c
CommitLineData
58ac8f52
CH
1/* Copyright (c) 1979 Regents of the University of California */
2#
3/*
4 * pi - Pascal interpreter code translator
5 *
6 * Charles Haley, Bill Joy UCB
7 * Version 1.2 November 1978
8 *
9 *
10 * pxp - Pascal execution profiler
11 *
12 * Bill Joy UCB
13 * Version 1.2 November 1978
14 */
15
16#include "whoami"
17#include "0.h"
18#include "yy.h"
19
20/*
21 * Scanner
22 */
23int yylacnt;
24
25#define YYLASIZ 10
26
27struct yytok Yla[YYLASIZ];
28
29unyylex(y)
30 struct yylex *y;
31{
32
33 if (yylacnt == YYLASIZ)
34 panic("unyylex");
35 copy(&Yla[yylacnt], y, sizeof Yla[0]);
36 yylacnt++;
37
38}
39
40yylex()
41{
42 register c;
43 register **ip;
44 register char *cp;
45 int f;
46 char delim;
47
48 if (yylacnt != 0) {
49 yylacnt--;
50 copy(&Y, &Yla[yylacnt], sizeof Y);
51 return (yychar);
52 }
53 if (c = yysavc)
54 yysavc = 0;
55 else
56 c = readch();
57#ifdef PXP
58 yytokcnt++;
59#endif
60
61next:
62 /*
63 * skip white space
64 */
65#ifdef PXP
66 yywhcnt = 0;
67#endif
68 while (c == ' ' || c == '\t') {
69#ifdef PXP
70 if (c == '\t')
71 yywhcnt++;
72 yywhcnt++;
73#endif
74 c = readch();
75 }
76 yyecol = yycol;
77 yyeline = yyline;
78 yyefile = filename;
79 yyeseqid = yyseqid;
80 yyseekp = yylinpt;
81 cp = token;
82 yylval = yyline;
83 switch (c) {
84 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
85 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
86 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
87 case 'v': case 'w': case 'x': case 'y': case 'z':
88 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
89 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
90 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
91 case 'V': case 'W': case 'X': case 'Y': case 'Z':
92 do {
93 *cp++ = c;
94 c = readch();
95 } while (alph(c) || digit(c));
96 *cp = 0;
97 if (opt('s'))
98 for (cp = token; *cp; cp++)
99 if (*cp >= 'A' && *cp <= 'Z') {
100 *cp =| ' ';
101 }
102 yysavc = c;
103 ip = hash(0, 1);
104 if (*ip < yykey || *ip >= lastkey) {
105 yylval = *ip;
106 return (YID);
107 }
108 yylval = yyline;
109 /*
110 * For keywords
111 * the lexical token
112 * is magically retrieved
113 * from the keyword table.
114 */
115 return ((*ip)[1]);
116 case '0': case '1': case '2': case '3': case '4':
117 case '5': case '6': case '7': case '8': case '9':
118 f = 0;
119 do {
120 *cp++ = c;
121 c = readch();
122 } while (digit(c));
123 if (c == 'b' || c == 'B') {
124 /*
125 * nonstandard - octal constants
126 */
127 if (opt('s')) {
128 standard();
129 yerror("Octal constants are non-standard");
130 }
131 *cp = 0;
132 yylval = copystr(token);
133 return (YBINT);
134 }
135 if (c == '.') {
136 c = readch();
137 if (c == '.') {
138 *cp = 0;
139 yysavc = YDOTDOT;
140 yylval = copystr(token);
141 return (YINT);
142 }
143infpnumb:
144 f++;
145 *cp++ = '.';
146 if (!digit(c)) {
147 yyset();
148 recovered();
149 yerror("Digits required after decimal point");
150 *cp++ = '0';
151 } else
152 while (digit(c)) {
153 *cp++ = c;
154 c = readch();
155 }
156 }
157 if (c == 'e' || c == 'E') {
158 f++;
159 *cp++ = c;
160 if ((c = yysavc) == 0)
161 c = readch();
162 if (c == '+' || c == '-') {
163 *cp++ = c;
164 c = readch();
165 }
166 if (!digit(c)) {
167 yyset();
168 yerror("Digits required in exponent");
169 *cp++ = '0';
170 } else
171 while (digit(c)) {
172 *cp++ = c;
173 c = readch();
174 }
175 }
176 *cp = 0;
177 yysavc = c;
178 yylval = copystr(token);
179 if (f)
180 return (YNUMB);
181 return (YINT);
182 case '"':
183 case '`':
184 if (!any(bufp + 1, c))
185 goto illch;
186 if (!dquote) {
187 recovered();
188 dquote++;
189 yerror("Character/string delimiter is '");
190 }
191 case '\'':
192 case '#':
193 delim = c;
194 do {
195 do {
196 c = readch();
197 if (c == '\n') {
198 yerror("Unmatched %c for string", delim);
199 if (cp == token)
200 *cp++ = ' ', cp++;
201 break;
202 }
203 *cp++ = c;
204 } while (c != delim);
205 c = readch();
206 } while (c == delim);
207 *--cp = 0;
208 if (cp == token) {
209 yerror("Null string not allowed");
210 *cp++ = ' ';
211 *cp++ = 0;
212 }
213 yysavc = c;
214 yylval = copystr(token);
215 return (YSTRING);
216 case '.':
217 c = readch();
218 if (c == '.')
219 return (YDOTDOT);
220 if (digit(c)) {
221 recovered();
222 yerror("Digits required before decimal point");
223 *cp++ = '0';
224 goto infpnumb;
225 }
226 yysavc = c;
227 return ('.');
228 case '{':
229 /*
230 * { ... } comment
231 */
232#ifdef PXP
233 getcm(c);
234#endif
235#ifdef PI
236 c = options();
237 while (c != '}') {
238 if (c <= 0)
239 goto nonterm;
240 if (c == '{') {
241 warning();
242 yyset();
243 yerror("{ in a { ... } comment");
244 }
245 c = readch();
246 }
247#endif
248 c = readch();
249 goto next;
250 case '(':
251 if ((c = readch()) == '*') {
252 /*
253 * (* ... *) comment
254 */
255#ifdef PXP
256 getcm(c);
257 c = readch();
258 goto next;
259#endif
260#ifdef PI
261 c = options();
262 for (;;) {
263 if (c < 0) {
264nonterm:
265 yerror("Comment does not terminate - QUIT");
266 pexit(ERRS);
267 }
268 if (c == '(' && (c = readch()) == '*') {
269 warning();
270 yyset();
271 yerror("(* in a (* ... *) comment");
272 }
273 if (c == '*') {
274 if ((c = readch()) != ')')
275 continue;
276 c = readch();
277 goto next;
278 }
279 c = readch();
280 }
281#endif
282 }
283 yysavc = c;
284 c = '(';
285 case ';':
286 case ',':
287 case ':':
288 case '=':
289 case '*':
290 case '+':
291 case '/':
292 case '-':
293 case '|':
294 case '&':
295 case ')':
296 case '[':
297 case ']':
298 case '<':
299 case '>':
300 case '~':
301 case '^':
302 return (c);
303 default:
304 switch (c) {
305 case YDOTDOT:
306 return (c);
307 case '\n':
308 c = readch();
309#ifdef PXP
310 yytokcnt++;
311#endif
312 goto next;
313 case '\f':
314 c = readch();
315 goto next;
316 }
317 if (c <= 0)
318 return (YEOF);
319illch:
320 do
321 yysavc = readch();
322 while (yysavc == c);
323 yylval = c;
324 return (YILLCH);
325 }
326}
327
328yyset()
329{
330
331 yyecol = yycol;
332 yyeline = yyline;
333 yyefile = filename;
334 yyseekp = yylinpt;
335}
336
337/*
338 * Setuflg trims the current
339 * input line to at most 72 chars
340 * for the u option.
341 */
342setuflg()
343{
344
345 if (charbuf[71] != '\n') {
346 charbuf[72] = '\n';
347 charbuf[73] = 0;
348 }
349}