xref: /csrg-svn/usr.bin/pascal/src/yylex.c (revision 7952)
1787Speter /* Copyright (c) 1979 Regents of the University of California */
2787Speter 
3*7952Speter static char sccsid[] = "@(#)yylex.c 1.3 08/29/82";
4787Speter 
5787Speter #include "whoami.h"
6787Speter #include "0.h"
7787Speter #include "yy.h"
8787Speter 
9787Speter /*
10787Speter  * Scanner
11787Speter  */
12787Speter int	yylacnt;
13787Speter 
14787Speter #define	YYLASIZ	10
15787Speter 
16787Speter struct	yytok Yla[YYLASIZ];
17787Speter 
18787Speter unyylex(y)
19787Speter 	struct yylex *y;
20787Speter {
21787Speter 
22787Speter 	if (yylacnt == YYLASIZ)
23787Speter 		panic("unyylex");
24787Speter 	copy(&Yla[yylacnt], y, sizeof Yla[0]);
25787Speter 	yylacnt++;
26787Speter 
27787Speter }
28787Speter 
29787Speter yylex()
30787Speter {
31787Speter 	register c;
32787Speter 	register **ip;
33787Speter 	register char *cp;
34787Speter 	int f;
35787Speter 	char delim;
36787Speter 
37787Speter 	if (yylacnt != 0) {
38787Speter 		yylacnt--;
39787Speter 		copy(&Y, &Yla[yylacnt], sizeof Y);
40787Speter 		return (yychar);
41787Speter 	}
42787Speter 	if (c = yysavc)
43787Speter 		yysavc = 0;
44787Speter 	else
45787Speter 		c = readch();
46787Speter #ifdef PXP
47787Speter 	yytokcnt++;
48787Speter #endif
49787Speter 
50787Speter next:
51787Speter 	/*
52787Speter 	 * skip white space
53787Speter 	 */
54787Speter #ifdef PXP
55787Speter 	yywhcnt = 0;
56787Speter #endif
57787Speter 	while (c == ' ' || c == '\t') {
58787Speter #ifdef PXP
59787Speter 		if (c == '\t')
60787Speter 			yywhcnt++;
61787Speter 		yywhcnt++;
62787Speter #endif
63787Speter 		c = readch();
64787Speter 	}
65787Speter 	yyecol = yycol;
66787Speter 	yyeline = yyline;
67787Speter 	yyefile = filename;
68787Speter 	yyeseqid = yyseqid;
69787Speter 	yyseekp = yylinpt;
70787Speter 	cp = token;
71787Speter 	yylval = yyline;
72787Speter 	switch (c) {
73787Speter 		case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
74787Speter 		case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
75787Speter 		case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
76787Speter 		case 'v': case 'w': case 'x': case 'y': case 'z':
77787Speter 		case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
78787Speter 		case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
79787Speter 		case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
80787Speter 		case 'V': case 'W': case 'X': case 'Y': case 'Z':
81787Speter 			do {
82787Speter 				*cp++ = c;
83787Speter 				c = readch();
84787Speter 			} while (alph(c) || digit(c));
85787Speter 			*cp = 0;
86787Speter 			if (opt('s'))
87787Speter 				for (cp = token; *cp; cp++)
88787Speter 					if (*cp >= 'A' && *cp <= 'Z') {
893086Smckusic 						*cp |= ' ';
90787Speter 					}
91787Speter 			yysavc = c;
92787Speter 			ip = hash(0, 1);
93787Speter 			if (*ip < yykey || *ip >= lastkey) {
94787Speter 				yylval = *ip;
95787Speter 				return (YID);
96787Speter 			}
97787Speter 			yylval = yyline;
98787Speter 			/*
99787Speter 			 * For keywords
100787Speter 			 * the lexical token
101787Speter 			 * is magically retrieved
102787Speter 			 * from the keyword table.
103787Speter 			 */
104787Speter 			return ((*ip)[1]);
105787Speter 		case '0': case '1': case '2': case '3': case '4':
106787Speter 		case '5': case '6': case '7': case '8': case '9':
107787Speter 			f = 0;
108787Speter 			do {
109787Speter 				*cp++ = c;
110787Speter 				c = readch();
111787Speter 			} while (digit(c));
112787Speter 			if (c == 'b' || c == 'B') {
113787Speter 				/*
114787Speter 				 * nonstandard - octal constants
115787Speter 				 */
116787Speter 				if (opt('s')) {
117787Speter 					standard();
118787Speter 					yerror("Octal constants are non-standard");
119787Speter 				}
120787Speter 				*cp = 0;
121787Speter 				yylval = copystr(token);
122787Speter 				return (YBINT);
123787Speter 			}
124787Speter 			if (c == '.') {
125787Speter 				c = readch();
126787Speter 				if (c == '.') {
127787Speter 					*cp = 0;
128787Speter 					yysavc = YDOTDOT;
129787Speter 					yylval = copystr(token);
130787Speter 					return (YINT);
131787Speter 				}
132787Speter infpnumb:
133787Speter 				f++;
134787Speter 				*cp++ = '.';
135787Speter 				if (!digit(c)) {
136787Speter 					yyset();
137787Speter 					recovered();
138787Speter 					yerror("Digits required after decimal point");
139787Speter 					*cp++ = '0';
140787Speter 				} else
141787Speter 					while (digit(c)) {
142787Speter 						*cp++ = c;
143787Speter 						c = readch();
144787Speter 					}
145787Speter 			}
146787Speter 			if (c == 'e' || c == 'E') {
147787Speter 				f++;
148787Speter 				*cp++ = c;
149787Speter 				if ((c = yysavc) == 0)
150787Speter 					c = readch();
151787Speter 				if (c == '+' || c == '-') {
152787Speter 					*cp++ = c;
153787Speter 					c = readch();
154787Speter 				}
155787Speter 				if (!digit(c)) {
156787Speter 					yyset();
157787Speter 					yerror("Digits required in exponent");
158787Speter 					*cp++ = '0';
159787Speter 				} else
160787Speter 					while (digit(c)) {
161787Speter 						*cp++ = c;
162787Speter 						c = readch();
163787Speter 					}
164787Speter 			}
165787Speter 			*cp = 0;
166787Speter 			yysavc = c;
167787Speter 			yylval = copystr(token);
168787Speter 			if (f)
169787Speter 				return (YNUMB);
170787Speter 			return (YINT);
171787Speter 		case '"':
172787Speter 		case '`':
173*7952Speter 		case '#':
174787Speter 			if (!any(bufp + 1, c))
175787Speter 				goto illch;
176787Speter 			if (!dquote) {
177787Speter 				recovered();
178787Speter 				dquote++;
179787Speter 				yerror("Character/string delimiter is '");
180787Speter 			}
181787Speter 		case '\'':
182787Speter 			delim = c;
183787Speter 			do {
184787Speter 				do {
185787Speter 					c = readch();
186787Speter 					if (c == '\n') {
187787Speter 						yerror("Unmatched %c for string", delim);
188787Speter 						if (cp == token)
189787Speter 							*cp++ = ' ', cp++;
190787Speter 						break;
191787Speter 					}
192787Speter 					*cp++ = c;
193787Speter 				} while (c != delim);
194787Speter 				c = readch();
195787Speter 			} while (c == delim);
196787Speter 			*--cp = 0;
197787Speter 			if (cp == token) {
198787Speter 				yerror("Null string not allowed");
199787Speter 				*cp++ = ' ';
200787Speter 				*cp++ = 0;
201787Speter 			}
202787Speter 			yysavc = c;
203787Speter 			yylval = copystr(token);
204787Speter 			return (YSTRING);
205787Speter 		case '.':
206787Speter 			c = readch();
207787Speter 			if (c == '.')
208787Speter 				return (YDOTDOT);
209787Speter 			if (digit(c)) {
210787Speter 				recovered();
211787Speter 				yerror("Digits required before decimal point");
212787Speter 				*cp++ = '0';
213787Speter 				goto infpnumb;
214787Speter 			}
215787Speter 			yysavc = c;
216787Speter 			return ('.');
217787Speter 		case '{':
218787Speter 			/*
219787Speter 			 * { ... } comment
220787Speter 			 */
221787Speter #ifdef PXP
222787Speter 			getcm(c);
223787Speter #endif
224787Speter #ifdef PI
225787Speter 			c = options();
226787Speter 			while (c != '}') {
227787Speter 				if (c <= 0)
228787Speter 					goto nonterm;
229787Speter 				if (c == '{') {
230787Speter 					warning();
231787Speter 					yyset();
232787Speter 					yerror("{ in a { ... } comment");
233787Speter 				}
234787Speter 				c = readch();
235787Speter 			}
236787Speter #endif
237787Speter 			c = readch();
238787Speter 			goto next;
239787Speter 		case '(':
240787Speter 			if ((c = readch()) == '*') {
241787Speter 				/*
242787Speter 				 * (* ... *) comment
243787Speter 				 */
244787Speter #ifdef PXP
245787Speter 				getcm(c);
246787Speter 				c = readch();
247787Speter 				goto next;
248787Speter #endif
249787Speter #ifdef PI
250787Speter 				c = options();
251787Speter 				for (;;) {
252787Speter 					if (c < 0) {
253787Speter nonterm:
254787Speter 						yerror("Comment does not terminate - QUIT");
255787Speter 						pexit(ERRS);
256787Speter 					}
257787Speter 					if (c == '(' && (c = readch()) == '*') {
258787Speter 						warning();
259787Speter 						yyset();
260787Speter 						yerror("(* in a (* ... *) comment");
261787Speter 					}
262787Speter 					if (c == '*') {
263787Speter 						if ((c = readch()) != ')')
264787Speter 							continue;
265787Speter 						c = readch();
266787Speter 						goto next;
267787Speter 					}
268787Speter 					c = readch();
269787Speter 				}
270787Speter #endif
271787Speter 			}
272787Speter 			yysavc = c;
273787Speter 			c = '(';
274787Speter 		case ';':
275787Speter 		case ',':
276787Speter 		case ':':
277787Speter 		case '=':
278787Speter 		case '*':
279787Speter 		case '+':
280787Speter 		case '/':
281787Speter 		case '-':
282787Speter 		case ')':
283787Speter 		case '[':
284787Speter 		case ']':
285787Speter 		case '<':
286787Speter 		case '>':
287787Speter 		case '^':
288787Speter 			return (c);
289*7952Speter 		case '~':
290*7952Speter 		case '|':
291*7952Speter 		case '&':
292*7952Speter 			if ( opt('s') ) {
293*7952Speter 			    yyset();
294*7952Speter 			    standard();
295*7952Speter 			    yerror("%c is non-standard", c);
296*7952Speter 			}
297*7952Speter 			return c;
298787Speter 		default:
299787Speter 			switch (c) {
300787Speter 				case YDOTDOT:
301787Speter 					return (c);
302787Speter 				case '\n':
303787Speter 					c = readch();
304787Speter #ifdef PXP
305787Speter 					yytokcnt++;
306787Speter #endif
307787Speter 					goto next;
308787Speter 				case '\f':
309787Speter 					c = readch();
310787Speter 					goto next;
311787Speter 			}
312787Speter 			if (c <= 0)
313787Speter 				return (YEOF);
314787Speter illch:
315787Speter 			do
316787Speter 				yysavc = readch();
317787Speter 			while (yysavc == c);
318787Speter 			yylval = c;
319787Speter 			return (YILLCH);
320787Speter 	}
321787Speter }
322787Speter 
323787Speter yyset()
324787Speter {
325787Speter 
326787Speter 	yyecol = yycol;
327787Speter 	yyeline = yyline;
328787Speter 	yyefile = filename;
329787Speter 	yyseekp = yylinpt;
330787Speter }
331787Speter 
332787Speter /*
333787Speter  * Setuflg trims the current
334787Speter  * input line to at most 72 chars
335787Speter  * for the u option.
336787Speter  */
337787Speter setuflg()
338787Speter {
339787Speter 
340787Speter 	if (charbuf[71] != '\n') {
341787Speter 		charbuf[72] = '\n';
342787Speter 		charbuf[73] = 0;
343787Speter 	}
344787Speter }
345