00001 #ifndef PARSE_HPP_ 00002 #define PARSE_HPP_ 00003 00004 #include <cstdlib> 00005 #include <istream> 00006 #include <locale> 00007 #include <ostream> 00008 #include <string> 00009 00010 #include "calc_error.hpp" 00011 #include "node.hpp" 00012 #include "number.hpp" 00013 00026 class parser 00027 { 00028 public: 00032 enum kind { eof, identifier, integer, floating_point, string, 00033 plus='+', minus='-', times='*', slash='/', lparen = '(', rparen=')', equal='=', 00034 comma=','}; 00035 00039 parser(std::istream& input); 00040 00055 bool get_statement(std::ostream& output); 00056 00057 private: 00062 std::string charify(char c); 00068 bool get_float(std::string const& token, node& result); 00074 bool get_integer(std::string const& token, node& result); 00079 bool get_expr(node& result); 00087 bool get_add_expr(node& result); 00095 bool get_mul_expr(node& result); 00106 bool get_primary(node& result); 00114 bool get_unary(node& result); 00127 void get_definition(std::string& name, identifier_list& parameters, node& definition); 00141 kind get_token(std::string& token); 00146 void get_identifier(std::string& identifier); 00150 void get_expr_list(node_list& result); 00151 00160 template<class OutputIterator> 00161 OutputIterator get_namelist(OutputIterator output); 00166 void get_escape(std::string& str); 00172 void get_string(std::string& result, char delimiter); 00173 00179 void push_back(std::string const& token, kind k); 00180 00185 bool isalpha(char c) const { return ctype_.is(ctype_.alpha, c); } 00190 bool isalnum(char c) const { return ctype_.is(ctype_.alnum, c); } 00195 bool isdigit(char c) const { return ctype_.is(ctype_.digit, c); } 00200 bool isprint(char c) const { return ctype_.is(ctype_.print, c); } 00201 00202 std::istream& input_; 00203 std::ctype<char> const& ctype_; 00204 std::string token_; 00205 kind kind_; 00206 }; 00207 00213 void parse_loop(std::istream& input, std::ostream& output); 00214 00215 template<class OutputIterator> 00216 OutputIterator parser::get_namelist(OutputIterator output) 00217 { 00218 std::string token; 00219 while (kind k = get_token(token)) { 00220 if (k == ')') 00221 return output; 00222 else if (k != identifier) 00223 throw syntax_error("expected function parameter, got " + token); 00224 else { 00225 *output = token; 00226 ++output; 00227 00228 k = get_token(token); 00229 if (k == ')') 00230 return output; 00231 if (k != ',') 00232 throw syntax_error("expected comma in function paramter list, got " + token); 00233 } 00234 } 00235 throw syntax_error("unexpected end of line in function parameter list"); 00236 } 00237 00238 00239 #endif