#include #include static char tmp[10001], tmp2[10001], s[10001], es[10001]; static int aux, final, applied; /* returns length of the copied expression */ int copy_lexpr(char *src, char *dst) { short ln; if ((src[0] >= 'a') && (src[0] <= 'z')) { dst[0] = src[0]; dst[1] = '\0'; return 1; } if (src[0] == 'L') { dst[0] = 'L'; dst[1] = src[1]; dst[2] = '.'; return 3 + copy_lexpr(src + 3, dst + 3); } dst[0] = '('; ln = copy_lexpr(src + 1, dst + 1); dst[ln + 1] = ')'; return ln + 2 + copy_lexpr(src + ln + 2, dst + ln + 2); } /* returns the length of the expression that was evaluated (source lenght) */ int substitute(char *body, char var, char *arg, char *dst, int arglen, int *dstlen) { int ln, ln2, ln3; if (body[0] == var) { strcpy(dst, arg); *dstlen = arglen; return 1; } if ((body[0] >= 'a') && (body[0] <= 'z')) { dst[0] = body[0]; dst[1] = '\0'; *dstlen = 1; return 1; } if (body[0] == 'L') { dst[0] = 'L'; dst[1] = body[1]; dst[2] = '.'; if (body[1] == var) /* don't substitute where the variable is bound */ { ln = copy_lexpr(body + 3, dst + 3); *dstlen = ln + 3; return *dstlen; } else { ln = substitute(body + 3, var, arg, dst + 3, arglen, dstlen); *dstlen += 3; return ln + 3; } } /* (...)... */ dst[0] = '('; ln = substitute(body + 1, var, arg, dst + 1, arglen, &ln2); dst[1 + ln2] = ')'; ln3 = substitute(body + ln + 2, var, arg, dst + 2 + ln2, arglen, dstlen); *dstlen += ln2 + 2; return ln + ln3 + 2; } /* returns the length of the expression that was evaluated (source lenght) */ int eval_lexpr(char *src, char *dst) { int ln, ln2; if ((src[0] >= 'a') && (src[0] <= 'z')) { dst[0] = src[0]; dst[1] = '\0'; return 1; } if (src[0] == 'L') { dst[0] = 'L'; dst[1] = src[1]; dst[2] = '.'; return 3 + copy_lexpr(src + 3, dst + 3); } ln = eval_lexpr(src + 1, dst); if (dst[0] != 'L') /* if the function evaluated to something else */ { if (dst[0] == '(') /* if it is a funtion application, we need to make another try */ { final = 0; strcpy(tmp, dst); dst[0] = '('; strcpy(dst + 1, tmp); ln2 = strlen(dst); dst[ln2++] = ')'; return ln + 2 + copy_lexpr(src + ln + 2, dst + ln2); } else /* function evaluated to constant */ { dst[1] = dst[0]; dst[0] = '('; dst[2] = ')'; return ln + 2 + eval_lexpr(src + ln + 2, dst + 3); } } /* function evaluated to Lvar.body */ final = 0; applied++; strcpy(tmp, dst + 3); /* copy body to tmp */ ln2 = copy_lexpr(src + 2 + ln, tmp2); /* copy argument to tmp2 */ substitute(tmp, dst[1], tmp2, dst, ln2, &aux); return ln + ln2 + 2; } int main() { int last; do { fgets(es, 10000, stdin); last = (es[0] == 'z'); applied = 0; /* number of applications */ do { /* evaluate the expression step-by-step */ strcpy(s, es); final = 1; eval_lexpr(s, es); } while (!final && (applied <= 1000)); if (applied > 1000) printf("unterminated\n"); else printf("%s\n", es); } while (!last); return 0; }