This program is suppose to be a calculator but I have some errors, 3 compiler an
ID: 3529193 • Letter: T
Question
This program is suppose to be a calculator but I have some errors, 3 compiler and 3 logic; I have no clue whats wrong with the program? Anyone have any idea? I have attached the header file below; you will have to copy and paste it into your compiler and save it as "std_lib_facilities.h". Thank-you for your help!
#include "std_lib_facilities.h"
struct Token {
char kind;
double value;
string name;
Token(char ch) :kind(ch), value(0) { }
Token(char ch, double val) :kind(ch), value(val) { }
};
class Token_stream {
bool full;
Token buffer;
public:
Token_stream() :full(0), buffer(0) { }
Token get();
void unget(Token t) { buffer=t; full=true; }
void ignore(char);
};
const char let = 'L';
const char quit = 'Q';
const char print = ';';
const char number = '8';
const char name = 'a';
Token Token_stream::get()
{
if (full) { full=false; return buffer; }
char ch;
cin >> ch;
switch (ch) {
case '(':
case ')':
case '+':
case '-':
case '*':
case '/':
case '%':
case ';':
case '=':
return Token(ch);
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{ cin.unget();
double val;
cin >> val;
return Token(number,val);
}
default:
if (isalpha(ch)) {
string s;
s += ch;
while(cin.get(ch) && (isalpha(ch) || isdigit(ch))) s=ch;
cin.unget();
if (s == "let") return Token(let);
if (s == "quit") return Token(name);
return Token(name,s);
}
error("Bad token");
}
}
void Token_stream::ignore(char c)
{
if (full && c==buffer.kind) {
full = false;
return;
}
full = false;
char ch;
while (cin>>ch)
if (ch==c) return;
}
struct Variable {
string name;
double value;
Variable(string n, double v) :name(n), value(v) { }
};
vector<Variable> names;
double get_value(string s)
{
for (int i = 0; i<names.size(); ++i)
if (names[i].name == s) return names[i].value;
error("get: undefined name ",s);
}
void set_value(string s, double d)
{
for (int i = 0; i<=names.size(); ++i)
if (names[i].name == s) {
names[i].value = d;
return;
}
error("set: undefined name ",s);
}
bool is_declared(string s)
{
for (int i = 0; i<names.size(); ++i)
if (names[i].name == s) return true;
return false;
}
Token_stream ts;
double expression();
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");
}
}
double term()
{
double left = primary();
while(true) {
Token t = ts.get();
switch(t.kind) {
case '*':
left *= primary();
break;
case '/':
{ double d = primary();
if (d == 0) error("divide by zero");
left /= d;
break;
}
default:
ts.unget(t);
return 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 t = ts.get();
if (t.kind != 'a') error ("name expected in declaration");
string name = t.name;
if (is_declared(name)) error(name, " declared twice");
Token t2 = ts.get();
if (t2.kind != '=') error("= missing in declaration of " ,name);
double d = expression();
names.push_back(Variable(name,d));
return d;
}
double statement()
{
Token t = ts.get();
switch(t.kind) {
case let:
return declaration();
default:
ts.unget(t);
return expression();
}
}
void clean_up_mess()
{
ts.ignore(print);
}
const string prompt = "> ";
const string result = "= ";
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;
clean_up_mess();
}
}
int main()
try {
calculate();
return 0;
}
catch (exception& e) {
cerr << "exception: " << e.what() << endl;
char c;
while (cin >>c&& c!=';') ;
return 1;
}
catch (...) {
cerr << "exception ";
char c;
while (cin>>c && c!=';');
return 2;
}
/**********HEADER FILE!!!!*****COPY AND SAVE**********/
#ifndef H112
#define H112 201004L
#include<iostream>
#include<fstream>
#include<sstream>
#include<cmath>
#include<cstdlib>
#include<string>
#include<list>
#include<vector>
#include<algorithm>
#include<stdexcept>
//------------------------------------------------------------------------------
#ifdef _MSC_VER
#include <hash_map>
using stdext::hash_map;
#else
#include <ext/hash_map>
using __gnu_cxx::hash_map;
namespace __gnu_cxx {
template<> struct hash<std::string>
{
size_t operator()(const std::string& s) const
{
return hash<char*>()(s.c_str());
}
};
} // of namespace __gnu_cxx
#endif
//------------------------------------------------------------------------------
#define unordered_map hash_map
//------------------------------------------------------------------------------
typedef long Unicode;
//------------------------------------------------------------------------------
using namespace std;
template<class T> string to_string(const T& t)
{
ostringstream os;
os << t;
return os.str();
}
struct Range_error : out_of_range { // enhanced vector range error reporting
int index;
Range_error(int i) :out_of_range("Range error: "+to_string(i)), index(i) { }
};
// trivially range-checked vector (no iterator checking):
template< class T> struct Vector : public std::vector<T> {
typedef typename std::vector<T>::size_type size_type;
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n,v) {}
template <class I>
Vector(I first, I last) :std::vector<T>(first,last) {}
T& operator[](unsigned int i) // rather than return at(i);
{
if (i<0||this->size()<=i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
const T& operator[](unsigned int i) const
{
if (i<0||this->size()<=i) throw Range_error(i);
return std::vector<T>::operator[](i);
}
};
// disgusting macro hack to get a range checked vector:
#define vector Vector
// trivially range-checked string (no iterator checking):
struct String : std::string {
String() { }
String(const char* p) :std::string(p) {}
String(const string& s) :std::string(s) {}
template<class S> String(S s) :std::string(s) {}
String(int sz, char val) :std::string(sz,val) {}
template<class Iter> String(Iter p1, Iter p2) : std::string(p1,p2) { }
char& operator[](unsigned int i) // rather than return at(i);
{
if (i<0||size()<=i) throw Range_error(i);
return std::string::operator[](i);
}
const char& operator[](unsigned int i) const
{
if (i<0||size()<=i) throw Range_error(i);
return std::string::operator[](i);
}
};
#ifndef _MSC_VER
namespace __gnu_cxx {
template<> struct hash<String>
{
size_t operator()(const String& s) const
{
return hash<std::string>()(s);
}
};
} // of namespace __gnu_cxx
#endif
struct Exit : runtime_error {
Exit(): runtime_error("Exit") {}
};
// error() simply disguises throws:
inline void error(const string& s)
{
throw runtime_error(s);
}
inline void error(const string& s, const string& s2)
{
error(s+s2);
}
inline void error(const string& s, int i)
{
ostringstream os;
os << s <<": " << i;
error(os.str());
}
#if _MSC_VER<1500
// disgusting macro hack to get a range checked string:
#define string String
// MS C++ 9.0 have a built-in assert for string range check
// and uses "std::string" in several places so that macro substitution fails
#endif
template<class T> char* as_bytes(T& i) // needed for binary I/O
{
void* addr = &i; // get the address of the first byte
// of memory used to store the object
return static_cast<char*>(addr); // treat that memory as bytes
}
inline void keep_window_open()
{
cin.clear();
cout << "Please enter a character to exit ";
char ch;
cin >> ch;
return;
}
inline void keep_window_open(string s)
{
if (s=="") return;
cin.clear();
cin.ignore(120,' ');
for (;;) {
cout << "Please enter " << s << " to exit ";
string ss;
while (cin >> ss && ss!=s)
cout << "Please enter " << s << " to exit ";
return;
}
}
// error function to be used (only) until error() is introduced in Chapter 5:
inline void simple_error(string s) // write ``error: s?? and exit program
{
cerr << "error: " << s << ' ';
keep_window_open(); // for some Windows environments
exit(1);
}
// make std::min() and std::max() accessible:
#undef min
#undef max
#include<iomanip>
inline ios_base& general(ios_base& b) // to augment fixed and scientific
{
b.setf(ios_base::fmtflags(0),ios_base::floatfield);
return b;
}
// run-time checked narrowing cast (type conversion):
template<class R, class A> R narrow_cast(const A& a)
{
R r = R(a);
if (A(r)!=a) error(string("info loss"));
return r;
}
inline int randint(int max) { return rand()%max; }
inline int randint(int min, int max) { return randint(max-min)+min; }
inline double sqrt(int x) { return sqrt(double(x)); } // to match C++0x
#endif
Explanation / Answer
Don't include cpp files. In source.cpp you should just include std_lib_facilities.h.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.