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