xref: /csrg-svn/old/eqn/common_source/lex.c (revision 14486)
1 #ifndef lint
2 static char sccsid[] = "@(#)lex.c	4.2 08/11/83";
3 #endif
4 
5 #include "e.h"
6 #include "e.def"
7 
8 #define	SSIZE	400
9 char	token[SSIZE];
10 int	sp;
11 #define	putbak(c)	*ip++ = c;
12 #define	PUSHBACK	300	/* maximum pushback characters */
13 char	ibuf[PUSHBACK+SSIZE];	/* pushback buffer for definitions, etc. */
14 char	*ip	= ibuf;
15 
16 gtc() {
17   loop:
18 	if (ip > ibuf)
19 		return(*--ip);	/* already present */
20 	lastchar = getc(curfile);
21 	if (lastchar=='\n')
22 		linect++;
23 	if (lastchar != EOF)
24 		return(lastchar);
25 	if (++ifile > svargc) {
26 		return(EOF);
27 	}
28 	fclose(curfile);
29 	linect = 1;
30 	if ((curfile=fopen(svargv[ifile], "r")) != NULL)
31 		goto loop;
32 	error(FATAL, "can't open file %s", svargv[ifile]);
33 	return(EOF);
34 }
35 
36 pbstr(str)
37 register char *str;
38 {
39 	register char *p;
40 
41 	p = str;
42 	while (*p++);
43 	--p;
44 	if (ip >= &ibuf[PUSHBACK])
45 		error( FATAL, "pushback overflow");
46 	while (p > str)
47 		putbak(*--p);
48 }
49 
50 yylex() {
51 	register int c;
52 	tbl *tp, *lookup();
53 	extern tbl **keytbl, **deftbl;
54 
55   beg:
56 	while ((c=gtc())==' ' || c=='\n')
57 		;
58 	yylval=c;
59 	switch(c) {
60 
61 	case EOF:
62 		return(EOF);
63 	case '~':
64 		return(SPACE);
65 	case '^':
66 		return(THIN);
67 	case '\t':
68 		return(TAB);
69 	case '{':
70 		return('{');
71 	case '}':
72 		return('}');
73 	case '"':
74 		for (sp=0; (c=gtc())!='"' && c != '\n'; ) {
75 			if (c == '\\')
76 				if ((c = gtc()) != '"')
77 					token[sp++] = '\\';
78 			token[sp++] = c;
79 			if (sp>=SSIZE)
80 				error(FATAL, "quoted string %.20s... too long", token);
81 		}
82 		token[sp]='\0';
83 		yylval = (int) &token[0];
84 		if (c == '\n')
85 			error(!FATAL, "missing \" in %.20s", token);
86 		return(QTEXT);
87 	}
88 	if (c==righteq)
89 		return(EOF);
90 
91 	putbak(c);
92 	getstr(token, SSIZE);
93 	if (dbg)printf(".\tlex token = |%s|\n", token);
94 	if ((tp = lookup(&deftbl, token, NULL)) != NULL) {
95 		putbak(' ');
96 		pbstr(tp->defn);
97 		putbak(' ');
98 		if (dbg)
99 			printf(".\tfound %s|=%s|\n", token, tp->defn);
100 	}
101 	else if ((tp = lookup(&keytbl, token, NULL)) == NULL) {
102 		if(dbg)printf(".\t%s is not a keyword\n", token);
103 		return(CONTIG);
104 	}
105 	else if (tp->defn == (char *) DEFINE || tp->defn == (char *) NDEFINE || tp->defn == (char *) TDEFINE)
106 		define(tp->defn);
107 	else if (tp->defn == (char *) DELIM)
108 		delim();
109 	else if (tp->defn == (char *) GSIZE)
110 		globsize();
111 	else if (tp->defn == (char *) GFONT)
112 		globfont();
113 	else if (tp->defn == (char *) INCLUDE)
114 		include();
115 	else {
116 		return((int) tp->defn);
117 	}
118 	goto beg;
119 }
120 
121 getstr(s, n) char *s; register int n; {
122 	register int c;
123 	register char *p;
124 
125 	p = s;
126 	while ((c = gtc()) == ' ' || c == '\n')
127 		;
128 	if (c == EOF) {
129 		*s = 0;
130 		return;
131 	}
132 	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
133 	  && c != '"' && c != '~' && c != '^' && c != righteq) {
134 		if (c == '\\')
135 			if ((c = gtc()) != '"')
136 				*p++ = '\\';
137 		*p++ = c;
138 		if (--n <= 0)
139 			error(FATAL, "token %.20s... too long", s);
140 		c = gtc();
141 	}
142 	if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq)
143 		putbak(c);
144 	*p = '\0';
145 	yylval = (int) s;
146 }
147 
148 cstr(s, quote, maxs) char *s; int quote; {
149 	int del, c, i;
150 
151 	while((del=gtc()) == ' ' || del == '\t' || del == '\n');
152 	if (quote)
153 		for (i=0; (c=gtc()) != del && c != EOF;) {
154 			s[i++] = c;
155 			if (i >= maxs)
156 				return(1);	/* disaster */
157 		}
158 	else {
159 		s[0] = del;
160 		for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
161 			s[i++]=c;
162 			if (i >= maxs)
163 				return(1);	/* disaster */
164 		}
165 	}
166 	s[i] = '\0';
167 	if (c == EOF)
168 		error(FATAL, "Unexpected end of input at %.20s", s);
169 	return(0);
170 }
171 
172 define(type) int type; {
173 	char *strsave(), *p1, *p2;
174 	tbl *lookup();
175 	extern tbl **deftbl;
176 
177 	getstr(token, SSIZE);	/* get name */
178 	if (type != DEFINE) {
179 		cstr(token, 1, SSIZE);	/* skip the definition too */
180 		return;
181 	}
182 	p1 = strsave(token);
183 	if (cstr(token, 1, SSIZE))
184 		error(FATAL, "Unterminated definition at %.20s", token);
185 	p2 = strsave(token);
186 	lookup(&deftbl, p1, p2);
187 	if (dbg)printf(".\tname %s defined as %s\n", p1, p2);
188 }
189 
190 char *strsave(s)
191 char *s;
192 {
193 	char *malloc();
194 	register char *q;
195 
196 	q = malloc(strlen(s)+1);
197 	if (q == NULL)
198 		error(FATAL, "out of space in strsave on %s", s);
199 	strcpy(q, s);
200 	return(q);
201 }
202 
203 include() {
204 	error(!FATAL, "Include not yet implemented");
205 }
206 
207 delim() {
208 	yyval = eqnreg = 0;
209 	if (cstr(token, 0, SSIZE))
210 		error(FATAL, "Bizarre delimiters at %.20s", token);
211 	lefteq = token[0];
212 	righteq = token[1];
213 	if (lefteq == 'o' && righteq == 'f')
214 		lefteq = righteq = '\0';
215 }
216