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