|
|
1.1 root 1: #define DEBUG 0
2:
3: #define setv 1
4: #define addeq 2
5: #define subeq 3
6: #define muleq 4
7: #define diveq 5
8: #define modeq 6
9: #define plus 7
10: #define minus 8
11: #define times 9
12: #define div 10
13: #define mod 11
14: #define power 12
15: #define uminus 13
16: #define gt 14
17: #define lt 15
18: #define ge 16
19: #define le 17
20: #define eq 18
21: #define ne 19
22: #define land 20
23: #define lor 21
24: #define lnot 22
25: #define princ 23
26: #define prdec 24
27: #define poinc 25
28: #define podec 26
29:
30: #define OP 0
31: #define NM 1
32:
33: #define unary(c) (c == uminus || c == lnot || c >= princ)
34: #define binary(c) !unary(c)
35:
36: struct REVPOL {
37: char toktyp;
38: short tokval;
39: } *parsed;
40:
41: int prs = 0;
42: extern int verbose;
43: char * Emalloc();
44:
45: pushnm(tok)
46: { if (prs >= EXPRMAX)
47: whoops("expression too long");
48: parsed[prs].toktyp = NM;
49: parsed[prs++].tokval = tok;
50: }
51:
52: pushop(tok)
53: { if (prs >= EXPRMAX)
54: whoops("expression too long");
55: parsed[prs].toktyp = OP;
56: parsed[prs++].tokval = tok;
57: }
58:
59: struct Node *
60: newnode(ntyp, nval, left, right)
61: struct Node *left, *right;
62: {
63: struct Node *try;
64:
65: try = (struct Node *) Emalloc(sizeof(struct Node));
66: try->ntyp = ntyp;
67: try->nval = nval;
68: try->left = left;
69: try->right = right;
70: return try;
71: }
72:
73: makeexpr(n)
74: { pushexpr(n);
75: return -(2 + addrevpol());
76: }
77:
78: pushexpr(n)
79: struct Node *n;
80: {
81: if (n == NULL) return;
82: switch (n->ntyp) {
83: case NM: pushnm(n->nval); break;
84: case OP: pushexpr(n->left); pushexpr(n->right); pushop(n->nval); break;
85: default: whoops("unknown node type");
86: }
87: }
88:
89: struct {
90: short n;
91: struct REVPOL *p;
92: } revpols[MANY];
93:
94: int npols = 0;
95:
96: numexps(fd)
97: FILE *fd;
98: { int i, j;
99: struct REVPOL *p;
100:
101: fprintf(fd, "EXPR %d\n", npols);
102: for (i = 0; i < npols; i++)
103: { fprintf(fd, "%d: ", revpols[i].n);
104: p = revpols[i].p;
105: for (j = (revpols[i].n)-1; j >= 0; j--)
106: fprintf(fd, "%d/%d ", p[j].toktyp, p[j].tokval);
107: putc('\n', fd);
108: } }
109:
110: findsame(a)
111: { struct REVPOL *p, *q;
112: int k = revpols[a].n;
113: int i, j;
114:
115: q = revpols[a].p;
116: for (i = 0; i < npols; i++)
117: { if (revpols[i].n != revpols[a].n)
118: continue;
119: p = revpols[i].p;
120: for (j = 0; j < k; j++)
121: if (p[j].toktyp != q[j].toktyp
122: || p[j].tokval != q[j].tokval)
123: break;
124: if (j == k)
125: break;
126: }
127: return i;
128: }
129:
130: addrevpol()
131: { int i;
132: int retval;
133:
134: if (npols >= MANY)
135: whoops("too many expressions");
136:
137: revpols[npols].n = prs;
138: revpols[npols].p = parsed;
139:
140: if ((retval = findsame(npols)) == npols)
141: npols++;
142:
143: #if 0
144: printf("exp(%d): ", prs);
145: for (i = prs-1; i >= 0; i--)
146: { if (parsed[i].toktyp == NM)
147: { printf("%d ", parsed[i].tokval);
148: continue;
149: }
150: switch(parsed[i].tokval) {
151: case setv: printf("= "); break;
152: case addeq: printf("+= "); break;
153: case subeq: printf("-= "); break;
154: case muleq: printf("*= "); break;
155: case diveq: printf("/= "); break;
156: case modeq: printf("%= "); break;
157: case plus: printf("+ "); break;
158: case minus: printf("- "); break;
159: case times: printf("* "); break;
160: case div: printf("/ "); break;
161: case mod: printf("% "); break;
162: case power: printf("^ "); break;
163: case uminus: printf(".- "); break;
164: case gt: printf("> "); break;
165: case lt: printf("< "); break;
166: case ge: printf(">= "); break;
167: case le: printf("<= "); break;
168: case eq: printf("== "); break;
169: case ne: printf("!= "); break;
170: case land: printf("&& "); break;
171: case lor: printf("|| "); break;
172: case lnot: printf("! "); break;
173: case princ: printf("++. "); break;
174: case prdec: printf("--. "); break;
175: case poinc: printf(".++ "); break;
176: case podec: printf(".-- "); break;
177: default: fprintf(stderr, "%d", parsed[i].tokval);
178: whoops("unknown operator");
179: }
180: }
181: putchar('\n');
182: #endif
183: parsed = (struct REVPOL *) Emalloc(EXPRMAX * sizeof(struct REVPOL));
184: prs = 0;
185:
186: return retval;
187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.