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