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 00010 class node; 00011 00013 class parse_error : public std::runtime_error { 00014 public: 00015 parse_error(std::string const& msg) : runtime_error(msg) {} 00016 }; 00017 00030 class parser 00031 { 00032 public: 00036 enum kind { eof, identifier, number, 00037 plus='+', minus='-', times='*', slash='/', lparen = '(', rparen=')', equal='=' }; 00038 00042 parser(std::istream& input); 00043 00049 bool get_expr(node& result); 00050 00051 private: 00056 std::string charify(char c); 00062 bool get_number(std::string const& token, node& result); 00070 bool get_add_expr(node& result); 00078 bool get_mul_expr(node& result); 00086 bool get_primary(node& result); 00094 bool get_unary(node& result); 00106 kind get_token(std::string& token); 00111 void get_identifier(std::string& identifier); 00112 00118 void push_back(std::string const& token, kind k) { token_ = token; kind_ = k; } 00119 00124 bool isalpha(char c) const { return ctype_.is(ctype_.alpha, c); } 00129 bool isalnum(char c) const { return ctype_.is(ctype_.alnum, c); } 00134 bool isdigit(char c) const { return ctype_.is(ctype_.digit, c); } 00139 bool isprint(char c) const { return ctype_.is(ctype_.print, c); } 00140 00141 std::istream& input_; 00142 std::ctype<char> const& ctype_; 00143 std::string token_; 00144 kind kind_; 00145 }; 00146 00152 void parse_loop(std::istream& input, std::ostream& output); 00153 00154 #endif