xref: /csrg-svn/old/eqn/common_source/lex.c (revision 48252)
1*48252Sbostic /*-
2*48252Sbostic  * Copyright (c) 1991 The Regents of the University of California.
3*48252Sbostic  * All rights reserved.
4*48252Sbostic  *
5*48252Sbostic  * %sccs.include.proprietary.c%
6*48252Sbostic  */
7*48252Sbostic 
814486Ssam #ifndef lint
9*48252Sbostic static char sccsid[] = "@(#)lex.c	4.4 (Berkeley) 04/17/91";
10*48252Sbostic #endif /* not lint */
1111008Sshannon 
1211008Sshannon #include "e.h"
1311008Sshannon #include "e.def"
1411008Sshannon 
1511008Sshannon #define	SSIZE	400
1611008Sshannon char	token[SSIZE];
1711008Sshannon int	sp;
1811008Sshannon #define	putbak(c)	*ip++ = c;
1911008Sshannon #define	PUSHBACK	300	/* maximum pushback characters */
2011008Sshannon char	ibuf[PUSHBACK+SSIZE];	/* pushback buffer for definitions, etc. */
2111008Sshannon char	*ip	= ibuf;
2211008Sshannon 
gtc()2311008Sshannon gtc() {
2411008Sshannon   loop:
2511008Sshannon 	if (ip > ibuf)
2611008Sshannon 		return(*--ip);	/* already present */
2711008Sshannon 	lastchar = getc(curfile);
2811008Sshannon 	if (lastchar=='\n')
2911008Sshannon 		linect++;
3011008Sshannon 	if (lastchar != EOF)
3111008Sshannon 		return(lastchar);
3211008Sshannon 	if (++ifile > svargc) {
3311008Sshannon 		return(EOF);
3411008Sshannon 	}
3511008Sshannon 	fclose(curfile);
3611008Sshannon 	linect = 1;
3714899Srrh 	if (openinfile() == 0)
3811008Sshannon 		goto loop;
3911008Sshannon 	return(EOF);
4011008Sshannon }
4114899Srrh /*
4214899Srrh  *	open file indexed by ifile in svargv, return non zero if fail
4314899Srrh  */
openinfile()4414899Srrh openinfile()
4514899Srrh {
4614899Srrh 	if (strcmp(svargv[ifile], "-") == 0){
4714899Srrh 		curfile = stdin;
4814899Srrh 		return(0);
4914899Srrh 	} else if ((curfile=fopen(svargv[ifile], "r")) != NULL){
5014899Srrh 		return(0);
5114899Srrh 	}
5214899Srrh 	error(FATAL, "can't open file %s", svargv[ifile]);
5314899Srrh 	return(1);
5414899Srrh }
5511008Sshannon 
pbstr(str)5611008Sshannon pbstr(str)
5711008Sshannon register char *str;
5811008Sshannon {
5911008Sshannon 	register char *p;
6011008Sshannon 
6111008Sshannon 	p = str;
6211008Sshannon 	while (*p++);
6311008Sshannon 	--p;
6411008Sshannon 	if (ip >= &ibuf[PUSHBACK])
6511008Sshannon 		error( FATAL, "pushback overflow");
6611008Sshannon 	while (p > str)
6711008Sshannon 		putbak(*--p);
6811008Sshannon }
6911008Sshannon 
yylex()7011008Sshannon yylex() {
7111008Sshannon 	register int c;
7211008Sshannon 	tbl *tp, *lookup();
7311008Sshannon 	extern tbl **keytbl, **deftbl;
7411008Sshannon 
7511008Sshannon   beg:
7611008Sshannon 	while ((c=gtc())==' ' || c=='\n')
7711008Sshannon 		;
7811008Sshannon 	yylval=c;
7911008Sshannon 	switch(c) {
8011008Sshannon 
8111008Sshannon 	case EOF:
8211008Sshannon 		return(EOF);
8311008Sshannon 	case '~':
8411008Sshannon 		return(SPACE);
8511008Sshannon 	case '^':
8611008Sshannon 		return(THIN);
8711008Sshannon 	case '\t':
8811008Sshannon 		return(TAB);
8911008Sshannon 	case '{':
9011008Sshannon 		return('{');
9111008Sshannon 	case '}':
9211008Sshannon 		return('}');
9311008Sshannon 	case '"':
9411008Sshannon 		for (sp=0; (c=gtc())!='"' && c != '\n'; ) {
9511008Sshannon 			if (c == '\\')
9611008Sshannon 				if ((c = gtc()) != '"')
9711008Sshannon 					token[sp++] = '\\';
9811008Sshannon 			token[sp++] = c;
9911008Sshannon 			if (sp>=SSIZE)
10011008Sshannon 				error(FATAL, "quoted string %.20s... too long", token);
10111008Sshannon 		}
10211008Sshannon 		token[sp]='\0';
10311008Sshannon 		yylval = (int) &token[0];
10411008Sshannon 		if (c == '\n')
10511008Sshannon 			error(!FATAL, "missing \" in %.20s", token);
10611008Sshannon 		return(QTEXT);
10711008Sshannon 	}
10811008Sshannon 	if (c==righteq)
10911008Sshannon 		return(EOF);
11011008Sshannon 
11111008Sshannon 	putbak(c);
11211008Sshannon 	getstr(token, SSIZE);
11311008Sshannon 	if (dbg)printf(".\tlex token = |%s|\n", token);
11411008Sshannon 	if ((tp = lookup(&deftbl, token, NULL)) != NULL) {
11511008Sshannon 		putbak(' ');
11611008Sshannon 		pbstr(tp->defn);
11711008Sshannon 		putbak(' ');
11811008Sshannon 		if (dbg)
11911008Sshannon 			printf(".\tfound %s|=%s|\n", token, tp->defn);
12011008Sshannon 	}
12111008Sshannon 	else if ((tp = lookup(&keytbl, token, NULL)) == NULL) {
12211008Sshannon 		if(dbg)printf(".\t%s is not a keyword\n", token);
12311008Sshannon 		return(CONTIG);
12411008Sshannon 	}
12511008Sshannon 	else if (tp->defn == (char *) DEFINE || tp->defn == (char *) NDEFINE || tp->defn == (char *) TDEFINE)
12611008Sshannon 		define(tp->defn);
12711008Sshannon 	else if (tp->defn == (char *) DELIM)
12811008Sshannon 		delim();
12911008Sshannon 	else if (tp->defn == (char *) GSIZE)
13011008Sshannon 		globsize();
13111008Sshannon 	else if (tp->defn == (char *) GFONT)
13211008Sshannon 		globfont();
13311008Sshannon 	else if (tp->defn == (char *) INCLUDE)
13411008Sshannon 		include();
13511008Sshannon 	else {
13611008Sshannon 		return((int) tp->defn);
13711008Sshannon 	}
13811008Sshannon 	goto beg;
13911008Sshannon }
14011008Sshannon 
getstr(s,n)14111008Sshannon getstr(s, n) char *s; register int n; {
14211008Sshannon 	register int c;
14311008Sshannon 	register char *p;
14411008Sshannon 
14511008Sshannon 	p = s;
14611008Sshannon 	while ((c = gtc()) == ' ' || c == '\n')
14711008Sshannon 		;
14811008Sshannon 	if (c == EOF) {
14911008Sshannon 		*s = 0;
15011008Sshannon 		return;
15111008Sshannon 	}
15211008Sshannon 	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
15311008Sshannon 	  && c != '"' && c != '~' && c != '^' && c != righteq) {
15411008Sshannon 		if (c == '\\')
15511008Sshannon 			if ((c = gtc()) != '"')
15611008Sshannon 				*p++ = '\\';
15711008Sshannon 		*p++ = c;
15811008Sshannon 		if (--n <= 0)
15911008Sshannon 			error(FATAL, "token %.20s... too long", s);
16011008Sshannon 		c = gtc();
16111008Sshannon 	}
16211008Sshannon 	if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq)
16311008Sshannon 		putbak(c);
16411008Sshannon 	*p = '\0';
16511008Sshannon 	yylval = (int) s;
16611008Sshannon }
16711008Sshannon 
cstr(s,quote,maxs)16811008Sshannon cstr(s, quote, maxs) char *s; int quote; {
16911008Sshannon 	int del, c, i;
17011008Sshannon 
17111008Sshannon 	while((del=gtc()) == ' ' || del == '\t' || del == '\n');
17211008Sshannon 	if (quote)
17311008Sshannon 		for (i=0; (c=gtc()) != del && c != EOF;) {
17411008Sshannon 			s[i++] = c;
17511008Sshannon 			if (i >= maxs)
17611008Sshannon 				return(1);	/* disaster */
17711008Sshannon 		}
17811008Sshannon 	else {
17911008Sshannon 		s[0] = del;
18011008Sshannon 		for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
18111008Sshannon 			s[i++]=c;
18211008Sshannon 			if (i >= maxs)
18311008Sshannon 				return(1);	/* disaster */
18411008Sshannon 		}
18511008Sshannon 	}
18611008Sshannon 	s[i] = '\0';
18711008Sshannon 	if (c == EOF)
18811008Sshannon 		error(FATAL, "Unexpected end of input at %.20s", s);
18911008Sshannon 	return(0);
19011008Sshannon }
19111008Sshannon 
define(type)19211008Sshannon define(type) int type; {
19311008Sshannon 	char *strsave(), *p1, *p2;
19411008Sshannon 	tbl *lookup();
19511008Sshannon 	extern tbl **deftbl;
19611008Sshannon 
19711008Sshannon 	getstr(token, SSIZE);	/* get name */
19811008Sshannon 	if (type != DEFINE) {
19911008Sshannon 		cstr(token, 1, SSIZE);	/* skip the definition too */
20011008Sshannon 		return;
20111008Sshannon 	}
20211008Sshannon 	p1 = strsave(token);
20311008Sshannon 	if (cstr(token, 1, SSIZE))
20411008Sshannon 		error(FATAL, "Unterminated definition at %.20s", token);
20511008Sshannon 	p2 = strsave(token);
20611008Sshannon 	lookup(&deftbl, p1, p2);
20711008Sshannon 	if (dbg)printf(".\tname %s defined as %s\n", p1, p2);
20811008Sshannon }
20911008Sshannon 
strsave(s)21011008Sshannon char *strsave(s)
21111008Sshannon char *s;
21211008Sshannon {
21311008Sshannon 	char *malloc();
21411008Sshannon 	register char *q;
21511008Sshannon 
21611008Sshannon 	q = malloc(strlen(s)+1);
21711008Sshannon 	if (q == NULL)
21811008Sshannon 		error(FATAL, "out of space in strsave on %s", s);
21911008Sshannon 	strcpy(q, s);
22011008Sshannon 	return(q);
22111008Sshannon }
22211008Sshannon 
include()22311008Sshannon include() {
22411008Sshannon 	error(!FATAL, "Include not yet implemented");
22511008Sshannon }
22611008Sshannon 
delim()22711008Sshannon delim() {
22811008Sshannon 	yyval = eqnreg = 0;
22911008Sshannon 	if (cstr(token, 0, SSIZE))
23011008Sshannon 		error(FATAL, "Bizarre delimiters at %.20s", token);
23111008Sshannon 	lefteq = token[0];
23211008Sshannon 	righteq = token[1];
23311008Sshannon 	if (lefteq == 'o' && righteq == 'f')
23411008Sshannon 		lefteq = righteq = '\0';
23511008Sshannon }
236