admin管理员组

文章数量:1126309

I am currently studying C++ through the book "PPP 3rd edition" and I just finished reading through chapter 5: Writing a Program.

I am using Visual Studio as an IDE and managed to make all the other excercises in the book to run.

In this chapter a simple calculator is made using Tokens and very simple parsing rules.

After copying the provided code snippets in the book into a full program (I triple checked, the order of the snippets is correct as the author also puts a collapsed view of the whole program), it doesn't even compile.

The code is:

//#include "PPP.h"

#include <iostream>
using namespace std;

class Token {
public:
    char kind;
    double value;
    Token(char k) :kind{ k }, value{ 0.0 } {}
    Token(char k, double v) :kind{ k }, value{ v } {}
};
class Token_stream {
public:
    Token get();
    void putback(Token t);
private:
    bool full = false;
    Token buffer;
};

void Token_stream::putback(Token t)
{
    if (full)
        cerr << "";//error("putback() into a full buffer");
    buffer = t;
    full = true;
}
Token Token_stream::get()
{
    if (full) {
        full = false;
        return buffer;
    }
    char ch = 0;
    if (!(cin >> ch))
        cerr << "";//error("no input");
    switch (ch) {
    case ';': // for "print"
    case 'q': // for "quit"
    case '(': case ')': case '+': case '-': case '*': case '/':
        return Token{ ch };
    case '.':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    {
        cin.putback(ch); 
        double val = 0;
        cin >> val;
        return Token{ '8' ,val }; 
    }
    default:
        cerr << "";//error("Bad token");
    }
}

Token_stream ts;
double expression();

double primary()
{
    Token t = ts.get();
    switch (t.kind) {
    case '(':
    {
        double d = expression();
        t = ts.get();
        if (t.kind != ')')
            cerr << "";//error("')' expected");
        return d;
    }
    case '8': // we use ’8’ to represent a number
        return t.value; // return the number’s value
    default:
        cerr << "";//error("primary expected");
    }
}
double term()
{
    double left = primary();
    Token t = ts.get();
    while (true) {
        switch (t.kind) {
        case '*':
            left *= primary();
            t = ts.get();
            break;
        case '/':
        {
            double d = primary();
            if (d == 0)
                cerr << "";//error("divide by zero");
            left /= d;
            t = ts.get();
            break;
        }
        default:
            ts.putback(t);
            return left;
        }
    }
}
double expression()
{
    double left = term(); 
    Token t = ts.get(); 
    while (true) {
        switch (t.kind) {
        case '+':
            left += term();
            t = ts.get();
            break;
        case '-':
            left -= term(); 
            t = ts.get();
            break;
        default:
            ts.putback(t);
            return left;
        }
    }
}

int main()
{
    double val = 0;
    while (cin) {
        Token t = ts.get();
        if (t.kind == 'q') // ’q’ for “quit”
            break;
        if (t.kind == ';') // ’;’ for “print now”
            cout << "=" << val << '\n';
        else
            ts.putback(t);
        val = expression();
    }
    return 0;
}

I commented the include PPP.h (module provided by author of the book) and used iostream instead. I'm also including the std namespace as that was used in the code and I didn't want to rewrite everything using std:: Lastly I commented out the helper function error() as that is in the PPP.h module since std::cerr would suffice.

There is a warning -> C4623 "'Token_stream': default constructor was implicitly defined as deleted"

And this error -> C2280 'Token_stream::Token_stream(void)': attempting to reference a deleted function

I read what the error means and I figured it's tied to the warning telling me that defining the constructor as deleted probably isn't a good thing, but other than that I'm pretty much stuck as this program should be just a copy and paste.

I tried looking at the excercise in the 2nd edition of the book and by messing around I managed to make it work making this changes:

class Token_stream {
public:
    Token_stream(); //Added this
    Token get();
    void putback(Token t);
private:
    bool full; //not making the default value flase
    Token buffer;
};

//Also added this
Token_stream::Token_stream()
    :full(false), buffer(0)
{
}

Why making this modification makes the program compile but not the actual code that I can find in the book?

This book is causing me more headaches than it should.

本文标签: