xref: /original-bsd/usr.bin/pascal/src/yylex.c (revision a118d5cd)
1b85afe43Sbostic /*-
2*a118d5cdSbostic  * Copyright (c) 1980, 1993
3*a118d5cdSbostic  *	The Regents of the University of California.  All rights reserved.
4b85afe43Sbostic  *
5b85afe43Sbostic  * %sccs.include.redist.c%
62ac53c41Sdist  */
713109469Speter 
849bee502Sthien #ifndef lint
9*a118d5cdSbostic static char sccsid[] = "@(#)yylex.c	8.1 (Berkeley) 06/06/93";
10b85afe43Sbostic #endif /* not lint */
1113109469Speter 
1213109469Speter #include "whoami.h"
1313109469Speter #include "0.h"
1449bee502Sthien #include "tree_ty.h"	/* must be included for yy.h */
1513109469Speter #include "yy.h"
1613109469Speter 
1713109469Speter /*
1813109469Speter  * Scanner
1913109469Speter  */
2013109469Speter int	yylacnt;
2113109469Speter 
2213109469Speter #define	YYLASIZ	10
2313109469Speter 
2413109469Speter struct	yytok Yla[YYLASIZ];
2513109469Speter 
2613109469Speter unyylex(y)
2749bee502Sthien 	struct yytok *y;
2813109469Speter {
2913109469Speter 
3013109469Speter 	if (yylacnt == YYLASIZ)
3113109469Speter 		panic("unyylex");
3249bee502Sthien 	copy((char *) &Yla[yylacnt], (char *) y, sizeof Yla[0]);
3313109469Speter 	yylacnt++;
3413109469Speter 
3513109469Speter }
3613109469Speter 
yylex()3713109469Speter yylex()
3813109469Speter {
3913109469Speter 	register c;
4049bee502Sthien 	register int **ip;
4113109469Speter 	register char *cp;
4213109469Speter 	int f;
4313109469Speter 	char delim;
4413109469Speter 
4513109469Speter 	if (yylacnt != 0) {
4613109469Speter 		yylacnt--;
4749bee502Sthien 		copy((char *) &Y, (char *) &Yla[yylacnt], sizeof Y);
4813109469Speter 		return (yychar);
4913109469Speter 	}
5013109469Speter 	if (c = yysavc)
5113109469Speter 		yysavc = 0;
5213109469Speter 	else
5313109469Speter 		c = readch();
5413109469Speter #ifdef PXP
5513109469Speter 	yytokcnt++;
5613109469Speter #endif
5713109469Speter 
5813109469Speter next:
5913109469Speter 	/*
6013109469Speter 	 * skip white space
6113109469Speter 	 */
6213109469Speter #ifdef PXP
6313109469Speter 	yywhcnt = 0;
6413109469Speter #endif
6513109469Speter 	while (c == ' ' || c == '\t') {
6613109469Speter #ifdef PXP
6713109469Speter 		if (c == '\t')
6813109469Speter 			yywhcnt++;
6913109469Speter 		yywhcnt++;
7013109469Speter #endif
7113109469Speter 		c = readch();
7213109469Speter 	}
7313109469Speter 	yyecol = yycol;
7413109469Speter 	yyeline = yyline;
7513109469Speter 	yyefile = filename;
7613109469Speter 	yyeseqid = yyseqid;
7713109469Speter 	yyseekp = yylinpt;
7813109469Speter 	cp = token;
7913109469Speter 	yylval = yyline;
8013109469Speter 	switch (c) {
8113109469Speter 		case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
8213109469Speter 		case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
8313109469Speter 		case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
8413109469Speter 		case 'v': case 'w': case 'x': case 'y': case 'z':
8513109469Speter 		case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
8613109469Speter 		case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
8713109469Speter 		case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
8813109469Speter 		case 'V': case 'W': case 'X': case 'Y': case 'Z':
8913109469Speter 			do {
9013109469Speter 				*cp++ = c;
9113109469Speter 				c = readch();
9213109469Speter 			} while (alph(c) || digit(c));
9313109469Speter 			*cp = 0;
9413109469Speter 			if (opt('s'))
9513109469Speter 				for (cp = token; *cp; cp++)
9613109469Speter 					if (*cp >= 'A' && *cp <= 'Z') {
970c2b8703Smckusic 						*cp |= ' ';
9813109469Speter 					}
9913109469Speter 			yysavc = c;
10049bee502Sthien 			ip = (int **) hash((char *) 0, 1);
10149bee502Sthien 			if (*ip < (int *) yykey || *ip >= (int *) lastkey) {
10249bee502Sthien 				yylval = (int) *ip;
10313109469Speter 				return (YID);
10413109469Speter 			}
10513109469Speter 			yylval = yyline;
10613109469Speter 			/*
10713109469Speter 			 * For keywords
10813109469Speter 			 * the lexical token
10913109469Speter 			 * is magically retrieved
11013109469Speter 			 * from the keyword table.
11113109469Speter 			 */
11213109469Speter 			return ((*ip)[1]);
11313109469Speter 		case '0': case '1': case '2': case '3': case '4':
11413109469Speter 		case '5': case '6': case '7': case '8': case '9':
11513109469Speter 			f = 0;
11613109469Speter 			do {
11713109469Speter 				*cp++ = c;
11813109469Speter 				c = readch();
11913109469Speter 			} while (digit(c));
12013109469Speter 			if (c == 'b' || c == 'B') {
12113109469Speter 				/*
12213109469Speter 				 * nonstandard - octal constants
12313109469Speter 				 */
12413109469Speter 				if (opt('s')) {
12513109469Speter 					standard();
12613109469Speter 					yerror("Octal constants are non-standard");
12713109469Speter 				}
12813109469Speter 				*cp = 0;
12913109469Speter 				yylval = copystr(token);
13013109469Speter 				return (YBINT);
13113109469Speter 			}
13213109469Speter 			if (c == '.') {
13313109469Speter 				c = readch();
13413109469Speter 				if (c == '.') {
13513109469Speter 					*cp = 0;
13613109469Speter 					yysavc = YDOTDOT;
13713109469Speter 					yylval = copystr(token);
13813109469Speter 					return (YINT);
13913109469Speter 				}
14013109469Speter infpnumb:
14113109469Speter 				f++;
14213109469Speter 				*cp++ = '.';
14313109469Speter 				if (!digit(c)) {
14413109469Speter 					yyset();
14513109469Speter 					recovered();
14613109469Speter 					yerror("Digits required after decimal point");
14713109469Speter 					*cp++ = '0';
14813109469Speter 				} else
14913109469Speter 					while (digit(c)) {
15013109469Speter 						*cp++ = c;
15113109469Speter 						c = readch();
15213109469Speter 					}
15313109469Speter 			}
15413109469Speter 			if (c == 'e' || c == 'E') {
15513109469Speter 				f++;
15613109469Speter 				*cp++ = c;
15713109469Speter 				if ((c = yysavc) == 0)
15813109469Speter 					c = readch();
15913109469Speter 				if (c == '+' || c == '-') {
16013109469Speter 					*cp++ = c;
16113109469Speter 					c = readch();
16213109469Speter 				}
16313109469Speter 				if (!digit(c)) {
16413109469Speter 					yyset();
16513109469Speter 					yerror("Digits required in exponent");
16613109469Speter 					*cp++ = '0';
16713109469Speter 				} else
16813109469Speter 					while (digit(c)) {
16913109469Speter 						*cp++ = c;
17013109469Speter 						c = readch();
17113109469Speter 					}
17213109469Speter 			}
17313109469Speter 			*cp = 0;
17413109469Speter 			yysavc = c;
17513109469Speter 			yylval = copystr(token);
17613109469Speter 			if (f)
17713109469Speter 				return (YNUMB);
17813109469Speter 			return (YINT);
17913109469Speter 		case '"':
18013109469Speter 		case '`':
181595b7fbcSpeter 		case '#':
18213109469Speter 			if (!any(bufp + 1, c))
18313109469Speter 				goto illch;
18413109469Speter 			if (!dquote) {
18513109469Speter 				recovered();
18613109469Speter 				dquote++;
18713109469Speter 				yerror("Character/string delimiter is '");
18813109469Speter 			}
18913109469Speter 		case '\'':
19013109469Speter 			delim = c;
19113109469Speter 			do {
19213109469Speter 				do {
19313109469Speter 					c = readch();
19413109469Speter 					if (c == '\n') {
19549bee502Sthien 						yerror("Unmatched %c for string", (char *) delim);
19613109469Speter 						if (cp == token)
19713109469Speter 							*cp++ = ' ', cp++;
19813109469Speter 						break;
19913109469Speter 					}
20013109469Speter 					*cp++ = c;
20113109469Speter 				} while (c != delim);
20213109469Speter 				c = readch();
20313109469Speter 			} while (c == delim);
20413109469Speter 			*--cp = 0;
20513109469Speter 			if (cp == token) {
20613109469Speter 				yerror("Null string not allowed");
20713109469Speter 				*cp++ = ' ';
20813109469Speter 				*cp++ = 0;
20913109469Speter 			}
21013109469Speter 			yysavc = c;
21113109469Speter 			yylval = copystr(token);
21213109469Speter 			return (YSTRING);
21313109469Speter 		case '.':
21413109469Speter 			c = readch();
21513109469Speter 			if (c == '.')
21613109469Speter 				return (YDOTDOT);
21713109469Speter 			if (digit(c)) {
21813109469Speter 				recovered();
21913109469Speter 				yerror("Digits required before decimal point");
22013109469Speter 				*cp++ = '0';
22113109469Speter 				goto infpnumb;
22213109469Speter 			}
22313109469Speter 			yysavc = c;
22413109469Speter 			return ('.');
22513109469Speter 		case '{':
22613109469Speter 			/*
22713109469Speter 			 * { ... } comment
22813109469Speter 			 */
22913109469Speter #ifdef PXP
23013109469Speter 			getcm(c);
23113109469Speter #endif
23213109469Speter #ifdef PI
23313109469Speter 			c = options();
23413109469Speter 			while (c != '}') {
23513109469Speter 				if (c <= 0)
23613109469Speter 					goto nonterm;
23713109469Speter 				if (c == '{') {
23813109469Speter 					warning();
23913109469Speter 					yyset();
24013109469Speter 					yerror("{ in a { ... } comment");
24113109469Speter 				}
24213109469Speter 				c = readch();
24313109469Speter 			}
24413109469Speter #endif
24513109469Speter 			c = readch();
24613109469Speter 			goto next;
24713109469Speter 		case '(':
24813109469Speter 			if ((c = readch()) == '*') {
24913109469Speter 				/*
25013109469Speter 				 * (* ... *) comment
25113109469Speter 				 */
25213109469Speter #ifdef PXP
25313109469Speter 				getcm(c);
25413109469Speter 				c = readch();
25513109469Speter 				goto next;
25613109469Speter #endif
25713109469Speter #ifdef PI
25813109469Speter 				c = options();
25913109469Speter 				for (;;) {
26013109469Speter 					if (c < 0) {
26113109469Speter nonterm:
26213109469Speter 						yerror("Comment does not terminate - QUIT");
26313109469Speter 						pexit(ERRS);
26413109469Speter 					}
26513109469Speter 					if (c == '(' && (c = readch()) == '*') {
26613109469Speter 						warning();
26713109469Speter 						yyset();
26813109469Speter 						yerror("(* in a (* ... *) comment");
26913109469Speter 					}
27013109469Speter 					if (c == '*') {
27113109469Speter 						if ((c = readch()) != ')')
27213109469Speter 							continue;
27313109469Speter 						c = readch();
27413109469Speter 						goto next;
27513109469Speter 					}
27613109469Speter 					c = readch();
27713109469Speter 				}
27813109469Speter #endif
27913109469Speter 			}
28013109469Speter 			yysavc = c;
28113109469Speter 			c = '(';
28213109469Speter 		case ';':
28313109469Speter 		case ',':
28413109469Speter 		case ':':
28513109469Speter 		case '=':
28613109469Speter 		case '*':
28713109469Speter 		case '+':
28813109469Speter 		case '/':
28913109469Speter 		case '-':
29013109469Speter 		case ')':
29113109469Speter 		case '[':
29213109469Speter 		case ']':
29313109469Speter 		case '<':
29413109469Speter 		case '>':
29513109469Speter 		case '^':
29613109469Speter 			return (c);
297595b7fbcSpeter 		case '~':
298595b7fbcSpeter 		case '|':
299595b7fbcSpeter 		case '&':
300595b7fbcSpeter 			if ( opt('s') ) {
301595b7fbcSpeter 			    yyset();
302595b7fbcSpeter 			    standard();
30349bee502Sthien 			    yerror("%c is non-standard", (char *) c);
304595b7fbcSpeter 			}
305595b7fbcSpeter 			return c;
30613109469Speter 		default:
30713109469Speter 			switch (c) {
30813109469Speter 				case YDOTDOT:
30913109469Speter 					return (c);
31013109469Speter 				case '\n':
31113109469Speter 					c = readch();
31213109469Speter #ifdef PXP
31313109469Speter 					yytokcnt++;
31413109469Speter #endif
31513109469Speter 					goto next;
31613109469Speter 				case '\f':
31713109469Speter 					c = readch();
31813109469Speter 					goto next;
31913109469Speter 			}
32013109469Speter 			if (c <= 0)
32113109469Speter 				return (YEOF);
32213109469Speter illch:
32313109469Speter 			do
32413109469Speter 				yysavc = readch();
32513109469Speter 			while (yysavc == c);
32613109469Speter 			yylval = c;
32713109469Speter 			return (YILLCH);
32813109469Speter 	}
32913109469Speter }
33013109469Speter 
yyset()33113109469Speter yyset()
33213109469Speter {
33313109469Speter 
33413109469Speter 	yyecol = yycol;
33513109469Speter 	yyeline = yyline;
33613109469Speter 	yyefile = filename;
33713109469Speter 	yyseekp = yylinpt;
33813109469Speter }
33913109469Speter 
34013109469Speter /*
34113109469Speter  * Setuflg trims the current
34213109469Speter  * input line to at most 72 chars
34313109469Speter  * for the u option.
34413109469Speter  */
setuflg()34513109469Speter setuflg()
34613109469Speter {
34713109469Speter 
34813109469Speter 	if (charbuf[71] != '\n') {
34913109469Speter 		charbuf[72] = '\n';
35013109469Speter 		charbuf[73] = 0;
35113109469Speter 	}
35213109469Speter }
353