|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)yylex.c 1.1 8/27/80";
4:
5: #include "whoami.h"
6: #include "0.h"
7: #include "yy.h"
8:
9: /*
10: * Scanner
11: */
12: int yylacnt;
13:
14: #define YYLASIZ 10
15:
16: struct yytok Yla[YYLASIZ];
17:
18: unyylex(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:
29: yylex()
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:
50: next:
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: }
132: infpnumb:
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) {
253: nonterm:
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);
308: illch:
309: do
310: yysavc = readch();
311: while (yysavc == c);
312: yylval = c;
313: return (YILLCH);
314: }
315: }
316:
317: yyset()
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: */
331: setuflg()
332: {
333:
334: if (charbuf[71] != '\n') {
335: charbuf[72] = '\n';
336: charbuf[73] = 0;
337: }
338: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.