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 int value{std::stoi(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 ==
',') {
165 return static_cast<kind>(c);
168 if (c < '0' or c >
'9') {
175 while (c >=
'0' and c <=
'9') {
184 throw syntax_error{
"unterminated number: expected digit after the decimal point"};
185 if (c < '0' or c >
'9') {
189 while (c >=
'0' and c <=
'9') {
195 if (c ==
'e' or c ==
'E') {
199 throw syntax_error{
"unterminated number: expected digit in the exponent"};
200 if (c ==
'-' or c ==
'+') {
203 throw syntax_error{
"unterminated number: expected digit after sign in the exponent"};
205 if (c < '0' or c >
'9') {
209 while (c >=
'0' and c <=
'9') {
221 std::istringstream stream{token};
224 if (not (stream >> value))
232 std::istringstream stream{token};
235 if (not (stream >> value))
256 throw syntax_error{
"expected = in definition, got " + token};
281 std::string filename{};
283 throw syntax_error{
"expected FILENAME after save, got " + token};
285 output <<
"Library saved to " << filename <<
'\n';
289 std::string filename{};
291 throw syntax_error{
"expected FILENAME after load, got " + token};
293 output <<
"Library loaded from " << filename <<
'\n';
318 if (k !=
'+' and k !=
'-') {
324 throw syntax_error{
"unterminated expression. Expected a multiplicative-expression after " + token};
325 result =
node(result, k, right);
337 if (k !=
'*' and k !=
'/') {
343 throw syntax_error{
"unterminated expression. Expected a unary-expression after " + token};
344 result =
node(result, k, right);
358 throw syntax_error{
"expected primary after unary " + token +
", got end of line"};
359 result =
node(k, result);
361 }
else if (k ==
'+') {
363 throw syntax_error{
"expected primary after unary +, got end of line"};
381 throw syntax_error{
"unexpected end of line in function argument"};
382 result.push_back(expr);
387 throw syntax_error{
"expected comma in argument list, got " + token};
389 throw syntax_error{
"unexpected end of line in function argument list"};
402 throw syntax_error{
"expected expression, got end of line"};
413 throw syntax_error{
"Invalid integer literal: " + token};
420 throw syntax_error{
"Invalid integer literal: " + token};
432 result =
node{std::move(token), std::move(arguments)};
437 result =
node{std::move(token), no_arguments};
450 for (output <<
"> "; std::getline(input, line); output <<
"> ") {
451 std::istringstream input{std::move(line)};
454 while (p.get_statement(output)) {
458 output << ex.what() <<
'\n';
459 }
catch(std::exception
const& ex) {
460 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_integer(std::string const &token, node &result)
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)
bool get_float(std::string const &token, node &result)
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.
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)