mir hat's mal wieder nach langer Zeit den Verstand geraubt...mit Bjarne Stroustrup Die C++ Programmierspache 3. Auflage
-
ich benutze
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
2.6.32-25-generic #45-Ubuntu SMP Sat Oct 16 19:48:22 UTC 2010 i686 GNU/Linuxund habe kapitel 6 folgenden Source-code abgepinnt, wird auch compiliert ohne Warunungen und Fehler...
[code]
/*
program:
END // END ist Eingabeende
expr_list ENDexpr_list:
expression PRINT // PRINT ist Semikolon
expression PRINT expr_listexpression:
expression + term
expression - term
termterm:
term / primary
term * primary
primaryprimary:
NUMBER
NAME
NAME = expression
- primary
( expression )
*/#include <iostream>
#include <string>
#include <map>
#include <cctype>using namespace std;
int no_of_errors;
double error( const string& s)
{
no_of_errors++;
cerr << "Fehler: " << s << endl;
return 1;
}enum token_value{
NAME, NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')'
};token_value curr_tok = PRINT;
double number_value;
string string_value;double expr( bool get);
double prim( bool get);
token_value get_token();
double error( const string& s);#if 0
Token_value get_token()
{
char ch = 0;
cin >> ch;switch( ch) {
case 0:
return curr_tok = END;
case ';':
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 '.':
cin.putback( ch);
cin >> number_value;
return curr_tok = NUMBER;
default:
if( isalpha( ch)) {
cin.putback( ch);
cin >> string_value;
return curr_tok = NAME;
}
error( "Falsches Token");
return curr_tok = PRINT;
}
}
#endiftoken_value get_token() // verbesserte eingabefunktion
{
char ch;do { // Überspringe Whitespace (Leerzeichen) außer '\n'
if( !cin.get( ch))
return curr_tok = END;
} 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 '.':
cin.putback(ch);
cin >> number_value;
return curr_tok=NUMBER;
default: // NAME, NAME= oder Fehler
if( isalpha( ch)) {
string_value = ch;
while( cin.get( ch) && isalnum( ch))
string_value += ch;
cin.putback( ch);
return curr_tok = NAME;
}
error( "Falsches Token");
return curr_tok = PRINT;
}
}map< string, double> table;
// return curr_tok=NUMBER;
double prim( bool get) // Behandelt primaries
{
if( get)
get_token();switch( curr_tok) {
case NUMBER: // Gleitkommakonstante (reele Zahl)
{
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: // Einstelliges Minus
return -prim( true);
case LP:
{
double e = expr(true);
if( curr_tok != RP)
return error( ") erwartet");
get_token(); // Verschlucke ')'
return e;
}
default:
return error( "primary erwartet");
}
}double term( bool get) // Multipliziere und dividiere
{
double left = prim( get);for(;;)
switch( curr_tok) {
case MUL:
left *= prim( true);
break;
case DIV:
if( double d = prim( true)) { // d != 0!!!
left /= d;
break;
}
return error( "Division durch 0");
default:
return left;
}
}double expr( bool get) // Addiere und subtrahiere
{
double left = term( get);for(;;) // forever Endlosschleife
switch( curr_tok) {
case PLUS:
left += term( true);
break;case MINUS:
left -= term( true);
break;
default:
return left;
}
}int main()
{
table["pi"] = 3.1415926535897932385; // vordefinierte Namen einfügen
table["e"] = 2.71828182845904590452354;while( cin) {
get_token();
if( curr_tok == END)
break;
if( curr_tok == PRINT)
continue;
cout << expr( false) << endl;
}
return no_of_errors;
}Wenn ich den Mist jetzt teste oder mit dem gdb laufen lassen, kommt folgendes:
5+6=
dc: stack empty
6+5;
dc: stack empty
4*9 (return)
+3 (return)(gdb) n
4
main () at dc.cc:223
223 while (cin) {
(gdb) n
224 get_token();
(gdb) n
+
225 if (curr_tok == END) break;
(gdb) n
226 if (curr_tok == PRINT) continue;
(gdb) nBreakpoint 1, main () at dc.cc:227
227 cout << expr(false) << '\n';
(gdb) n
error: primary expected
error: primary expected
2
223 while (cin) {
(gdb) n
224 get_token();
(gdb)ist jemand hier, der mir vielleicht sagen was ich da falsch gemacht habe?
verliere komplett die Übersicht, weil ich auch mit der Stackfehlermeldung nichts anfangen kann...vielen Dank
-
Du hast dein Programm nicht zufällig dc genannt?
-
Jetzt ist einiges klar.
-
An so einen einfachen fehler hab ich nicht gedacht, sollte mal mein OS besser kennnenlernen *schäm
-
Ist mir eine Zeit lang regelmäßig mit man: test(1) passiert.
-
Mir auch schon -)
Daher am besten immer lokal mittels "./prog" starten...