double statement() { Token t = ts.get(); switch(t.kind) { case sqrt_kind: return func(sqrt_kind); case power_kind: return func(power_kind); case let: return declaration(); case name: return assign(t.name); default: ts.unget(t); return expression(); } }
// deal with numbers and parentheses double primary() { Token t = ts.get(); switch (t.kind) { case '(': case '{': // handle '(' expression ')' { double d = expression(); t = ts.get(); if (t.kind != ')' && t.kind !='}') error("')' or '}' expected"); return d; } case '8': // we use '8' to represent a number return t.value; // return the number's value default: error("primary expected"); } }
double declaration() { Token t = ts.get(); if (t.kind != VAR) { ts.end(); error ("Valid name expected in declaration"); } string name = t.name; Token t2 = ts.get(); if (t2.kind != '=') { ts.end(); error("'=' missing in declaration of " ,name); } double d = expression(); variables.set_value(name, d); return d; }
double prim(bool get) { if (get) ts.get(); switch (ts.current().kind) { case Kind::number: { double v = ts.current().number_value; ts.get(); return v; } case Kind::name: { double &v = table[ts.current().string_value]; if (ts.get().kind == Kind::assign) v = expr(true); return v; } case Kind::minus: { return -prim(true); } case Kind::lp: { auto e = expr(true); if (ts.current().kind != Kind::rp) return error("'(' expected"); } default: return error("primary expected"); } }
//------------------------------------------------------------------------------ void calculate() { double val = 0; while (cin) try { cout << prompt; Token t = ts.get(); while (t.kind == print) t=ts.get(); // first discard all “prints” if (t.kind == quit) return; ts.putback(t); cout << result << statement() << '\n'; } catch (exception& e) { cerr << e.what() << '\n'; // write error message clean_up_mess(); } }
// Put the next token into the token stream. Returns // true if scanning succeeded. inline bool Lexer::scan(Token_stream& ts) { if (Token tok = scan()) { ts.put(tok); return true; } return false; }
double expression() { // deal we A+B and A-B double left = term(); while(true) { Token t = ts.get(); // get the next Token from the stream switch(t.kind) { case '+': left += term(); break; case '-': left -= term(); break; default: ts.unget(t); // put the Token back onto the stream (we did not do any action here) return left; } } }
// check for a suffix after an expression (so far, only factorial) and evaluate. double suffix(double expression) { Token t=ts.get(); switch(t.kind) { case '!': // factorial (non-recursive algorithm) { int intexpr=(int)expression; if(intexpr<0) error("cannot take the factorial of a negative number"); if(intexpr<2) return 1; int fact=intexpr; for(int i=intexpr;i>1;fact*=--i); // FORE return fact; } default: ts.putback(t); return expression; } }
void calculate() { while(cin) { try { cout << prompt; Token t = ts.get(); while (t.kind == print) t = ts.get(); if (t.kind == quit) return; ts.unget(t); cout << result << statement() << endl; } catch(exception &e) { cerr << e.what() << endl; clean_up_mess(); } } }
double pow(){ // Multiplies n by n m times Token t = ts.get(); if (t.kind == '(') { double lval = expression(); int rval = 0; t = ts.get(); if(t.kind == ',') rval = narrow_cast<int>(primary()); else error("Second argument is not provided"); double result = 1; for(double i = 0; i < rval; i++) { result*=lval; } t = ts.get(); if (t.kind != ')') error("')' expected"); // If there wasn't any ')' return an error return result; } else error("'(' expected"); // If there wasn't any ')' return an error }
double expression() // Performs '+' and '-' operations { double left = term(); // Get the number or the result of calculations in term while(true) { Token t = ts.get(); switch(t.kind) { case '+': left += term(); // Addition break; case '-': left -= term(); // Subtraction break; default: ts.unget(t); // If nothing was done return character to the stream return left; // Return the new or unchanged value of 'left' } } }
double expression() { double left = term(); while(true) { Token t = ts.get(); switch(t.kind) { case '+': left += term(); break; case '-': left -= term(); break; default: ts.unget(t); return left; } } }
double declaration(Token k) // Taken from: http://www.stroustrup.com/Programming/Solutions/Ch7/e7-1.cpp // handle: name = expression // declare a variable called "name" with the initial value "expression" // k will be "let" or "con"(stant) { Token t = ts.get(); if (t.kind != name) error ("name expected in declaration"); string var_name = t.name; Token t2 = ts.get(); if (t2.kind != '=') error("= missing in declaration of ", var_name); double d = expression(); sym_table.declare(var_name,d,k.kind==let); return d; }
// deal with numbers and parentheses double primary1() { Token t = ts.get(); switch (t.kind) { case '(': // handle '(' expression ')' { double d = expression(); t = ts.get(); if (t.kind != ')') error("')' expected"); else { t = ts.get(); if (t.kind == '!') d = factorial(d); else ts.putback(t); } return d; } case '{': // handle '(' expression ')' { double d = expression(); t = ts.get(); if (t.kind != '}') error("'}' expected"); else { t = ts.get(); if (t.kind == '!') d = factorial(d); else ts.putback(t); } return d; } case '8': // we use '8' to represent a number { double d = t.value; t = ts.get(); if (t.kind == '!') d = factorial(d); else ts.putback(t); return d; // return the number's value } default: error("primary expexted"); } }
double Symbol_table::define_name(char type) // Defines a variable { Token t = ts.get(); // Get a character from the stream if (t.kind != 'a') error ("name expected in declaration"); // If there is no name return an error string name = t.name; // Read the name in 'name' if (is_declared(name)) error(name, " declared twice"); // Check if the variable had been already declared Token t2 = ts.get(); // Get a character from the stream if (t2.kind != '=') error("= missing in definition of " ,name); /* If there is no '=' symbol used to assign a value to the variable return an error */ double d = expression(); // Process the provided value switch(type) { case let: names.push_back(Variable(name,d)); // Add new variable to a vector return d; // Return the value of new variable case constant: names.push_back(Variable(name,d,constant)); // Add new constant to a vector return d; // Return the value of new constant } }
void calculate(Token_stream& ts) { const string prompt = "> "; const string result = "= "; while (cin) { try { cout << prompt; Token t = ts.get(); while (t.kind == print) t = ts.get(); if (t.kind == quit) return; ts.putback(t); cout << result << statement(ts) << endl; } catch (exception& e) { cerr << e.what() << endl; clean_up_mess(ts); } } }
double primary() { Token t = ts.get(); switch(t.kind) { case '(': // '(' Expression ')'を処理する { double d = expression(); t = ts.get(); if(t.kind != ')') error("')' expected"); return d; } case '8': // '8'を使って数字を表す return t.value; // 数字の値を返す case 'q': // 追加 keep_window_open("~0"); exit(EXIT_SUCCESS); default: error("primary expected"); } }
double assign(string var_name) { const Token t {ts.get()}; if (t.kind != '=') error("= missing in the assignment of " + var_name); double d {expression()}; set_value(var_name, d); return d; }
double primary() { Token t = ts.get(); switch (t.kind) { case '(': { double d = expression(); t = ts.get(); if (t.kind != ')') error("'(' expected"); } case '-': return -primary(); case number: return t.value; case name: return get_value(t.name); default: error("primary expected"); } }
// deal with numbers and parentheses 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 '-': // so can use negative numbers return -primary(); case '8': // we use '8' to represent a number return t.value; // return the number's value default: error("primary expected"); return 0; //compile warning without wont get here } }
void calculate() { while(true) try { cout << prompt; Token t = ts.get(); while (t.kind == print) t=ts.get(); if (t.kind == quit) return; ts.unget(t); cout << result << statement() << endl; } catch(runtime_error& e) { cerr << e.what() << endl; cerr << "Enter \'" << print << "\' to try again\n"; clean_up_mess(); cout << endl; } }
double expression(){ double left = term(); // Termを読み取って評価する Token t = ts.get(); // 次のトークンを取得する while(true){ // +または-を探す switch(t.kind){ case '+': left += term(); // Termを評価して足す t = ts.get(); break; case '-': left -= term(); // Termを評価して引く t = ts.get(); break; default: ts.putback(t); return left; // +または-はもう残っていないので、答えを返す } } }
double primary(){ Token t = ts.get(); switch(t.kind){ case '(': // '(' Expression ')'を処理する { double d = expression(); t = ts.get(); if(t.kind != ')') error("')' expected"); return d; } case number: // 数字を表す return t.value; // 数字の値を返す case '-': return -primary(); case '+': return primary(); default: error("primary expected"); } }
double primary() { Token t = ts.get(); switch (t.kind) { case '(': { double d = expression(); t = ts.get(); if (t.kind != ')') error("')' expected"); return d; } case '-': return - primary(); case number: return t.value; // 数字トークンの場合は値を返す case name: return get_value(t.name); // 名前トークンの場合は変数の値を返す default: error("primary expected"); } }
double expression() { double left = term(); // read and evaluate a Term Token t = ts.get(); // get the next token while (true) { switch (t.kind) { case '+': left += term(); // evaluate Term and add t = ts.get(); break; case '-': left -= term(); // evaluate Term and subtract t = ts.get(); break; default: ts.putback(t); // put t back into the token stream return left; // finally: no more + or -; return the answer } } }
// deal with numbers and parentheses 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 '8': // we use '8' to represent a number return t.value; // return the number's value case quit: keep_window_open(); exit(EXIT_SUCCESS); default: error("primary expected"); } }
double primary() { Token t = ts.get(); switch (t.kind) { case '(': { double d = expression(); t = ts.get(); if (t.kind != ')') error("expected ')'"); return d; } case '{': { double d = expression(); t = ts.get(); if (t.kind != '}') error("expected '}'"); return d; } case number: return t.value; case '-': return - primary(); case '+': return primary(); case name: { Token next = ts.get(); if (next.kind == '=') { double d = expression(); sym_table.set(t.name,d); return d; } else { ts.putback(next); return sym_table.get(t.name); } } default: error("primary expected"); } }
double primary() { Token t = ts.get(); switch(t.kind) { case '(': { double val = expression(); t = ts.get(); if (t.kind != ')') error ("Closing parenthesis expected, but not found"); return val; } case '{': { double val = expression(); t = ts.get(); if(t.kind != '}') error ("Closing brace expected, but not found"); return val; } case '-': // unary minus return - primary(); case '+': return primary(); case '8': return t.value; case NAME: return get_value(t.name); default: error("primary: Primary expected, but found something else"); } // can never reach here cerr << "Should never reach here" << endl; return 0; }
int main() { try { double val = 0; while (cin) { Token t = ts.get(); if (t.kind == 'q') break; if (t.kind == ';') cout << "= " << val << '\n'; else ts.putback(t); val = expression(); } } catch (exception& e) { cerr << e.what() << endl; return 1; } catch (...) { cerr << "exception \n"; return 2; } }
// deal with numbers and parentheses 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 number: return t.value; // return the number's value case '-': return - primary(); case '+': return primary(); default: error("primary expected"); } }