// // Convert a formula from direct polish notation // into the normal (infix) form // // Grammar: // S -> + S S | - S S | * S S | / S S | // a | b | ... | z | A | B | ... | Z // // Example: on input // / + a b - a b // the program prints // ((a+b)/(a-b)) #include #include #include #include static char line[1024] = ""; static char *curpos = line; static char outLine[1024]; static char *outpos = outLine; static void parse_S0(); static void parse_S(); static void skipSpace(); static void syntaxError(const char* s); static void output(char c); jmp_buf env; int main() { while (true) { setjmp(env); printf("Input a formula in the direct polish notation:\n"); fgets(line, 1022, stdin); int lineLen = strlen(line); if (lineLen >= 1 && line[lineLen-1] == '\n') { --lineLen; line[lineLen] = 0; } if (lineLen >= 1 && line[lineLen-1] == '\r') { --lineLen; line[lineLen] = 0; } if (lineLen == 0) break; curpos = line; skipSpace(); if (*curpos == 0) break; // Add the end marker line[lineLen] = '$'; ++lineLen; outpos = outLine; parse_S0(); *outpos = 0; printf("%s\n", outLine); } return 0; } static void parse_S0() { parse_S(); // Check the end marker skipSpace(); if (*curpos != '$') syntaxError(curpos); } static void parse_S() { skipSpace(); char c = *curpos; switch (c) { case '+': case '-': case '*': case '/': ++curpos; // Skip an operation output('('); // Enclose a formula into parentheses parse_S(); // Parse the first operand output(c); // Print an operation parse_S(); // Parse the second operand output(')'); // Close parentheses break; default: if (isalpha(c)) { output(c); // Print a name ++curpos; // Skip a name } else { syntaxError(curpos); } } } static void skipSpace() { while (*curpos != 0 && isspace(*curpos)) ++curpos; } static void output(char c) { if (outpos - outLine >= 1023) return; *outpos = c; ++outpos; } static void syntaxError(const char *str) { if (*str != 0) printf("Syntax error: \"%s\"\n", str); else printf("Syntax error.\n", str); longjmp(env, 0); }