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