Commit | Line | Data |
---|---|---|
a32b3978 BS |
1 | /* lex.c 4.1 83/02/11 */ |
2 | ||
3 | #include "e.h" | |
4 | #include "e.def" | |
5 | ||
6 | #define SSIZE 400 | |
7 | char token[SSIZE]; | |
8 | int sp; | |
9 | #define putbak(c) *ip++ = c; | |
10 | #define PUSHBACK 300 /* maximum pushback characters */ | |
11 | char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */ | |
12 | char *ip = ibuf; | |
13 | ||
14 | gtc() { | |
15 | loop: | |
16 | if (ip > ibuf) | |
17 | return(*--ip); /* already present */ | |
18 | lastchar = getc(curfile); | |
19 | if (lastchar=='\n') | |
20 | linect++; | |
21 | if (lastchar != EOF) | |
22 | return(lastchar); | |
23 | if (++ifile > svargc) { | |
24 | return(EOF); | |
25 | } | |
26 | fclose(curfile); | |
27 | linect = 1; | |
28 | if ((curfile=fopen(svargv[ifile], "r")) != NULL) | |
29 | goto loop; | |
30 | error(FATAL, "can't open file %s", svargv[ifile]); | |
31 | return(EOF); | |
32 | } | |
33 | ||
34 | pbstr(str) | |
35 | register char *str; | |
36 | { | |
37 | register char *p; | |
38 | ||
39 | p = str; | |
40 | while (*p++); | |
41 | --p; | |
42 | if (ip >= &ibuf[PUSHBACK]) | |
43 | error( FATAL, "pushback overflow"); | |
44 | while (p > str) | |
45 | putbak(*--p); | |
46 | } | |
47 | ||
48 | yylex() { | |
49 | register int c; | |
50 | tbl *tp, *lookup(); | |
51 | extern tbl **keytbl, **deftbl; | |
52 | ||
53 | beg: | |
54 | while ((c=gtc())==' ' || c=='\n') | |
55 | ; | |
56 | yylval=c; | |
57 | switch(c) { | |
58 | ||
59 | case EOF: | |
60 | return(EOF); | |
61 | case '~': | |
62 | return(SPACE); | |
63 | case '^': | |
64 | return(THIN); | |
65 | case '\t': | |
66 | return(TAB); | |
67 | case '{': | |
68 | return('{'); | |
69 | case '}': | |
70 | return('}'); | |
71 | case '"': | |
72 | for (sp=0; (c=gtc())!='"' && c != '\n'; ) { | |
73 | if (c == '\\') | |
74 | if ((c = gtc()) != '"') | |
75 | token[sp++] = '\\'; | |
76 | token[sp++] = c; | |
77 | if (sp>=SSIZE) | |
78 | error(FATAL, "quoted string %.20s... too long", token); | |
79 | } | |
80 | token[sp]='\0'; | |
81 | yylval = (int) &token[0]; | |
82 | if (c == '\n') | |
83 | error(!FATAL, "missing \" in %.20s", token); | |
84 | return(QTEXT); | |
85 | } | |
86 | if (c==righteq) | |
87 | return(EOF); | |
88 | ||
89 | putbak(c); | |
90 | getstr(token, SSIZE); | |
91 | if (dbg)printf(".\tlex token = |%s|\n", token); | |
92 | if ((tp = lookup(&deftbl, token, NULL)) != NULL) { | |
93 | putbak(' '); | |
94 | pbstr(tp->defn); | |
95 | putbak(' '); | |
96 | if (dbg) | |
97 | printf(".\tfound %s|=%s|\n", token, tp->defn); | |
98 | } | |
99 | else if ((tp = lookup(&keytbl, token, NULL)) == NULL) { | |
100 | if(dbg)printf(".\t%s is not a keyword\n", token); | |
101 | return(CONTIG); | |
102 | } | |
103 | else if (tp->defn == (char *) DEFINE || tp->defn == (char *) NDEFINE || tp->defn == (char *) TDEFINE) | |
104 | define(tp->defn); | |
105 | else if (tp->defn == (char *) DELIM) | |
106 | delim(); | |
107 | else if (tp->defn == (char *) GSIZE) | |
108 | globsize(); | |
109 | else if (tp->defn == (char *) GFONT) | |
110 | globfont(); | |
111 | else if (tp->defn == (char *) INCLUDE) | |
112 | include(); | |
113 | else { | |
114 | return((int) tp->defn); | |
115 | } | |
116 | goto beg; | |
117 | } | |
118 | ||
119 | getstr(s, n) char *s; register int n; { | |
120 | register int c; | |
121 | register char *p; | |
122 | ||
123 | p = s; | |
124 | while ((c = gtc()) == ' ' || c == '\n') | |
125 | ; | |
126 | if (c == EOF) { | |
127 | *s = 0; | |
128 | return; | |
129 | } | |
130 | while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' | |
131 | && c != '"' && c != '~' && c != '^' && c != righteq) { | |
132 | if (c == '\\') | |
133 | if ((c = gtc()) != '"') | |
134 | *p++ = '\\'; | |
135 | *p++ = c; | |
136 | if (--n <= 0) | |
137 | error(FATAL, "token %.20s... too long", s); | |
138 | c = gtc(); | |
139 | } | |
140 | if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq) | |
141 | putbak(c); | |
142 | *p = '\0'; | |
143 | yylval = (int) s; | |
144 | } | |
145 | ||
146 | cstr(s, quote, maxs) char *s; int quote; { | |
147 | int del, c, i; | |
148 | ||
149 | while((del=gtc()) == ' ' || del == '\t' || del == '\n'); | |
150 | if (quote) | |
151 | for (i=0; (c=gtc()) != del && c != EOF;) { | |
152 | s[i++] = c; | |
153 | if (i >= maxs) | |
154 | return(1); /* disaster */ | |
155 | } | |
156 | else { | |
157 | s[0] = del; | |
158 | for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) { | |
159 | s[i++]=c; | |
160 | if (i >= maxs) | |
161 | return(1); /* disaster */ | |
162 | } | |
163 | } | |
164 | s[i] = '\0'; | |
165 | if (c == EOF) | |
166 | error(FATAL, "Unexpected end of input at %.20s", s); | |
167 | return(0); | |
168 | } | |
169 | ||
170 | define(type) int type; { | |
171 | char *strsave(), *p1, *p2; | |
172 | tbl *lookup(); | |
173 | extern tbl **deftbl; | |
174 | ||
175 | getstr(token, SSIZE); /* get name */ | |
176 | if (type != DEFINE) { | |
177 | cstr(token, 1, SSIZE); /* skip the definition too */ | |
178 | return; | |
179 | } | |
180 | p1 = strsave(token); | |
181 | if (cstr(token, 1, SSIZE)) | |
182 | error(FATAL, "Unterminated definition at %.20s", token); | |
183 | p2 = strsave(token); | |
184 | lookup(&deftbl, p1, p2); | |
185 | if (dbg)printf(".\tname %s defined as %s\n", p1, p2); | |
186 | } | |
187 | ||
188 | char *strsave(s) | |
189 | char *s; | |
190 | { | |
191 | char *malloc(); | |
192 | register char *q; | |
193 | ||
194 | q = malloc(strlen(s)+1); | |
195 | if (q == NULL) | |
196 | error(FATAL, "out of space in strsave on %s", s); | |
197 | strcpy(q, s); | |
198 | return(q); | |
199 | } | |
200 | ||
201 | include() { | |
202 | error(!FATAL, "Include not yet implemented"); | |
203 | } | |
204 | ||
205 | delim() { | |
206 | yyval = eqnreg = 0; | |
207 | if (cstr(token, 0, SSIZE)) | |
208 | error(FATAL, "Bizarre delimiters at %.20s", token); | |
209 | lefteq = token[0]; | |
210 | righteq = token[1]; | |
211 | if (lefteq == 'o' && righteq == 'f') | |
212 | lefteq = righteq = '\0'; | |
213 | } |