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, 00032 plus='+', minus='-', times='*', slash='/', lparen = '(', rparen=')', equal='=', 00033 comma=','}; 00034 00038 parser(std::istream& input); 00039 00051 bool get_statement(std::ostream& output); 00052 00053 private: 00058 std::string charify(char c); 00064 bool get_number(std::string const& token, node& result); 00069 bool get_expr(node& result); 00077 bool get_add_expr(node& result); 00085 bool get_mul_expr(node& result); 00096 bool get_primary(node& result); 00104 bool get_unary(node& result); 00117 void get_definition(std::string& name, identifier_list& parameters, node& definition); 00129 kind get_token(std::string& token); 00134 void get_identifier(std::string& identifier); 00138 void get_expr_list(node_list& result); 00139 00148 template<class OutputIterator> 00149 OutputIterator get_namelist(OutputIterator output); 00150 00156 void push_back(std::string const& token, kind k); 00157 00162 bool isalpha(char c) const { return ctype_.is(ctype_.alpha, c); } 00167 bool isalnum(char c) const { return ctype_.is(ctype_.alnum, c); } 00172 bool isdigit(char c) const { return ctype_.is(ctype_.digit, c); } 00177 bool isprint(char c) const { return ctype_.is(ctype_.print, c); } 00178 00179 std::istream& input_; 00180 std::ctype<char> const& ctype_; 00181 std::string token_; 00182 kind kind_; 00183 }; 00184 00190 void parse_loop(std::istream& input, std::ostream& output); 00191 00192 template<class OutputIterator> 00193 OutputIterator parser::get_namelist(OutputIterator output) 00194 { 00195 std::string token; 00196 while (kind k = get_token(token)) { 00197 if (k == ')') 00198 return output; 00199 else if (k != identifier) 00200 throw syntax_error("expected function parameter, got " + token); 00201 else { 00202 *output = token; 00203 ++output; 00204 00205 k = get_token(token); 00206 if (k == ')') 00207 return output; 00208 if (k != ',') 00209 throw syntax_error("expected comma in function paramter list, got " + token); 00210 } 00211 } 00212 throw syntax_error("unexpected end of line in function parameter list"); 00213 } 00214 00215 00216 #endif