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