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