
//
// To jest przykładowy kod z podrozdziału 8.5.8 „Implementacja wywołań funkcji” książki 
// "Programowanie. Teoria i praktyka z wykorzystaniem C++" Bjarne'a Stroustrupa.
//

class Token {
public:
    char kind;        // rodzaj tokenu
    double value;     // Dla liczb" wartość
    Token(char ch)    // Tworzy token ze znaku.
        :kind(ch), value(0) { }    
    Token(char ch, double val)     // Tworzy token ze znaku i liczby typu double.
        :kind(ch), value(val) { }
};

//------------------------------------------------------------------------------

class Token_stream {
public: 
    Token_stream();   // Tworzy strumień tokenów wczytujący dane ze strumienia cin.
    Token get();      // Pobiera token (funkcja get() została zdefiniowana w innym miejscu).
    void putback(Token t);    // Zwraca token.
private:
    bool full;        // Sprawdza czy w buforze jest token.
    Token buffer;     // Przechowuje tokeny zwrócone przez funkcję putback().
};

//------------------------------------------------------------------------------

double primary(Token_stream& ts);
double term(Token_stream& ts);

double expression(Token_stream& ts)
{
    double left = term(ts);
    Token t = ts.get();
    // ...
    return left;
}

//------------------------------------------------------------------------------

double term(Token_stream& ts)
{
    double left = primary(ts);
    Token t = ts.get();
    switch (t.kind) {
    // ...
        case '/':
        {
            double d = primary(ts);
            // ...
        }
    // ...
    }

    return left;
}

//------------------------------------------------------------------------------

double primary(Token_stream& ts)
{
    Token t = ts.get ();
    switch (t.kind) {
    case ' (':
        {    double d = expression(ts);
            // ...
        }
        // ...
    }

    return 0.0;
}

//------------------------------------------------------------------------------
