/* Code of Figure 7.11, pages 294-297 from Kenneth C. Louden, Programming Languages Principles and Practice 2nd Edition Copyright (C) Brooks-Cole/ITP, 2003 */ #include #include using namespace std; int token; struct InputError {} inputError; struct UnexpectedChar { char got; }; struct NumberExpected { char got; }; struct ExtraChars { string chars; }; struct Unwind {} unwind; void command() throw (Unwind,InputError); int expr() throw (Unwind, InputError); int term() throw (Unwind, InputError); int factor() throw (Unwind, InputError); int number() throw (NumberExpected,InputError); int digit() throw (NumberExpected,InputError); void getToken() throw (InputError) { token = cin.get(); if (cin.fail()) throw inputError; } void match(char c) throw (InputError,UnexpectedChar) { if (token == c) getToken(); else { UnexpectedChar u; // struct not required in C++ u.got = token; throw u; } } void command() throw (Unwind,InputError) { try { int result = expr(); if (token != '\n') { ExtraChars e; // struct not reqired while (token != '\n') { e.chars += token; getToken(); } throw e; } else cout << "The result is: " << result; } catch (ExtraChars e) { cout << "Extra characters found in command: " << e.chars << endl << "(missing operator or extra right parenthesis?)\n"; throw unwind; } catch (Unwind u) { cout << "Unwinding command\n"; throw; } } int expr() throw (Unwind,InputError) { try { int result = term(); while (token == '+') { match('+'); result += term(); } return result; } catch (Unwind u) { cout << "Unwinding expression\n"; throw; } } int term() throw (Unwind,InputError) { try { int result = factor(); while (token == '*') { match('*'); result *= factor(); } return result; } catch (Unwind u) { cout << "Unwinding term\n"; throw; } } int factor() throw (Unwind,InputError) { try { int result; if (token == '(') { match('('); result = expr(); match(')'); } else result = number(); return result; } catch (UnexpectedChar u) { cout << "Expected right parenthesis in factor\n" << "found: " << u.got << endl; throw unwind; } catch (Unwind u) { cout << "Unwinding factor\n"; throw; } catch (NumberExpected n) { cout << "Number expected in factor\n" << "found: " << n.got << endl; throw unwind; } } int number() throw (NumberExpected,InputError) { int result = digit(); while (isdigit(token)) result = 10 * result + digit(); return result; } int digit() throw (NumberExpected,InputError) { if (isdigit(token)) { int result = token - '0'; match(token); return result; } else { NumberExpected n; // struct not required n.got = token; throw n; } } void parse() throw (InputError) { try { getToken(); command(); } catch (Unwind u) { cout << "Unwinding parse\n"; } } int main() { try { parse(); } catch (InputError i) { cout << "Input error in parse\n"; } return 0; }