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