Calculator  Step 4
parse.hpp
Go to the documentation of this file.
1 #ifndef PARSE_HPP_
2 #define PARSE_HPP_
3 
4 #include <cstdlib>
5 #include <istream>
6 #include <locale>
7 #include <ostream>
8 #include <string>
9 
10 #include "calc_error.hpp"
11 #include "node.hpp"
12 
25 class parser
26 {
27 public:
31  enum kind : int { eof, identifier, number,
32  plus='+', minus='-', times='*', slash='/', lparen = '(', rparen=')', equal='=',
33  comma=','};
34 
38  parser(std::istream& input);
39 
51  bool get_statement(std::ostream& output);
52 
53 private:
58  std::string charify(char c);
64  bool get_number(std::string const& token, node& result);
69  bool get_expr(node& result);
77  bool get_add_expr(node& result);
85  bool get_mul_expr(node& result);
96  bool get_primary(node& result);
104  bool get_unary(node& result);
117  void get_definition(std::string& name, identifier_list& parameters, node& definition);
129  kind get_token(std::string& token);
134  void get_identifier(std::string& identifier);
138  void get_expr_list(node_list& result);
139 
148  template<class OutputIterator>
149  OutputIterator get_namelist(OutputIterator output);
150 
156  void push_back(std::string const& token, kind k);
157 
162  bool isalpha(char c) const { return ctype_.is(ctype_.alpha, c); }
167  bool isalnum(char c) const { return ctype_.is(ctype_.alnum, c); }
172  bool isdigit(char c) const { return ctype_.is(ctype_.digit, c); }
177  bool isprint(char c) const { return ctype_.is(ctype_.print, c); }
178 
179  std::istream& input_;
180  std::ctype<char> const& ctype_;
181  std::string token_;
183 };
184 
190 void parse_loop(std::istream& input, std::ostream& output);
191 
192 template<class OutputIterator>
193 OutputIterator parser::get_namelist(OutputIterator output)
194 {
195  std::string token{};
196  while (kind k = get_token(token)) {
197  if (k == ')')
198  return output;
199  else if (k != identifier)
200  throw syntax_error{"expected function parameter, got " + token};
201  else {
202  *output = token;
203  ++output;
204 
205  k = get_token(token);
206  if (k == ')')
207  return output;
208  if (k != ',')
209  throw syntax_error{"expected comma in function paramter list, got " + token};
210  }
211  }
212  throw syntax_error{"unexpected end of line in function parameter list"};
213 }
214 
215 
216 #endif
void parse_loop(std::istream &input, std::ostream &output)
Definition: parse.cpp:338
bool isprint(char c) const
Definition: parse.hpp:177
bool get_expr(node &result)
Definition: parse.cpp:208
parser(std::istream &input)
Definition: parse.cpp:10
void get_identifier(std::string &identifier)
Definition: parse.cpp:41
std::string charify(char c)
Definition: parse.cpp:17
Definition: node.hpp:26
void get_definition(std::string &name, identifier_list &parameters, node &definition)
Definition: parse.cpp:157
void push_back(std::string const &token, kind k)
Definition: parse.cpp:60
bool get_statement(std::ostream &output)
Definition: parse.cpp:178
Definition: parse.hpp:25
bool get_primary(node &result)
Definition: parse.cpp:293
std::vector< std::string > identifier_list
A sequence of identifiers (e.g., parameter names).
Definition: node.hpp:19
OutputIterator get_namelist(OutputIterator output)
Definition: parse.hpp:193
bool get_unary(node &result)
Definition: parse.cpp:251
bool isalpha(char c) const
Definition: parse.hpp:162
kind get_token(std::string &token)
Definition: parse.cpp:69
std::string token_
One token push-back.
Definition: parse.hpp:181
std::istream & input_
Share the input stream.
Definition: parse.hpp:179
kind kind_
The kind of token that was pushed back.
Definition: parse.hpp:182
kind
Definition: parse.hpp:31
std::vector< node > node_list
A sequence of nodes.
Definition: node.hpp:13
bool get_number(std::string const &token, node &result)
Definition: parse.cpp:146
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
Definition: parse.hpp:180
bool get_mul_expr(node &result)
Definition: parse.cpp:232
bool get_add_expr(node &result)
Definition: parse.cpp:213
void get_expr_list(node_list &result)
Definition: parse.cpp:272
bool isalnum(char c) const
Definition: parse.hpp:167
bool isdigit(char c) const
Definition: parse.hpp:172