C++プログラミング言語計算機ソースコード 7788 ワード C+ まず教科書が最初に出てきたソースコードで、実行できます.#include "pch.h" #include #include #include #include #include using namespace std; enum Token_value{ NAME,NUMBER,END, PLUS='+',MINUS='-',MUL='*',DIV='/', PRINT=';',ASSIGN='=',LP='(',RP=')' }; Token_value curr_tok = PRINT; int no_of_errors; double term(bool get); string string_value; double number_value; double error(const string&s) { no_of_errors++; cout << "error" << s << ''; return 1; } 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; default: if (isalpha(ch)) { string_value = ch; while (cin.get(ch) && isalnum(ch)); string_value.push_back(ch); return curr_tok = NAME; } error("bad token"); return curr_tok = PRINT; return curr_tok = NUMBER; } } double expr(bool get) { double left = term(get); for(;;) switch (curr_tok) { case PLUS: left += term(true); break; case MINUS: left -= term(true); break; default: return left; } } double prim(bool get) { if (get) get_token(); switch (curr_tok) { case NUMBER: { double v = number_value; get_token(); return v; } case NAME: { double&v = number_value; if (get_token() == ASSIGN) v = expr(true); return v; } case MINUS: return -prim(true); case LP: { double e = expr(true); if (curr_tok != RP) return error(")needed"); get_token(); return e; } default: return error(" "); } } double term(bool get) { 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; } } istream* input; 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!"); return 1; } while (*input) { get_token(); if (curr_tok == END)break; if (curr_tok == PRINT) continue; cout << expr(false) << ''; } if (input != &cin) delete input; return no_of_errors; } ネーミングスペースと例外処理コンテンツを追加した究極のバージョン#include "pch.h" #include #include #include #include #include using namespace std; namespace Error { struct Zero_divide { }; struct Syntax_error { const char*p; Syntax_error(const char*q) { p = q; } }; struct Range_error { int i; Range_error(int ii) { i = ii; } }; } namespace Parser { using namespace Error; double expr(bool get); double prim(bool get); double term(bool get); } namespace Lexer { enum Token_value { NAME, NUMBER, END, PLUS = '+', MINUS = '-', MUL = '*', DIV = '/', PRINT = ';', ASSIGN = '=', LP = '(', RP = ')' }; Token_value curr_tok = PRINT; Token_value get_token(); string string_value; double number_value; }; double Parser::expr(bool get) { using Lexer::curr_tok; using Lexer::PLUS; using Lexer::MINUS; double left = term(get); for (;;) switch (curr_tok) { case PLUS: left += term(true); break; case MINUS: left -= term(true); break; default: return left; } } double Parser::prim(bool get) { if (get) Lexer::get_token(); switch (Lexer::curr_tok) { case Lexer::NUMBER: { double v = Lexer::number_value; Lexer::get_token(); return v; } case Lexer::NAME: { double&v = Lexer::number_value; if (Lexer::get_token() == Lexer::ASSIGN) v = expr(true); return v; } case Lexer::MINUS: return -prim(true); case Lexer::LP: { double e = expr(true); if (Lexer::curr_tok != Lexer::RP) throw Error::Syntax_error(" "); Lexer::get_token(); return e; } default: throw Error::Syntax_error(" "); } } double Parser::term(bool get) { double left = prim(get); for (;;) switch (Lexer::curr_tok) { case Lexer::MUL: left *= prim(true); break; case Lexer::DIV: if (double d = prim(true)) { left /= d; break; } throw Error::Zero_divide(); default: return left; } } Lexer::Token_value Lexer::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)) { string_value = ch; while (cin.get(ch) && isalnum(ch)); string_value.push_back(ch); return curr_tok = NAME; } throw Error::Syntax_error("bad token"); return curr_tok = PRINT; return curr_tok = NUMBER; } } // 。 namespace Driver { int no_of_errors; istream* input; void skip(); } void Driver::skip() { //skip , 。 no_of_errors++; while (*input) { char ch; input->get(ch); switch (ch) { case'': case';': return; } } } int main(int argc, char* argv[]) { try { switch (argc) { case 1: { Driver::input = &cin; break; } case 2: { Driver::input = new istringstream(argv[1]); break; } default: throw Error::Range_error(1); } } catch (Error::Range_error) { cout << "too many"; Lexer::curr_tok = Lexer::PRINT; } /*using namespace Lexer; using namespace Parser; while (*Driver::input) try{ get_token(); if (curr_tok == END)break; if (curr_tok == PRINT) continue; cout << expr(false) << ''; } catch(Error::Zero_divide){ cerr << " 。"; if (Lexer::curr_tok != Lexer::PRINT)Driver::skip(); //skip() 。 } catch(Error::Syntax_error e){ cerr << " 。" << e.p << ''; if (Lexer::curr_tok != Lexer::PRINT)Driver::skip(); } if (Driver::input != &cin) delete Driver::input; // 。 return Driver::no_of_errors;*/ bool in_error = false; // , , 。 while (*Driver::input) { try { Lexer::get_token(); if (Lexer::curr_tok == Lexer::END)break; if (Lexer::curr_tok == Lexer::PRINT) { in_error = false; continue; } if (in_error == false)cout << Parser::expr(false) << ''; } catch (Error::Zero_divide) { cerr << " "; in_error = true; } catch (Error::Syntax_error e) { cerr << " :" << e.p << ''; in_error = true; cout << "error "; } if (Driver::input != &cin) delete Driver::input; // 。 return Driver::no_of_errors; } } Alexaスキル検討(社員情報検索) リモートのバックアップとmysqlのリストア