1 /*	idlex.l	(CWI)	1.1	85/03/01	*/
2 %{
3 #include "ideal.h"
4 #include "y.tab.h"
5 extern int lineno, yylval;
6 extern boolean flyback;
7 
8 #define	BUFLEN	100
9 
10 struct filenode {
11 	struct filenode *next;
12 	FILE *file;
13 	int lineno;
14 	char *name;
15 	char buf[BUFLEN];
16 	int head;
17 };
18 
19 struct filenode *filestack = NULL;
20 
21 FILE *curfile;
22 #undef	input
23 #undef	unput
24 
25 boolean file_start = TRUE;
26 boolean just_popped = FALSE;
27 
28 void filepush ();
29 void filepop ();
30 char input ();
31 void unput ();
32 %}
33 %Start	PROGRAM COMMENT OUTSIDE LIBRARY INCLUDE
34 %%
35 %{
36 	int numitems, i;
37 	char item[5][20];
38 	char cmd[20];
39 	static int ISnest, bracenest, commnest, omode;
40 	if (file_start) {
41 		BEGIN OUTSIDE;
42 		ISnest = 0;
43 	};
44 	file_start = FALSE;
45 %}
46 <OUTSIDE>^\.IS.*\n	{
47 			BEGIN PROGRAM;
48 			if (!ISnest)
49 				printf ("%s", yytext);
50 			ISnest ++;
51 			bracenest = commnest = 0;
52 			}
53 <OUTSIDE>[ \t]		{
54 			if (just_popped) {
55 				if (omode == LIBFIL)
56 					BEGIN LIBRARY;
57 				else if (omode == CHATTY)
58 					BEGIN INCLUDE;
59 				else impossible ("idlex");
60 				just_popped = FALSE;
61 			} else
62 				printf ("%s", yytext);
63 			}
64 <OUTSIDE>.		{
65 			printf ("%s", yytext);
66 			}
67 <OUTSIDE>\n		{
68 			if (just_popped) {
69 				BEGIN PROGRAM;
70 				just_popped = FALSE;
71 			} else {
72 				printf ("\n");
73 			}
74 			}
75 <PROGRAM>box		return(yylval = BOX);
76 <PROGRAM>var		return(yylval = VAR);
77 <PROGRAM>bdlist		return(yylval = BDLIST);
78 <PROGRAM>boundary	return(yylval = BDLIST);
79 <PROGRAM>put		return(yylval = PUT);
80 <PROGRAM>conn		return(yylval = CONN);
81 <PROGRAM>to		return(yylval = TO);
82 <PROGRAM>using		return(yylval = USING);
83 <PROGRAM>construct	return(yylval = CONSTRUCT);
84 <PROGRAM>draw		return(yylval = DRAW);
85 <PROGRAM>opaque		return(yylval = OPAQUE);
86 <PROGRAM>left		return(yylval = LEFT);
87 <PROGRAM>text		return(yylval = CENTER);
88 <PROGRAM>right		return(yylval = RIGHT);
89 <PROGRAM>spline		return(yylval = SPLINE);
90 <PROGRAM>at		return(yylval = AT);
91 <PROGRAM>interior	return(yylval = INTERIOR);
92 <PROGRAM>exterior	return(yylval = EXTERIOR);
93 <PROGRAM>[a-zA-Z][a-zA-Z0-9]*	{
94 			yylval = lookup(&yytext[0]);
95 			return(NAME);
96 			}
97 <PROGRAM>[0-9]+|[0-9]*\.[0-9]+	{
98 			float temp;
99 			sscanf(yytext, "%f", &temp);
100 			yylval = (int) fextlgen(temp);
101 			return(CONST);
102 			}
103 <PROGRAM>^\.\.\.forget.*	{
104 			numitems = sscanf (yytext, "%s %s %s %s %s %s",
105 				cmd,
106 				&item[0][0],
107 				&item[1][0],
108 				&item[2][0],
109 				&item[3][0],
110 				&item[4][0]
111 			);
112 			numitems --;
113 			for (i = 0; i < numitems; i ++)
114 				forget (lookup (&item[i][0]));
115 			}
116 <PROGRAM>^\.\.\.radians.*	radflag = TRUE;
117 <PROGRAM>^\.\.\.degrees.*	radflag = FALSE;
118 <PROGRAM>^\.\.\.libfile	{
119 			omode = LIBFIL;
120 			BEGIN LIBRARY;
121 			}
122 <LIBRARY>[ \t]+		;
123 <LIBRARY>[^ \t\n]+	{
124 			idinclude (yytext, LIBFIL);
125 			BEGIN OUTSIDE + 1;
126 			}
127 <LIBRARY>\n		{
128 			BEGIN PROGRAM + 1;
129 			}
130 <PROGRAM>^\.\.\.include	{
131 			omode = CHATTY;
132 			BEGIN INCLUDE;
133 			}
134 <INCLUDE>[ \t]+		;
135 <INCLUDE>[^ \t\n]+	{
136 			idinclude (yytext, CHATTY);
137 			BEGIN OUTSIDE + 1;
138 			}
139 <INCLUDE>\n		{
140 			BEGIN PROGRAM + 1;
141 			}
142 <PROGRAM>^\.I[EF].*\n	{
143 			interpret ();
144 			ISnest --;
145 			if (!ISnest)
146 				printf ("%s", yytext);
147 			if (bracenest > 0)
148 				fprintf (stderr, "ideal: excess {\n");
149 			BEGIN OUTSIDE;
150 			}
151 <PROGRAM>^\..*		{
152 			sscanf (yytext, "%s", cmd);
153 			if (strcmp (cmd, "...libfile") && strcmp (cmd, "...include"))
154 				printf ("%s\n", yytext);
155 			else
156 				REJECT;
157 			}
158 <PROGRAM>#.*		;
159 <PROGRAM>"/*"		{
160 			commnest = 1;
161 			BEGIN COMMENT;
162 			}
163 <COMMENT>"/*"		{
164 			commnest ++;
165 			}
166 <COMMENT>"*/"		{
167 			commnest --;
168 			if (!commnest)
169 				BEGIN PROGRAM;
170 			}
171 <COMMENT>.		;
172 <COMMENT>\n		{
173 			}
174 <PROGRAM>"'"[^']*	{
175 			if (yytext[yyleng-1] == '\\') {
176 				yytext[yyleng-1] = yytext[yyleng];
177 				yyleng --;
178 				yymore();
179 			} else {
180 				char *temp;
181 				temp = malloc((unsigned) yyleng+1);
182 				yytext[yyleng] = '\0';
183 				strcpy(temp, &yytext[1]);
184 				yylval = (int) temp;
185 				input();
186 				return(STRING);
187 			}
188 			}
189 <PROGRAM>\"[^\"]*	{
190 			if (yytext[yyleng-1] == '\\') {
191 				yytext[yyleng-1] = yytext[yyleng];
192 				yyleng --;
193 				yymore();
194 			} else {
195 				char *temp;
196 				temp = malloc((unsigned) yyleng+1);
197 				yytext[yyleng] = '\0';
198 				strcpy(temp, &yytext[1]);
199 				yylval = (int) temp;
200 				input();
201 				return(STRING);
202 			}
203 			}
204 <PROGRAM>[ \t]+		{
205 			if (just_popped) {
206 				if (omode == LIBFIL)
207 					BEGIN LIBRARY;
208 				else if (omode == CHATTY)
209 					BEGIN INCLUDE;
210 				else impossible ("idlex");
211 				just_popped = FALSE;
212 			}
213 			}
214 <PROGRAM>\n		{
215 			}
216 <PROGRAM>"{"		{
217 			bracenest ++;
218 			return (yylval = LBRACE);
219 			}
220 <PROGRAM>"}"		{
221 			bracenest --;
222 			if (bracenest < 0)
223 				fprintf (stderr, "ideal: excess }\n");
224 			return (yylval = RBRACE);
225 			}
226 <PROGRAM>[\<\>\(\)\[\]\+\-\*\/\=\,\;\:\.\^\~]	return(yytext[0]);
227 <PROGRAM>.		fprintf(stderr, "ideal: unknown input token %s flushed\n", &yytext[0]);
228 %%
229 void filepush (f)
230 FILE *f;
231 {
232 	struct filenode *newfile;
233 	newfile = (struct filenode *) calloc (1, sizeof (struct filenode));
234 	if (newfile) {
235 		newfile->next = filestack;
236 		newfile->file = curfile = f;
237 		newfile->head = -1;
238 		if (filestack)
239 			filestack->lineno = lineno;
240 		newfile->name = malloc ((unsigned)strlen(filename)+1);
241 		strcpy (newfile->name, filename);
242 		filestack = newfile;
243 		lineno = 1;
244 	} else {
245 		fprintf (stderr, "ideal: no room for file descriptor\n");
246 		exit (1);
247 	}
248 }
249 
250 void filepop ()
251 {
252 	struct filenode *oldfile;
253 	if (filestack) {
254 		if (filestack->head > -1)
255 			fprintf (stderr, "ideal: characters ignored in file %s\n", filename);
256 		oldfile = filestack;
257 		filestack = filestack->next;
258 		fclose (oldfile->file);
259 		if (filestack) {
260 			curfile = filestack->file;
261 			lineno = filestack->lineno;
262 			filename = filestack->name;
263 		} else
264 			curfile = NULL;
265 		free ((char *)oldfile);
266 	} else {
267 		fprintf (stderr, "ideal: file stack botch\n");
268 		exit (1);
269 	}
270 }
271 
272 int idgetc (f)
273 struct filenode *f;
274 {
275 	int c;
276 	if (!f)
277 		return (EOF);
278 	if (f->head > -1) {
279 		c = f->buf[f->head--];
280 	} else
281 		c = getc(f->file);
282 	return (c);
283 }
284 
285 char input ()
286 {
287 	int c;
288 	c = 0;
289 	if (filestack)
290 		c = idgetc(filestack);
291 	while (c == EOF && filestack) {
292 		filepop();
293 		if (filestack) {
294 			c = idgetc(filestack);
295 			just_popped = TRUE;
296 		}
297 		else
298 			c = EOF;
299 	}
300 	if (c == '\n')
301 		lineno++;
302 	return ((c == EOF)?0:c);
303 }
304 
305 void unput (c)
306 char c;
307 {
308 	struct filenode *f;
309 	if (f = filestack) {
310 		if (f->head < BUFLEN) {
311 			f->buf[++f->head] = c;
312 			if (c == '\n')
313 				-- lineno;
314 		} else {
315 			fprintf (stderr, "ideal: out of pushback space\n");
316 			exit (1);
317 		}
318 	}
319 }
320