#include #include #define MAXL 1000 #define PUSH(kam,co) (*(kam)++=(co)) #define POP(odkud) (*--(odkud)) #define TOP(odkud) ((odkud)[-1]) #define swap(a,b) {typeof(a) p=a;a=b;b=p;} typedef unsigned char uch; #define UNUSED 0 #define ZACATEK (uch) 1 #define KONEC (uch) 0 #define AND (uch) '&' #define OR (uch) '|' #define XOR (uch) '^' #define NOT (uch) '!' #define LEFT (uch) '(' #define RIGHT (uch) ')' #define NUMBER (uch) 255 typedef struct { uch *od; int l, ng; } number; number NIC; void unnegate(number * co) { if (co->ng) { int i; co->ng = 0; for (i = 0; i < co->l; i++) co->od[i] ^= 1; } } void negate(number * co) { if (!co->ng) { int i; co->ng = 1; for (i = 0; i < co->l; i++) co->od[i] ^= 1; } } number enoth(number a, number b) { return a; } number enot(number a, number b) { a.ng ^= 1; return a; } number eand(number a, number b) { int ai, bi; if (a.l < b.l) swap(a, b); if (b.ng) { unnegate(&b); for (ai = a.l - 1, bi = b.l - 1; bi >= 0; ai--, bi--) a.od[ai] = a.ng ^ ((a.ng ^ a.od[ai]) & b.od[bi]); } else { a.od += a.l - b.l; a.l = b.l; unnegate(&a); for (ai = 0; ai < a.l; ai++) a.od[ai] &= b.od[ai]; } return a; } number eor(number a, number b) { int ai, bi; if (a.l < b.l) swap(a, b); if (b.ng) { a.od += a.l - b.l; a.l = b.l; negate(&a); unnegate(&b); for (ai = 0; ai < a.l; ai++) a.od[ai] = 1 ^ ((1 ^ a.od[ai]) | b.od[ai]); } else { for (ai = a.l - 1, bi = b.l - 1; bi >= 0; ai--, bi--) a.od[ai] = a.ng ^ ((a.ng ^ a.od[ai]) | b.od[bi]); } return a; } number exor(number a, number b) { int ai, bi; if (a.l < b.l) swap(a, b); if (b.ng) { unnegate(&b); for (ai = a.l - 1, bi = b.l - 1; bi >= 0; ai--, bi--) a.od[ai] = 1 ^ a.od[ai] ^ b.od[bi]; a.ng ^= 1; } else { for (ai = a.l - 1, bi = b.l - 1; bi >= 0; ai--, bi--) a.od[ai] = a.od[ai] ^ b.od[bi]; } return a; } void vypis(number co) { int l = 0; if (co.ng) printf("...11"); else { for (; l < co.l && !co.od[l]; l++); if (l == co.l) putchar('0'); } for (; l < co.l; l++) putchar('0' + (co.od[l] ^ co.ng)); putchar('\n'); } typedef struct { uch typ; number value; } token; typedef enum { o_pref, o_post, o_cbra, o_inf, o_nul } typ; typedef number(*akce) (number a, number b); int prio[256]; typ top[256]; akce what[256]; #define operator(zn,tp,pr,ak)\ {\ prio[zn]=pr;\ top[zn]=tp;\ what[zn]=ak;\ } void init_ops(void) { operator(ZACATEK, o_pref, -3, enoth); operator(KONEC, o_post, -2, enoth); operator(AND, o_inf, 3, eand); operator(OR, o_inf, 2, eor); operator(XOR, o_inf, 1, exor); operator(NOT, o_pref, 4, enot); operator(LEFT, o_pref, -1, NULL); operator(RIGHT, o_cbra, 0, NULL); operator(NUMBER, o_nul, UNUSED, NULL); } uch *ostack, *otop; number *nstack, *ntop; uch buffer[MAXL]; void contr(int pr) { while (prio[TOP(otop)] >= pr) { uch ao = POP(otop); number c1, c2; c2 = POP(ntop); if (top[ao] == o_inf) { c1 = POP(ntop); PUSH(ntop, what[ao] (c1, c2)); } else PUSH(ntop, what[ao] (c2, NIC)); } } void nexttoken(uch ** odkud, token * kam) { switch (**odkud) { case 0: case '!': case '&': case '|': case '^': case ')': case '(': kam->typ = *(*odkud)++; break; case '0': case '1': kam->typ = NUMBER; kam->value.od = *odkud; kam->value.ng = 0; while (**odkud == '0' || **odkud == '1') *(*odkud)++ -= '0'; kam->value.l = *odkud - kam->value.od; break; } } int main(void) { uch *co = buffer; token akt; init_ops(); gets(buffer); ostack = otop = malloc(sizeof(uch) * (strlen(co) + 2)); nstack = ntop = malloc(sizeof(number) * (strlen(co) + 2)); PUSH(otop, ZACATEK); while (1) { nexttoken(&co, &akt); switch (top[akt.typ]) { case o_inf: contr(prio[akt.typ]); PUSH(otop, akt.typ); break; case o_post: contr(prio[akt.typ]); PUSH(ntop, what[akt.typ] (POP(ntop), NIC)); break; case o_cbra: contr(prio[akt.typ]); POP(otop); break; case o_pref: PUSH(otop, akt.typ); break; case o_nul: PUSH(ntop, akt.value); break; } if (akt.typ == KONEC) break; } vypis(POP(ntop)); return 0; }