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