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