Listing 5: The decl parser with error recovery using
exception handling


//
// decl3.cpp - translate C++ declarations into English
//
// Copyright (C) 1996 by Dan Saks.
// May be copied for private, non-commercial use,
// provided this copyright notice remains intact.
// All other rights reserved.
//

#include <iostream>

#include "scanner.h"

//
// a bool type for compilers that don't have one
//
typedef int bool;
const int false = 0;
const int true = 1;

class parser
    {
public:
    parser(istream &, ostream &);
private:
    scanner input;
    ostream &output;
    struct recoverable_error { };

    void error(const string &);
    void must_be(token::category);
    string array_suffix();
    string cv_qualifier_seq();
    string declarator();
    string decl_specifier_seq();
    string direct_declarator();
    string function_suffix();
    string ptr_operator();
    string simple_declaration();

    parser(const parser &);
    parser &operator=(const parser &);
    };

void parser::error(const string &why)
    {
    output << "error: " << why << '\n';
    input.reset();
    throw recoverable_error();
    }

//
// See Listing 4 for the other parser member functions
//

//
// parser =
//     { simple-declaration ";" } .
//
parser::parser(istream &is, ostream &os)
    : input(is), output(os)
    {
    for (;;)
        try
            {
            while (input.get().kind() != token::NO_MORE)
                {
                string s = simple_declaration();
                if (input.current().kind() != token::SEMICOLON)
                    error("';' expected");
                else
                    output << s;
                }
            break;
            }
        catch (const recoverable_error &re)
            {
            }
    }

int main()
    {
    parser declarations(cin, cout);
    return 0;
    }