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