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