|
|
1.1 root 1: #include "stdio.h"
2:
3: char line[10240];
4: struct arg {
5: char *val;
6: int len;
7: } args[1000];
8: int narg;
9: struct arg words[2000];
10: extern char *wordskip(), *matchskip();
11:
12: main()
13: { char *p, *q;
14: for(;;) {
15: (void) fgets(line, sizeof(line), stdin);
16: if(feof(stdin))
17: exit(0);
18: narg = 0;
19: p = wordskip(line, '\t');
20: q = matchskip(p);
21: if(!findargs(p))
22: continue;
23: if(!uniqargs())
24: continue;
25: if(!matchargs(q))
26: continue;
27: if(!checktemp(q))
28: continue;
29: fixtree();
30: prleft(q);
31: }
32: }
33:
34: fixtree()
35: { int i, j;
36: for(i = 0; i < narg; i++)
37: for(j = 0; j < args[i].len; j++)
38: args[i].val[j] = i;
39: }
40:
41:
42: checktemp(q)
43: char *q; /* [^\].(fp) is an unusable temporary, and ,$n */
44: { char *p;
45: for(p = q; *p != '\n'; p++)
46: if(*p == 'f' && *(p-1) == '(' && *(p-2) > ' ')
47: return(0);
48: for(p = q; *p != '\n'; p++)
49: if(*p == ',' && *(p+1) == '$' && *(p+2) > ' ')
50: return(0);
51: for(p = q; *p != '\n'; p++)
52: if(*p == '$' && *(p+1) == '-')
53: return(0);
54: return(1);
55: }
56:
57: prleft(q)
58: char *q;
59: { char *p, *s;
60: for(p = line; *p != '\t'; p++)
61: ;
62: *p = ' ';
63: for(p = line; *p != '\n'; ) {
64: if(*p >= ' ') {
65: putchar(*p++);
66: continue;
67: }
68: for(s = p; *s == *p; s++)
69: ;
70: if(*p < 10)
71: printf("\\%d", *p);
72: else
73: printf("\\%c", *p - 9 + 'a');
74: p = s;
75: }
76: putchar('\n');
77: }
78: int alens[33]; /* if an arg > 32, forget it */
79: matchargs(s)
80: char *s;
81: { char *p;
82: int i, j, ok;
83: for(i = 0; i < 33; i++)
84: alens[i] = 0;
85: for(i = 0; i < narg; i++)
86: if(args[i].len <= 32)
87: alens[args[i].len]++;
88: else
89: return(0);
90: for(j = 32; j >= 1; j--) {
91: if(alens[j] == 0)
92: continue;
93: for(i = 0; i < narg; i++) {
94: if(args[i].len != j)
95: continue;
96: ok = 0;
97: for(p = s; *p != '\n'; p++)
98: if(*p == args[i].val[0])
99: ok += matchit(p, i);
100: if(ok == 0)
101: return(0);
102: }
103: }
104: return(1);
105: }
106:
107: matchit(p, i)
108: char *p;
109: { int j, c;
110: for(j = 0; j < args[i].len; j++)
111: if(p[j] != args[i].val[j])
112: return(0);
113: if((c = p[j]) <= '9' && c >= '0')
114: return(0);
115: if(c <= 'z' && c >= 'a')
116: return(0);
117: if(c <= 'Z' && c >= 'A')
118: return(0);
119: for(j = 0; j < args[i].len; j++)
120: p[j] = i; /* assumes narg < 32!!!!*/
121: return(1);
122: }
123:
124: findargs(p)
125: char *p;
126: { int cnt, i, j;
127: struct arg *a;
128: if(*p != '(') {
129: fprintf(stderr, "findargs fmt %s", line);
130: return(0);
131: }
132: cnt = setwords(p);
133: for(i = 0; i <= cnt; i++)
134: stripcrud(words + i);
135: for(i = 0; i <= cnt; i++) {
136: a = &words[i];
137: if(a->len == 0)
138: continue;
139: switch(numargs(a->val)) {
140: case 0:
141: continue;
142: case 2:
143: args[narg++] = words[++i];
144: case 1:
145: args[narg++] = words[++i];
146: continue;
147: default:
148: fprintf(stderr, "unk op %s|%s", a->val, line);
149: return(0);
150: }
151: }
152: return(1);
153: }
154:
155: struct {
156: char *val;
157: int num, len;
158: } ops[] = {
159: {"and", 0},
160: {"asg", 0}, /* asg ops are binary*/
161: {"assign", 0},
162: {"call", 1},
163: {"cm", 0},
164: {"comop", 0},
165: {"compl", 0},
166: {"conv", 0},
167: {"decr", 0},
168: {"div", 0},
169: {"er", 0},
170: {"fld", 2},
171: {"funarg", 0},
172: {"genbr", 2},
173: {"genlab", 1},
174: {"genubr", 1},
175: {"icon", 1},
176: {"init", 0},
177: {"incr", 0},
178: {"ls", 0},
179: {"minus", 0},
180: {"mod", 0},
181: {"mul", 0},
182: {"name", 1},
183: {"not", 0},
184: {"or", 0},
185: {"plus", 0},
186: {"reg", 1},
187: {"return", 0},
188: {"unary", 0}, /* common prefix for unary ops */
189: {"rnode", 0},
190: {"qnode", 0},
191: {"snode", 0},
192: {"rs", 0},
193: {"star", 0},
194: {"starg", 2},
195: {"stasg", 1},
196: {"stcall", 2},
197: {"vauto", 1},
198: {"vparam", 1},
199: {0,0}
200: };
201:
202: numargs(s)
203: char *s;
204: { int i;
205: static int init = 0;
206: if(!init++)
207: for(i = 0; ops[i].val; i++)
208: ops[i].len = strlen(ops[i].val);
209: for(i = 0; ops[i].val; i++)
210: if(strncmp(s+1, ops[i].val,ops[i].len) == 0)
211: return(ops[i].num);
212: return(-1);
213: }
214:
215: stripcrud(a)
216: struct arg *a;
217: { char *p;
218: for(p = a->val + a->len - 1; *p == ' ' || *p == ')'; p--)
219: ;
220: if(p < a->val)
221: p = a->val - 1;
222: a->len = p - a->val + 1;
223: }
224:
225: setwords(p)
226: char *p;
227: { int i;
228: i = 0;
229: loop:
230: words[i].val = p;
231: p = wordskip(p, ' ');
232: words[i].len = p - words[i].val;
233: if(*p == '\\')
234: return(i);
235: i++;
236: goto loop;
237: }
238:
239: argcmp(a, b)
240: struct arg *a, *b;
241: { int n, i;
242: n = a->len;
243: if(b->len < n)
244: n = b->len;
245: i = strncmp(a->val, b->val, n);
246: if(i != 0)
247: return(i);
248: if(a->len < b->len)
249: return(-1);
250: else if(a->len > b->len)
251: return(1);
252: return(0);
253: }
254:
255: uniqargs()
256: { int i, j;
257: for(i = 1; i < narg; i++) {
258: if(args[i].len <= 0)
259: continue;
260: for(j = 0; j < i; j++) {
261: if(args[j].len <= 0)
262: continue;
263: if(argcmp(args + i, args + j) == 0) {
264: /*printf("%5.5s %5.5s ", args[i].val, args[j].val);
265: */return(0);
266: }
267: }
268: }
269: return(1);
270: }
271:
272: char *
273: wordskip(p, c)
274: char *p;
275: {
276: for(; *p != c; p++)
277: ;
278: for(; *p == c; p++)
279: ;
280: return(p);
281: }
282:
283: char *
284: matchskip(p)
285: char *p;
286: { int cnt;
287: for(cnt = 0; ; p++)
288: if(*p == '(')
289: cnt++;
290: else if(*p == ')')
291: if(--cnt <= 0)
292: return(p+1);
293: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.