/* idlex.l (CWI) 1.1 85/03/01 */ %{ #include "ideal.h" #include "y.tab.h" extern int lineno, yylval; extern boolean flyback; #define BUFLEN 100 struct filenode { struct filenode *next; FILE *file; int lineno; char *name; char buf[BUFLEN]; int head; }; struct filenode *filestack = NULL; FILE *curfile; #undef input #undef unput boolean file_start = TRUE; boolean just_popped = FALSE; void filepush (); void filepop (); char input (); void unput (); %} %Start PROGRAM COMMENT OUTSIDE LIBRARY INCLUDE %% %{ int numitems, i; char item[5][20]; char cmd[20]; static int ISnest, bracenest, commnest, omode; if (file_start) { BEGIN OUTSIDE; ISnest = 0; }; file_start = FALSE; %} ^\.IS.*\n { BEGIN PROGRAM; if (!ISnest) printf ("%s", yytext); ISnest ++; bracenest = commnest = 0; } [ \t] { if (just_popped) { if (omode == LIBFIL) BEGIN LIBRARY; else if (omode == CHATTY) BEGIN INCLUDE; else impossible ("idlex"); just_popped = FALSE; } else printf ("%s", yytext); } . { printf ("%s", yytext); } \n { if (just_popped) { BEGIN PROGRAM; just_popped = FALSE; } else { printf ("\n"); } } box return(yylval = BOX); var return(yylval = VAR); bdlist return(yylval = BDLIST); boundary return(yylval = BDLIST); put return(yylval = PUT); conn return(yylval = CONN); to return(yylval = TO); using return(yylval = USING); construct return(yylval = CONSTRUCT); draw return(yylval = DRAW); opaque return(yylval = OPAQUE); left return(yylval = LEFT); text return(yylval = CENTER); right return(yylval = RIGHT); spline return(yylval = SPLINE); at return(yylval = AT); interior return(yylval = INTERIOR); exterior return(yylval = EXTERIOR); [a-zA-Z][a-zA-Z0-9]* { yylval = lookup(&yytext[0]); return(NAME); } [0-9]+|[0-9]*\.[0-9]+ { float temp; sscanf(yytext, "%f", &temp); yylval = (int) fextlgen(temp); return(CONST); } ^\.\.\.forget.* { numitems = sscanf (yytext, "%s %s %s %s %s %s", cmd, &item[0][0], &item[1][0], &item[2][0], &item[3][0], &item[4][0] ); numitems --; for (i = 0; i < numitems; i ++) forget (lookup (&item[i][0])); } ^\.\.\.radians.* radflag = TRUE; ^\.\.\.degrees.* radflag = FALSE; ^\.\.\.libfile { omode = LIBFIL; BEGIN LIBRARY; } [ \t]+ ; [^ \t\n]+ { idinclude (yytext, LIBFIL); BEGIN OUTSIDE + 1; } \n { BEGIN PROGRAM + 1; } ^\.\.\.include { omode = CHATTY; BEGIN INCLUDE; } [ \t]+ ; [^ \t\n]+ { idinclude (yytext, CHATTY); BEGIN OUTSIDE + 1; } \n { BEGIN PROGRAM + 1; } ^\.I[EF].*\n { interpret (); ISnest --; if (!ISnest) printf ("%s", yytext); if (bracenest > 0) fprintf (stderr, "ideal: excess {\n"); BEGIN OUTSIDE; } ^\..* { sscanf (yytext, "%s", cmd); if (strcmp (cmd, "...libfile") && strcmp (cmd, "...include")) printf ("%s\n", yytext); else REJECT; } #.* ; "/*" { commnest = 1; BEGIN COMMENT; } "/*" { commnest ++; } "*/" { commnest --; if (!commnest) BEGIN PROGRAM; } . ; \n { } "'"[^']* { if (yytext[yyleng-1] == '\\') { yytext[yyleng-1] = yytext[yyleng]; yyleng --; yymore(); } else { char *temp; temp = malloc((unsigned) yyleng+1); yytext[yyleng] = '\0'; strcpy(temp, &yytext[1]); yylval = (int) temp; input(); return(STRING); } } \"[^\"]* { if (yytext[yyleng-1] == '\\') { yytext[yyleng-1] = yytext[yyleng]; yyleng --; yymore(); } else { char *temp; temp = malloc((unsigned) yyleng+1); yytext[yyleng] = '\0'; strcpy(temp, &yytext[1]); yylval = (int) temp; input(); return(STRING); } } [ \t]+ { if (just_popped) { if (omode == LIBFIL) BEGIN LIBRARY; else if (omode == CHATTY) BEGIN INCLUDE; else impossible ("idlex"); just_popped = FALSE; } } \n { } "{" { bracenest ++; return (yylval = LBRACE); } "}" { bracenest --; if (bracenest < 0) fprintf (stderr, "ideal: excess }\n"); return (yylval = RBRACE); } [\<\>\(\)\[\]\+\-\*\/\=\,\;\:\.\^\~] return(yytext[0]); . fprintf(stderr, "ideal: unknown input token %s flushed\n", &yytext[0]); %% void filepush (f) FILE *f; { struct filenode *newfile; newfile = (struct filenode *) calloc (1, sizeof (struct filenode)); if (newfile) { newfile->next = filestack; newfile->file = curfile = f; newfile->head = -1; if (filestack) filestack->lineno = lineno; newfile->name = malloc ((unsigned)strlen(filename)+1); strcpy (newfile->name, filename); filestack = newfile; lineno = 1; } else { fprintf (stderr, "ideal: no room for file descriptor\n"); exit (1); } } void filepop () { struct filenode *oldfile; if (filestack) { if (filestack->head > -1) fprintf (stderr, "ideal: characters ignored in file %s\n", filename); oldfile = filestack; filestack = filestack->next; fclose (oldfile->file); if (filestack) { curfile = filestack->file; lineno = filestack->lineno; filename = filestack->name; } else curfile = NULL; free ((char *)oldfile); } else { fprintf (stderr, "ideal: file stack botch\n"); exit (1); } } int idgetc (f) struct filenode *f; { int c; if (!f) return (EOF); if (f->head > -1) { c = f->buf[f->head--]; } else c = getc(f->file); return (c); } char input () { int c; c = 0; if (filestack) c = idgetc(filestack); while (c == EOF && filestack) { filepop(); if (filestack) { c = idgetc(filestack); just_popped = TRUE; } else c = EOF; } if (c == '\n') lineno++; return ((c == EOF)?0:c); } void unput (c) char c; { struct filenode *f; if (f = filestack) { if (f->head < BUFLEN) { f->buf[++f->head] = c; if (c == '\n') -- lineno; } else { fprintf (stderr, "ideal: out of pushback space\n"); exit (1); } } }