Token Problem in Calculator

Hi!,

I am doing the exercises in Stroustrup's book, Programming: Principles and Practice Using C++. The 6th chapter uses a simple calculator to demonstrate Tokens and grammars. I realize that there are many calculator questions in the forum, but each seems to deal with a different issue. I did not find one that dealt with mine. An exercise is to add factorial capability to the calculator. That would involve altering the grammar and the tokens.

I added the exclamation point (!) to the token stream so that it would be recognized as a valid token as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Token Token_stream::get()
{
    if (full) {       // do we already have a Token ready?
        // remove token from buffer
        full=false;
        return buffer;
    } 

    char ch;
    cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

    switch (ch) {
    case '=':    // for "print"
    case 'x':   // for "quit"
	case '(': case ')': case '+': case '-': case '*': case '/': case '{': case '}': case '!':
        return Token(ch);        // let each character represent itself
    case '.':
    case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
        {    
            cin.putback(ch);         // put digit back into the input stream
            double val;
            cin >> val;              // read a floating-point number
            return Token('8',val);   // let '8' represent "a number"
        }
    default:
        error("Bad token");
    }
}


I then added the exclamation point to the grammar list so that the expression would be recognized, as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
double primary()
{
    Token t = ts.get();
    switch (t.kind) {
    case '(':    // handle '(' expression ')'
        {    
            double d = expression();
            t = ts.get();
            if (t.kind != ')') error("')' expected");
            return d;
        }
    case '{':    // handle '(' expression ')'
        {    
            double d = expression();
            t = ts.get();
			if (t.kind != '}') error("'}' expected");
            return d;
        }

    case '!':     // handle '!' expression
	{
	    double d = expression();
	    t = ts.get();
	    return d;
	}

    case '8':            // we use '8' to represent a number
        return t.value;  // return the number's value
    default:
        error("primary expected");
    }
}

However, when I try to compute a factorial, I receive the 'Error: Primary expected' message. This means to me that the case of ! is not being recognized so the default (error) is being executed.

Has anyone completed this exercise? Can you show me how to add the factorial case to this calculator? Thanks very much.
Last edited on
like you are doing there the ! operator comes before the expression
In BNF: prim ::= '!' expr
you want it the other way round ( prim ::= expr '!' )
Topic archived. No new replies allowed.