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