istringstream syntax error question

Discussion in 'C++' started by Donald Canton, Jan 29, 2004.

  1. Hi,

    I'm using Bjarne's book to learn C++ and am stuck on the Calc program
    in Section 6. Everything works fine except when I try to use
    istringstream to parse a token from the command line. I thought I
    followed his instructions on page 118 correctly, but I can't get it to
    compile without syntax errors in the get_token() function. The whole
    program follows with the four syntax errors flagged with the text "//
    SYNTAX ERROR". Thanks in advance.

    #include <iostream> // I/O
    #include <string> // strings
    #include <map> // map
    #include <cctype> // isalpha(), etc.
    #include <sstream> // so that we can use "istringstream"
    using namespace std;

    istream* input; //pointer to input stream

    enum Token_value {
    NAME, NUMBER, END,
    PLUS='+', MINUS='-', MUL='*', DIV='/',
    PRINT=';', ASSIGN='=', LP='(', RP=')'
    };

    Token_value curr_tok = PRINT;

    //function prototypes
    map<string, double> table;
    double expr(bool);
    double term(bool);
    double prim (bool);
    Token_value get_token();
    double error(const string&);

    double expr(bool get) //add and subtract
    {
    double left = term(get);

    for (;;) //"forever"
    switch (curr_tok) {
    case PLUS:
    left += term(true);
    break;
    case MINUS:
    left -= term(true);
    break;
    default:
    return left;
    }
    }

    double term(bool get) //multiply and divide
    {
    double left = prim(get);

    for (;;)
    switch (curr_tok) {
    case MUL:
    left *= prim(true);
    break;
    case DIV:
    if (double d = prim(true)) {
    left /= d;
    break;
    }
    return error("divide by 0");
    default:
    return left;
    }
    }

    double number_value;
    string string_value;

    double prim (bool get) //handle primaries
    {
    if (get) get_token();

    switch (curr_tok) {
    case NUMBER:
    { double v = number_value;
    get_token();
    return v;
    }
    case NAME:
    { double& v = table[string_value];
    if (get_token() == ASSIGN) v = expr(true);
    return v;
    }
    case MINUS: //unary minus
    return -prim(true);
    case LP:
    { double e = expr(true);
    if (curr_tok != RP) return error("')' expected");
    get_token(); //eat ')'
    return e;
    }
    default:
    return error("primary expected");
    }
    }

    Token_value get_token()
    {
    char ch;
    do { //skip whitespace except '\n'
    if (!*input.get(ch)) return curr_tok=END; // SYNTAX ERROR
    } while (ch != '\n' && isspace(ch));

    switch (ch) {
    case ';':
    case '\n':
    return curr_tok=PRINT;
    case '*':
    case '/':
    case '+':
    case '-':
    case '(':
    case ')':
    case '=':
    return curr_tok=Token_value(ch);
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    case '.':
    *input.putback(ch); // SYNTAX ERROR
    *input >> number_value;
    return curr_tok=NUMBER;
    default: //NAME, NAME=, or error
    if (isalpha(ch)) {
    string_value = ch;
    while (*input.get(ch) && isalnum(ch)) // SYNTAX ERROR
    string_value.push_back(ch);
    *input.putback(ch); // SYNTAX ERROR
    return curr_tok=NAME;
    }
    error("bad token");
    return curr_tok=PRINT;
    }
    }

    int no_of_errors;

    double error(const string& s)
    {
    no_of_errors++;
    cerr << "error:" << s << '\n';
    return 1;
    }

    int main(int argc, char* argv[])
    {
    switch (argc) {
    case 1:
    input = &cin;
    break;
    case 2:
    input = new istringstream(argv[1]);
    break;
    default:
    error("too many arguments");
    return 1;
    }

    table["pi"] = 3.1415926535897932384626433832795; //insert
    predefined names
    table["e"] = 2.7182818284590452353602874713527;

    while (*input) {
    get_token();
    if (curr_tok==END) break;
    if (curr_tok==PRINT) continue;
    cout << expr(false) << '\n';
    }
    if (input != &cin) delete input;
    return no_of_errors;
    }
     
    Donald Canton, Jan 29, 2004
    #1
    1. Advertising

  2. Donald Canton

    David Harmon Guest

    On 29 Jan 2004 13:59:30 -0800 in comp.lang.c++,
    (Donald Canton) was alleged to have written:
    > *input.putback(ch); // SYNTAX ERROR


    Precedence. Everywhere you have *input.something
    write (*input).something or input->something
     
    David Harmon, Jan 30, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Viet Le Hong

    istringstream question

    Viet Le Hong, Sep 18, 2003, in forum: C++
    Replies:
    3
    Views:
    699
    Buster Copley
    Sep 18, 2003
  2. Luther Baker

    istringstream question

    Luther Baker, May 22, 2004, in forum: C++
    Replies:
    7
    Views:
    3,895
    John Harrison
    May 22, 2004
  3. JustSomeGuy

    A question about istringstream

    JustSomeGuy, Nov 24, 2004, in forum: C++
    Replies:
    6
    Views:
    427
    =?iso-8859-1?Q?Ali_=C7ehreli?=
    Nov 25, 2004
  4. Randy Yates

    istringstream class question

    Randy Yates, Jan 2, 2005, in forum: C++
    Replies:
    8
    Views:
    526
    Jonathan Turkanis
    Jan 3, 2005
  5. Markus Kern

    [NEWBIE] istringstream-syntax

    Markus Kern, Feb 21, 2005, in forum: C++
    Replies:
    4
    Views:
    573
    Karl Heinz Buchegger
    Feb 22, 2005
Loading...

Share This Page