1 #ifndef lint 2 static char sccsid[] = "@(#)lex.c 2.2 (CWI) 87/04/01"; 3 #endif lint 4 #include "e.h" 5 #include "y.tab.h" 6 #include "ctype.h" 7 8 #define SSIZE 400 9 char token[SSIZE]; 10 int sp; 11 12 yylex() 13 { 14 register int c; 15 tbl *tp; 16 17 begin: 18 while ((c=input()) == ' ' || c == '\n') 19 ; 20 yylval = c; 21 switch (c) { 22 case EOF: 23 error(!FATAL, "unexpected end of input inside equation"); 24 return(EOF); 25 case '~': 26 return(SPACE); 27 case '^': 28 return(THIN); 29 case '\t': 30 return(TAB); 31 case '{': 32 return('{'); 33 case '}': 34 return('}'); 35 case '"': 36 for (sp = 0; (c=input())!='"' && c != '\n'; ) { 37 if (c == '\\') 38 if ((c = input()) != '"') 39 token[sp++] = '\\'; 40 token[sp++] = c; 41 if (sp >= SSIZE) 42 error(FATAL, "quoted string %.20s... too long", token); 43 } 44 token[sp] = '\0'; 45 yylval = (int) &token[0]; 46 if (c == '\n') 47 error(!FATAL, "missing \" in %.20s", token); 48 return(QTEXT); 49 } 50 if (!display && c == righteq) 51 return(EOF); 52 53 unput(c); 54 getstr(token, SSIZE); 55 dprintf(".\tlex token = |%s|\n", token); 56 if ((tp = lookup(deftbl, token, NULL)) != NULL) { /* defined term */ 57 c = input(); 58 unput(c); 59 if (c == '(') /* macro with args */ 60 dodef(tp); 61 else { /* no args */ 62 unput(' '); 63 pbstr(tp->defn); 64 dprintf(".\tfound %s|=%s|\n", token, tp->defn); 65 } 66 goto begin; 67 } 68 69 if ((tp = lookup(keytbl, token, NULL)) == NULL) /* not a keyword */ 70 return CONTIG; 71 72 switch ((int) tp->defn) { /* some kind of keyword */ 73 case DEFINE: case TDEFINE: case NDEFINE: 74 define(tp->defn); 75 break; 76 case IFDEF: 77 ifdef(); 78 break; 79 case DELIM: 80 delim(); 81 break; 82 case GSIZE: 83 globsize(); 84 break; 85 case GFONT: 86 globfont(); 87 break; 88 case INCLUDE: 89 include(); 90 break; 91 case SPACE: 92 space(); 93 break; 94 case DOTEQ: 95 /* .EQ inside equation -- should warn if at bottom level */ 96 break; 97 case DOTEN: 98 if (curfile == infile) 99 return EOF; 100 /* else ignore nested .EN */ 101 break; 102 default: 103 return (int) tp->defn; 104 } 105 goto begin; 106 } 107 108 getstr(s, n) 109 char *s; 110 register int n; 111 { 112 register int c; 113 register char *p; 114 115 p = s; 116 while ((c = input()) == ' ' || c == '\n') 117 ; 118 if (c == EOF) { 119 *s = 0; 120 return; 121 } 122 while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' 123 && c != '"' && c != '~' && c != '^') { 124 if (!display && c == righteq) 125 break; 126 if (c == '(' && p > s) { /* might be defined(...) */ 127 *p = '\0'; 128 if (lookup(deftbl, s, NULL) != NULL) 129 break; 130 } 131 if (c == '\\') 132 if ((c = input()) != '"') 133 *p++ = '\\'; 134 *p++ = c; 135 if (--n <= 0) 136 error(FATAL, "token %.20s... too long", s); 137 c = input(); 138 } 139 unput(c); 140 *p = '\0'; 141 yylval = (int) s; 142 } 143 144 cstr(s, quote, maxs) 145 char *s; 146 int quote; 147 { 148 int del, c, i; 149 150 s[0] = 0; 151 while ((del=input()) == ' ' || del == '\t') 152 ; 153 if (quote) 154 for (i=0; (c=input()) != del && c != EOF;) { 155 s[i++] = c; 156 if (i >= maxs) 157 return(1); /* disaster */ 158 } 159 else { 160 if (del == '\n') 161 return(1); 162 s[0] = del; 163 for (i=1; (c=input())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) { 164 s[i++] = c; 165 if (i >= maxs) 166 return(1); /* disaster */ 167 } 168 } 169 s[i] = '\0'; 170 if (c == EOF) 171 error(FATAL, "Unexpected end of input at %.20s", s); 172 return(0); 173 } 174 175 define(type) 176 int type; 177 { 178 char *p1, *p2; 179 180 getstr(token, SSIZE); /* get name */ 181 if (type != DEFINE) { 182 cstr(token, 1, SSIZE); /* skip the definition too */ 183 return; 184 } 185 p1 = strsave(token); 186 if (cstr(token, 1, SSIZE)) 187 error(FATAL, "Unterminated definition at %.20s", token); 188 p2 = strsave(token); 189 lookup(deftbl, p1, p2); 190 dprintf(".\tname %s defined as %s\n", p1, p2); 191 } 192 193 ifdef() /* do body if name is defined */ 194 { 195 tbl *tp; 196 char name[100], *p; 197 198 getstr(name, sizeof(name)); /* get name */ 199 cstr(token, 1, SSIZE); /* and body */ 200 if ((tp = lookup(deftbl, name, NULL)) != NULL) { /* found it */ 201 p = strsave(token); 202 pushsrc(Free, p); 203 pushsrc(String, p); 204 } 205 } 206 207 char *spaceval = NULL; 208 209 space() /* collect line of form "space amt" to replace \x in output */ 210 { 211 getstr(token, SSIZE); 212 spaceval = strsave(token); 213 dprintf(".\tsetting spaceval to %s\n", token); 214 } 215 216 char *strsave(s) 217 char *s; 218 { 219 register char *q; 220 221 q = malloc(strlen(s)+1); 222 if (q == NULL) 223 error(FATAL, "out of space in strsave on %s", s); 224 strcpy(q, s); 225 return(q); 226 } 227 228 include() 229 { 230 char name[100]; 231 FILE *fin; 232 int c; 233 extern int errno; 234 235 while ((c = input()) == ' ') 236 ; 237 unput(c); 238 cstr(name, c == '"', sizeof(name)); /* gets it quoted or not */ 239 if ((fin = fopen(name, "r")) == NULL) 240 fatal("can't open file %s", name); 241 errno = 0; 242 curfile++; 243 curfile->fin = fin; 244 curfile->fname = strsave(name); 245 curfile->lineno = 0; 246 printf(".lf 1 %s\n", curfile->fname); 247 pushsrc(File, curfile); 248 } 249 250 delim() 251 { 252 yyval = eqnreg = 0; 253 if (cstr(token, 0, SSIZE)) 254 error(FATAL, "Bizarre delimiters"); 255 lefteq = token[0]; 256 righteq = token[1]; 257 if (!isprint(lefteq) || !isprint(righteq)) 258 error(FATAL, "Bizarre delimiters"); 259 if (lefteq == 'o' && righteq == 'f') 260 lefteq = righteq = '\0'; 261 } 262