12 ctype_(std::use_facet<std::ctype<char> >(input.getloc())),
19 if (c ==
'\a')
return R
"('\a')";
20 if (c ==
'\b')
return R
"('\b')";
21 if (c ==
'\f')
return R
"('\f')";
22 if (c ==
'\n')
return R
"('\n')";
23 if (c ==
'\r')
return R
"('\r')";
24 if (c ==
'\t')
return R
"('\t')";
25 if (c ==
'\v')
return R
"('\v')";
26 if (c ==
'\'')
return R
"('\'')";
27 if (c ==
'\\')
return R
"('\\')";
30 return std::string{
"\'"} + std::string(1,c) +
"\'";
32 std::ostringstream stream{};
33 stream <<
"'\\x" << std::hex;
36 stream << (std::char_traits<char>::to_int_type(c) & 0xFF) <<
'\'';
70 unsigned long value{std::stoul(digits,
nullptr, 16)};
71 str +=
static_cast<char>(
static_cast<unsigned char>(value));
72 }
else if (c >=
'0' and c <=
'7') {
75 for (
int i = 0; i < 3 and
input_.get(c) and c >=
'0' and c <=
'7'; ++i)
77 if (
input_ or c < '0' or c >
'7')
79 unsigned long value{std::stoul(digits,
nullptr, 8)};
80 str +=
static_cast<char>(
static_cast<unsigned char>(value));
145 token =
"end of line";
154 if (c ==
'\'' or c ==
'"') {
163 if (c ==
'+' or c ==
'-' or c ==
'*' or c ==
'/' or c ==
'%' or c ==
'(' or c ==
')' or c ==
'=' or c ==
',') {
168 if (c < '0' or c >
'9') {
172 while (c >=
'0' and c <=
'9') {
180 throw syntax_error(
"unterminated number: expected digit after the decimal point");
181 if (c < '0' or c >
'9') {
185 while (c >=
'0' and c <=
'9') {
191 if (c ==
'e' or c ==
'E') {
194 throw syntax_error(
"unterminated number: expected digit in the exponent");
195 if (c ==
'-' or c ==
'+') {
198 throw syntax_error(
"unterminated number: expected digit after sign in the exponent");
200 if (c < '0' or c >
'9') {
204 while (c >=
'0' and c <=
'9') {
216 std::istringstream stream(token);
219 if (not (stream >> value))
221 result =
node(value);
240 throw syntax_error(
"expected = in definition, got " + token);
265 std::string filename;
267 throw syntax_error(
"expected FILENAME after save, got " + token);
269 output <<
"Library saved to " << filename <<
'\n';
273 std::string filename;
275 throw syntax_error(
"expected FILENAME after load, got " + token);
277 output <<
"Library loaded from " << filename <<
'\n';
302 if (k !=
'+' and k !=
'-') {
308 throw syntax_error{
"unterminated expression. Expected a multiplicative-expression after " + token};
309 result =
node(result, k, right);
321 if (k !=
'*' and k !=
'/') {
327 throw syntax_error{
"unterminated expression. Expected a unary-expression after " + token};
328 result =
node(result, k, right);
342 throw syntax_error{
"expected primary after unary " + token +
", got end of line"};
343 result =
node(k, result);
345 }
else if (k ==
'+') {
347 throw syntax_error{
"expected primary after unary +, got end of line"};
365 throw syntax_error{
"unexpected end of line in function argument"};
366 result.push_back(expr);
371 throw syntax_error{
"expected comma in argument list, got " + token};
373 throw syntax_error{
"unexpected end of line in function argument list"};
386 throw syntax_error{
"expected expression, got end of line"};
397 throw syntax_error{
"Invalid numeric literal: " + token};
409 result =
node{std::move(token), std::move(arguments)};
414 result =
node{std::move(token), no_arguments};
427 for (output <<
"> "; std::getline(input, line); output <<
"> ") {
428 std::istringstream input{std::move(line)};
435 output << ex.what() <<
'\n';
436 }
catch(std::exception
const& ex) {
437 output <<
"exception: " << ex.what() <<
'\n';
void load_library(std::string const &filename)
void get_string(std::string &result, char delimiter)
void parse_loop(std::istream &input, std::ostream &output)
bool isprint(char c) const
bool get_expr(node &result)
void save_library(std::string const &filename)
parser(std::istream &input)
void get_identifier(std::string &identifier)
std::string charify(char c)
void get_definition(std::string &name, identifier_list ¶meters, node &definition)
void push_back(std::string const &token, kind k)
bool get_statement(std::ostream &output)
bool get_primary(node &result)
std::vector< std::string > identifier_list
A sequence of identifiers (e.g., parameter names).
OutputIterator get_namelist(OutputIterator output)
bool get_unary(node &result)
bool isalpha(char c) const
kind get_token(std::string &token)
std::string token_
One token push-back.
void set_function(std::string const &name, node value)
std::istream & input_
Share the input stream.
kind kind_
The kind of token that was pushed back.
std::vector< node > node_list
A sequence of nodes.
bool get_number(std::string const &token, node &result)
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
bool get_mul_expr(node &result)
bool get_add_expr(node &result)
void get_expr_list(node_list &result)
bool isalnum(char c) const
void get_escape(std::string &str)