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 00025 class parser 00026 { 00027 public: 00031 enum kind { eof, identifier, number, string, 00032 plus='+', minus='-', times='*', slash='/', lparen = '(', rparen=')', equal='=', 00033 comma=','}; 00034 00038 parser(std::istream& input); 00039 00054 bool get_statement(std::ostream& output); 00055 00056 private: 00061 std::string charify(char c); 00067 bool get_number(std::string const& token, node& result); 00072 bool get_expr(node& result); 00080 bool get_add_expr(node& result); 00088 bool get_mul_expr(node& result); 00099 bool get_primary(node& result); 00107 bool get_unary(node& result); 00120 void get_definition(std::string& name, identifier_list& parameters, node& definition); 00132 kind get_token(std::string& token); 00137 void get_identifier(std::string& identifier); 00141 void get_expr_list(node_list& result); 00142 00151 template<class OutputIterator> 00152 OutputIterator get_namelist(OutputIterator output); 00157 void get_escape(std::string& str); 00163 void get_string(std::string& result, char delimiter); 00164 00170 void push_back(std::string const& token, kind k); 00171 00176 bool isalpha(char c) const { return ctype_.is(ctype_.alpha, c); } 00181 bool isalnum(char c) const { return ctype_.is(ctype_.alnum, c); } 00186 bool isdigit(char c) const { return ctype_.is(ctype_.digit, c); } 00191 bool isprint(char c) const { return ctype_.is(ctype_.print, c); } 00192 00193 std::istream& input_; 00194 std::ctype<char> const& ctype_; 00195 std::string token_; 00196 kind kind_; 00197 }; 00198 00204 void parse_loop(std::istream& input, std::ostream& output); 00205 00206 template<class OutputIterator> 00207 OutputIterator parser::get_namelist(OutputIterator output) 00208 { 00209 std::string token; 00210 while (kind k = get_token(token)) { 00211 if (k == ')') 00212 return output; 00213 else if (k != identifier) 00214 throw syntax_error("expected function parameter, got " + token); 00215 else { 00216 *output = token; 00217 ++output; 00218 00219 k = get_token(token); 00220 if (k == ')') 00221 return output; 00222 if (k != ',') 00223 throw syntax_error("expected comma in function paramter list, got " + token); 00224 } 00225 } 00226 throw syntax_error("unexpected end of line in function parameter list"); 00227 } 00228 00229 00230 #endif