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) <<
'\'';
84 token =
"end of line";
95 if (c ==
'+' or c ==
'-' or c ==
'*' or c ==
'/' or c ==
'%' or c ==
'(' or c ==
')' or c ==
'=' or c ==
',') {
100 if (c < '0' or c >
'9') {
104 while (c >=
'0' and c <=
'9') {
112 throw syntax_error{
"unterminated number: expected digit after the decimal point"};
113 if (c < '0' or c >
'9') {
117 while (c >=
'0' and c <=
'9') {
123 if (c ==
'e' or c ==
'E') {
126 throw syntax_error{
"unterminated number: expected digit in the exponent"};
127 if (c ==
'-' or c ==
'+') {
130 throw syntax_error{
"unterminated number: expected digit after sign in the exponent"};
132 if (c < '0' or c >
'9') {
136 while (c >=
'0' and c <=
'9') {
148 std::istringstream stream{token};
151 if (not (stream >> value))
153 result =
node(value);
172 throw syntax_error{
"expected = in definition, got " + token};
219 if (k !=
'+' and k !=
'-') {
225 throw syntax_error{
"unterminated expression. Expected a multiplicative-expression after " + token};
226 result =
node(result, k, right);
238 if (k !=
'*' and k !=
'/') {
244 throw syntax_error{
"unterminated expression. Expected a unary-expression after " + token};
245 result =
node(result, k, right);
259 throw syntax_error{
"expected primary after unary " + token +
", got end of line"};
260 result =
node(k, result);
262 }
else if (k ==
'+') {
264 throw syntax_error{
"expected primary after unary +, got end of line"};
282 throw syntax_error{
"unexpected end of line in function argument"};
283 result.push_back(expr);
288 throw syntax_error{
"expected comma in argument list, got " + token};
290 throw syntax_error{
"unexpected end of line in function argument list"};
303 throw syntax_error{
"expected expression, got end of line"};
314 throw syntax_error{
"Invalid numeric literal: " + token};
326 result =
node{std::move(token), std::move(arguments)};
331 result =
node(std::move(token), no_arguments);
344 for (output <<
"> "; std::getline(input, line); output <<
"> ") {
345 std::istringstream input{std::move(line)};
348 while (p.get_statement(output)) {
352 output << ex.what() <<
'\n';
353 }
catch(std::exception
const& ex) {
354 output <<
"exception: " << ex.what() <<
'\n';
void parse_loop(std::istream &input, std::ostream &output)
bool isprint(char c) const
bool get_expr(node &result)
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)
bool get_mul_expr(node &result)
bool get_add_expr(node &result)
void get_expr_list(node_list &result)
bool isalnum(char c) const