00001 #ifndef PARSE_HPP_
00002 #define PARSE_HPP_
00003
00004 #include <istream>
00005 #include <locale>
00006 #include <ostream>
00007 #include <stdexcept>
00008 #include <string>
00009 #include <vector>
00010
00011 #include "variables.hpp"
00012
00014 class parse_error : public std::runtime_error {
00015 public:
00016 parse_error(std::string const& msg) : runtime_error(msg) {}
00017 };
00018
00031 class parser
00032 {
00033 public:
00037 enum kind { eof, identifier, number,
00038 plus='+', minus='-', times='*', slash='/', lparen = '(', rparen=')', equal='=' };
00039
00043 parser(std::istream& input);
00044
00050 bool get_expr(double& result);
00051
00052 private:
00057 std::string charify(char c);
00063 bool get_number(std::string const& token, double& result);
00071 bool get_add_expr(double& result);
00079 bool get_mul_expr(double& result);
00087 bool get_primary(double& result);
00095 bool get_unary(double& result);
00107 kind get_token(std::string& token);
00112 void get_identifier(std::string& identifier);
00113
00119 void push_back(std::string const& token, kind k) { token_ = token; kind_ = k; }
00120
00125 bool isalpha(char c) const { return ctype_.is(ctype_.alpha, c); }
00130 bool isalnum(char c) const { return ctype_.is(ctype_.alnum, c); }
00135 bool isdigit(char c) const { return ctype_.is(ctype_.digit, c); }
00140 bool isprint(char c) const { return ctype_.is(ctype_.print, c); }
00141
00142 std::istream& input_;
00143 std::ctype<char> const& ctype_;
00144 std::string token_;
00145 kind kind_;
00146 };
00147
00153 void parse_loop(std::istream& input, std::ostream& output);
00154
00155 #endif