Calculator  Step 6
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
parser Class Reference

#include <parse.hpp>

Public Types

enum  kind : int {
  eof, identifier, integer, floating_point,
  string, plus ='+', minus ='-', times ='*',
  slash ='/', lparen = '(', rparen =')', equal ='=',
  comma =','
}
 

Public Member Functions

 parser (std::istream &input)
 
bool get_statement (std::ostream &output)
 

Private Member Functions

std::string charify (char c)
 
bool get_float (std::string const &token, node &result)
 
bool get_integer (std::string const &token, node &result)
 
bool get_expr (node &result)
 
bool get_add_expr (node &result)
 
bool get_mul_expr (node &result)
 
bool get_primary (node &result)
 
bool get_unary (node &result)
 
void get_definition (std::string &name, identifier_list &parameters, node &definition)
 
kind get_token (std::string &token)
 
void get_identifier (std::string &identifier)
 
void get_expr_list (node_list &result)
 
template<class OutputIterator >
OutputIterator get_namelist (OutputIterator output)
 
void get_escape (std::string &str)
 
void get_string (std::string &result, char delimiter)
 
void push_back (std::string const &token, kind k)
 
bool isalpha (char c) const
 
bool isalnum (char c) const
 
bool isdigit (char c) const
 
bool isprint (char c) const
 

Private Attributes

std::istream & input_
 Share the input stream. More...
 
std::ctype< char > const & ctype_
 Cache the ctype facet for checking character categories. More...
 
std::string token_
 One token push-back. More...
 
kind kind_
 The kind of token that was pushed back. More...
 

Detailed Description

Parser class template. The parser reads tokens from an input stream. A token can be a keyword, numeric literal, identifier, or symbol (operator or punctuator). Symbols can have multiple characters (e.g., :=).

Because the recursive-descent parser can examine too many tokens from the input stream, it keeps a push-back token. Once the parser knows it has gone too far, it pushes back the most recently read token. The next call to get_token() retrieves the pushed-back token.

Only one push-back is available, which limits the complexity of the syntax.

Definition at line 26 of file parse.hpp.

Member Enumeration Documentation

enum parser::kind : int

Token kind. Declare a name for each single-character token, to ensure the enumerated type can represent any operator or punctuator character.

Enumerator
eof 
identifier 
integer 
floating_point 
string 
plus 
minus 
times 
slash 
lparen 
rparen 
equal 
comma 

Definition at line 32 of file parse.hpp.

Constructor & Destructor Documentation

parser::parser ( std::istream &  input)

Constructor. Save the input stream.

Parameters
inputThe input stream

Definition at line 10 of file parse.cpp.

11 : input_(input),
12  ctype_(std::use_facet<std::ctype<char> >(input.getloc())),
13  token_(),
14  kind_()
15 {}
std::string token_
One token push-back.
Definition: parse.hpp:204
std::istream & input_
Share the input stream.
Definition: parse.hpp:202
kind kind_
The kind of token that was pushed back.
Definition: parse.hpp:205
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
Definition: parse.hpp:203

Member Function Documentation

std::string parser::charify ( char  c)
private

Convert a characer to a readable form.

Parameters
cThe character
Returns
A C++-style character literal that ensures c is readable.

Definition at line 17 of file parse.cpp.

References isprint().

Referenced by get_identifier(), and get_token().

18 {
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"('\\')";
28 
29  if (isprint(c))
30  return std::string{"\'"} + std::string(1,c) + "\'";
31  else {
32  std::ostringstream stream{};
33  stream << "'\\x" << std::hex;
34  stream.fill('0');
35  stream.width(2);
36  stream << (std::char_traits<char>::to_int_type(c) & 0xFF) << '\'';
37  return stream.str();
38  }
39 }
bool isprint(char c) const
Definition: parse.hpp:200
bool parser::get_add_expr ( node result)
private

Parse an addition expression

ADD_EXPR ::= MUL_EXPR | ADD_EXPR + MUL_EXPR | ADD_EXPR - MUL_EXPR
Parameters
resultStore the result here
Returns
true to continue parsing or false to stop (end of file or error)

Definition at line 312 of file parse.cpp.

References get_mul_expr(), get_token(), and push_back().

Referenced by get_expr().

313 {
314  if (not get_mul_expr(result))
315  return false;
316  std::string token{};
317  while (kind k = get_token(token)) {
318  if (k != '+' and k != '-') {
319  push_back(token, k);
320  return true;
321  } else {
322  node right{};
323  if (not get_mul_expr(right))
324  throw syntax_error{"unterminated expression. Expected a multiplicative-expression after " + token};
325  result = node(result, k, right);
326  }
327  }
328  return true;
329 }
Definition: node.hpp:28
void push_back(std::string const &token, kind k)
Definition: parse.cpp:121
kind get_token(std::string &token)
Definition: parse.cpp:130
kind
Definition: parse.hpp:32
bool get_mul_expr(node &result)
Definition: parse.cpp:331
void parser::get_definition ( std::string &  name,
identifier_list parameters,
node definition 
)
private

Parse a function or variable definition A variable is just like a function that takes no parameters.

DEFINITION ::= DEF IDENTIFIER OPT_PARAMETERS '=' EXPR
OPT_PARAMETERS ::= emtpy | '(' OPT_IDENTIFIER_LIST ')'
OPT_IDENTIFIER_LIST ::=  empty | IDENTIFIER_LIST
IDENTIFIER_LIST ::= IDENTIFIER | IDENTIFIER_LIST ',' IDENTIFIER
Parameters
[out]nameStore the variable or function name here
[out]parametersStore the list of parameter names here
[out]definitionStore the definition expression here

Definition at line 241 of file parse.cpp.

References get_expr(), get_namelist(), get_token(), and identifier.

Referenced by get_statement().

242 {
243  // Define a variable.
244  kind k = get_token(name);
245  if (k != identifier)
246  throw syntax_error{"expected IDENTIFIER, got " + name};
247 
248  std::string token{};
249  k = get_token(token);
250  if (k == '(') {
251  get_namelist(std::back_inserter(parameters));
252  k = get_token(token);
253  }
254 
255  if (k != '=')
256  throw syntax_error{"expected = in definition, got " + token};
257 
258  if (not get_expr(definition))
259  throw syntax_error{"expected exprssion in assignment"};
260 }
bool get_expr(node &result)
Definition: parse.cpp:307
OutputIterator get_namelist(OutputIterator output)
Definition: parse.hpp:216
kind get_token(std::string &token)
Definition: parse.cpp:130
kind
Definition: parse.hpp:32
void parser::get_escape ( std::string &  str)
private

Interpret a backslash escape sequence. The caller must have read the backslash already.

Parameters
[out]strWrite the string equivalent of the escape sequence at the end of this string

Definition at line 41 of file parse.cpp.

References ctype_, and input_.

Referenced by get_string().

42 {
43  char c;
44  if (not input_.get(c))
45  throw syntax_error{"incomplete escape"};
46  if (c == '\n')
47  return;
48 
49  if (c == 'a')
50  str += '\a';
51  else if (c == 'b')
52  str += '\b';
53  else if (c == 'n')
54  str += '\n';
55  else if (c == 'f')
56  str += '\f';
57  else if (c == 'r')
58  str += '\r';
59  else if (c == 't')
60  str += '\t';
61  else if (c == 'v')
62  str += '\v';
63  else if (c == 'x') {
64  // hexadecimal sequence
65  std::string digits{};
66  while(input_.get(c) and ctype_.is(ctype_.xdigit, c))
67  digits += c;
68  if (input_)
69  input_.unget();
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') {
73  // octal sequence
74  std::string digits{};
75  for (int i = 0; i < 3 and input_.get(c) and c >= '0' and c <= '7'; ++i)
76  digits += c;
77  if (input_ or c < '0' or c > '7')
78  input_.unget();
79  int value{std::stoi(digits, nullptr, 8)};
80  str += static_cast<char>(static_cast<unsigned char>(value));
81  } else {
82  str += c;
83  }
84 }
std::istream & input_
Share the input stream.
Definition: parse.hpp:202
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
Definition: parse.hpp:203
bool parser::get_expr ( node result)
private

Parse an expression

Parameters
resultStore the result here
Returns
true to continue parsing or false to stop (end of file or error)

Definition at line 307 of file parse.cpp.

References get_add_expr().

Referenced by get_definition(), get_expr_list(), get_primary(), and get_statement().

308 {
309  return get_add_expr(result);
310 }
bool get_add_expr(node &result)
Definition: parse.cpp:312
void parser::get_expr_list ( node_list result)
private

Parse a comma-separated expression list.

Parameters
[out]resultStore the result here

Definition at line 371 of file parse.cpp.

References get_expr(), get_token(), and push_back().

Referenced by get_primary().

372 {
373  result.clear();
374  std::string token{};
375  while (kind k = get_token(token)) {
376  if (k == ')')
377  return;
378  push_back(token, k);
379  node expr{};
380  if (not get_expr(expr))
381  throw syntax_error{"unexpected end of line in function argument"};
382  result.push_back(expr);
383  k = get_token(token);
384  if (k == ')')
385  return;
386  else if (k != ',')
387  throw syntax_error{"expected comma in argument list, got " + token};
388  }
389  throw syntax_error{"unexpected end of line in function argument list"};
390 }
bool get_expr(node &result)
Definition: parse.cpp:307
Definition: node.hpp:28
void push_back(std::string const &token, kind k)
Definition: parse.cpp:121
kind get_token(std::string &token)
Definition: parse.cpp:130
kind
Definition: parse.hpp:32
bool parser::get_float ( std::string const &  token,
node result 
)
private

Parse a floating number.

Parameters
tokenThe token to parse
resultStore the number here
Returns
true if token is a valid number or false for an error

Definition at line 230 of file parse.cpp.

Referenced by get_primary().

231 {
232  std::istringstream stream{token};
233  // If the value overflows or is otherwise invalid, return false.
234  double value{};
235  if (not (stream >> value))
236  return false;
237  result = node{number{value}};
238  return true;
239 }
Definition: node.hpp:28
void parser::get_identifier ( std::string &  identifier)
private

Parse an identifer.

Parameters
identifierStore the identifier here.
Precondition
first input character is alphabetic

Definition at line 102 of file parse.cpp.

References charify(), input_, isalnum(), and isalpha().

Referenced by get_token().

103 {
104  identifier.clear();
105  char c{};
106  if (not input_.get(c))
107  return;
108  if (not isalpha(c))
109  throw syntax_error{"expected alphabetic, got " + charify(c)};
110  identifier += c;
111  while (input_.get(c)) {
112  if (not isalnum(c)) {
113  input_.unget();
114  return;
115  }
116  identifier += c;
117  }
118  return;
119 }
std::string charify(char c)
Definition: parse.cpp:17
bool isalpha(char c) const
Definition: parse.hpp:185
std::istream & input_
Share the input stream.
Definition: parse.hpp:202
bool isalnum(char c) const
Definition: parse.hpp:190
bool parser::get_integer ( std::string const &  token,
node result 
)
private

Parse an integer.

Parameters
tokenThe token to parse
resultStore the number here
Returns
true if token is a valid number or false for an error

Definition at line 219 of file parse.cpp.

Referenced by get_primary().

220 {
221  std::istringstream stream{token};
222  // If the value overflows or is otherwise invalid, return false.
223  long long value{};
224  if (not (stream >> value))
225  return false;
226  result = node{number{value}};
227  return true;
228 }
Definition: node.hpp:28
bool parser::get_mul_expr ( node result)
private

Parse a multiplicative expression.

MUL_EXPR ::= UNARY | MUL_EXPR + UNARY | MUL_EXPR - UNARY
Parameters
resultStore the result here
Returns
true to continue parsing or false to stop (end of file or error)

Definition at line 331 of file parse.cpp.

References get_token(), get_unary(), and push_back().

Referenced by get_add_expr().

332 {
333  if (not get_unary(result))
334  return false;
335  std::string token{};
336  while (kind k = get_token(token)) {
337  if (k != '*' and k != '/') {
338  push_back(token, k);
339  return true;
340  } else {
341  node right{};
342  if (not get_unary(right))
343  throw syntax_error{"unterminated expression. Expected a unary-expression after " + token};
344  result = node(result, k, right);
345  }
346  }
347  return true;
348 }
Definition: node.hpp:28
void push_back(std::string const &token, kind k)
Definition: parse.cpp:121
bool get_unary(node &result)
Definition: parse.cpp:350
kind get_token(std::string &token)
Definition: parse.cpp:130
kind
Definition: parse.hpp:32
template<class OutputIterator >
OutputIterator parser::get_namelist ( OutputIterator  output)
private

Parse a list of parameter names. Names are identifiers, separated by commas. The list can be empty. This is a template so the container type is unimportant. Any output iterator will do.

Parameters
[out]outputStore the identifiers here
Returns
a copy of output after storing all the identifiers

Definition at line 216 of file parse.hpp.

References get_token(), and identifier.

Referenced by get_definition().

217 {
218  std::string token{};
219  while (kind k = get_token(token)) {
220  if (k == ')')
221  return output;
222  else if (k != identifier)
223  throw syntax_error{"expected function parameter, got " + token};
224  else {
225  *output = token;
226  ++output;
227 
228  k = get_token(token);
229  if (k == ')')
230  return output;
231  if (k != ',')
232  throw syntax_error{"expected comma in function paramter list, got " + token};
233  }
234  }
235  throw syntax_error{"unexpected end of line in function parameter list"};
236 }
kind get_token(std::string &token)
Definition: parse.cpp:130
kind
Definition: parse.hpp:32
bool parser::get_primary ( node result)
private

Parse a primary expression.

PRIMARY ::= NUMBER | IDENTIFIER | '(' EXPR ')' | FUNCTION_CALL
FUNCTION_CALL ::= IDENTIFIER '(' OPT_EXPR_LIST ')'
OPT_EXPR_LIST ::= empty | EXPR_LIST
EXPR_LIST ::= EXPR | EXPR_LIST ',' EXPR
Parameters
resultStore the result here
Returns
true to continue parsing or false to stop (end of file or error)

Definition at line 392 of file parse.cpp.

References eof, floating_point, get_expr(), get_expr_list(), get_float(), get_integer(), get_token(), identifier, integer, and push_back().

Referenced by get_unary().

393 {
394  std::string token{};
395  kind k = get_token(token);
396  if (k == eof)
397  return false;
398 
399  if (k == '(') {
400  // Parenthesized expression
401  if (not get_expr(result))
402  throw syntax_error{"expected expression, got end of line"};
403  k = get_token(token);
404  if (k != ')')
405  throw syntax_error{"expected ')', got " + token};
406  else
407  return true;
408  }
409 
410  if (k == integer) {
411  // Integer literal
412  if (not get_integer(token, result))
413  throw syntax_error{"Invalid integer literal: " + token};
414  return true;
415  }
416 
417  if (k == floating_point) {
418  // Integer literal
419  if (not get_float(token, result))
420  throw syntax_error{"Invalid integer literal: " + token};
421  return true;
422  }
423 
424  if (k == identifier) {
425  // Identifier: variable or function call
426  std::string next{};
427  k = get_token(next);
428  if (k == '(') {
429  // function call
430  node_list arguments{};
431  get_expr_list(arguments);
432  result = node{std::move(token), std::move(arguments)};
433  } else {
434  static const node_list no_arguments;
435  // Variable reference or function call with no arguments
436  push_back(next, k);
437  result = node{std::move(token), no_arguments};
438  }
439  return true;
440  }
441  throw syntax_error{"expected a primary, got " + token};
442 }
bool get_expr(node &result)
Definition: parse.cpp:307
Definition: node.hpp:28
void push_back(std::string const &token, kind k)
Definition: parse.cpp:121
bool get_integer(std::string const &token, node &result)
Definition: parse.cpp:219
kind get_token(std::string &token)
Definition: parse.cpp:130
bool get_float(std::string const &token, node &result)
Definition: parse.cpp:230
kind
Definition: parse.hpp:32
std::vector< node > node_list
A sequence of nodes.
Definition: node.hpp:15
void get_expr_list(node_list &result)
Definition: parse.cpp:371
bool parser::get_statement ( std::ostream &  output)

Read one statement and store the parse tree in result. If the statement is an assignment or function definition, store the variable or function. If the statement is an expression, print the result to output.

STATEMENT ::= DEFINITION | QUIT | EXPR | SAVE | LOAD
SAVE ::= "save" FILENAME
LOAD ::= "load" FILENAME
FILENAME ::= quoted-string
Parameters
outputThe output stream.
Returns
true to continue or false to end the loop
Exceptions
parse_errorfor various syntax and other errors

Definition at line 262 of file parse.cpp.

References eof, node::evaluate(), get_definition(), get_expr(), get_token(), identifier, load_library(), push_back(), save_library(), and set_function().

263 {
264  std::string token{};
265  kind k(get_token(token));
266  if (k == eof)
267  return false;
268 
269  if (k == identifier and token == "def") {
270  node definition{};
271  identifier_list parameters{};
272  get_definition(token, parameters, definition);
273  set_function(token, node{std::move(parameters), definition});
274  return true;
275  }
276 
277  if (k == identifier and token == "quit")
278  std::exit(0);
279 
280  if (k == identifier and token == "save") {
281  std::string filename{};
282  if (get_token(filename) != string)
283  throw syntax_error{"expected FILENAME after save, got " + token};
284  save_library(filename);
285  output << "Library saved to " << filename << '\n';
286  }
287 
288  if (k == identifier and token == "load") {
289  std::string filename{};
290  if (get_token(filename) != string)
291  throw syntax_error{"expected FILENAME after load, got " + token};
292  load_library(filename);
293  output << "Library loaded from " << filename << '\n';
294  }
295  // Otherwise, the statement must be an expression.
296  push_back(token, k);
297  node n{};
298  if (not get_expr(n))
299  return false;
300  else {
301  // Evaluate the expression and print the result.
302  output << n.evaluate() << '\n';
303  return true;
304  }
305 }
void load_library(std::string const &filename)
Definition: variables.cpp:100
bool get_expr(node &result)
Definition: parse.cpp:307
void save_library(std::string const &filename)
Definition: variables.cpp:79
Definition: node.hpp:28
void get_definition(std::string &name, identifier_list &parameters, node &definition)
Definition: parse.cpp:241
void push_back(std::string const &token, kind k)
Definition: parse.cpp:121
std::vector< std::string > identifier_list
A sequence of identifiers (e.g., parameter names).
Definition: node.hpp:21
kind get_token(std::string &token)
Definition: parse.cpp:130
void set_function(std::string const &name, node value)
Definition: variables.cpp:74
number evaluate() const
Definition: node.cpp:73
kind
Definition: parse.hpp:32
void parser::get_string ( std::string &  result,
char  delimiter 
)
private

Parse a quoted string. The caller passes the quote character in the delimiter argument.

Parameters
[out]resultStore the token here.
[in]delimiterThe quote character (' or ")

Definition at line 86 of file parse.cpp.

References get_escape(), and input_.

Referenced by get_token().

87 {
88  char c{};
89  while (input_.get(c)) {
90  if (c == delimiter)
91  return;
92  else if (c == '\\')
93  get_escape(result);
94  else if (c == '\n')
95  throw syntax_error{"unterminated string"};
96  else
97  result += c;
98  }
99  throw syntax_error{"unterminated string"};
100 }
std::istream & input_
Share the input stream.
Definition: parse.hpp:202
void get_escape(std::string &str)
Definition: parse.cpp:41
parser::kind parser::get_token ( std::string &  token)
private

Parse a token. A token can be a keyword, a literal or a symbol.

TOKEN ::= IDENTIFIER | NUMBER | SYMBOL | STRING
IDENTIIFER ::= ALPHA (ALPHA | DIGIT)*
NUMBER ::= INTEGER | FLOATING-POINT
INTEGER ::= DIGIT+
FLOATING_POINT ::= DIGIT+ '.' DIGITS+ ('E' SIGN? DIGITS+)? | DIGIT+ ('.' DIGITS+)? 'E' SIGN? DIGITS+
SYMBOL ::= '+' | '-' | '*' | '/' | '%' | '(' | ')' | '=' | ','
Parameters
tokenStore the text of the token here.
Returns
the token kind

Definition at line 130 of file parse.cpp.

References charify(), eof, floating_point, get_identifier(), get_string(), identifier, input_, integer, isalpha(), kind_, string, and token_.

Referenced by get_add_expr(), get_definition(), get_expr_list(), get_mul_expr(), get_namelist(), get_primary(), get_statement(), and get_unary().

131 {
132  if (not token_.empty())
133  {
134  kind result(kind_);
135  token = token_;
136 
137  token_.clear();
138  kind_ = eof;
139 
140  return result;
141  }
142 
143  char c{};
144  if (not (input_ >> c)) {
145  token = "end of line";
146  return eof;
147  }
148  if (isalpha(c)) {
149  input_.unget();
150  get_identifier(token);
151  return identifier;
152  }
153 
154  if (c == '\'' or c == '"') {
155  // Quoted string
156  token.clear();
157  get_string(token, c);
158  return string;
159  }
160 
161  // Get a numeric literal.
162  token.clear();
163  if (c == '+' or c == '-' or c == '*' or c == '/' or c == '%' or c == '(' or c == ')' or c == '=' or c == ',') {
164  token += c;
165  return static_cast<kind>(c);
166  }
167 
168  if (c < '0' or c > '9') {
169  input_.unget();
170  throw syntax_error{"expected digit, got " + charify(c)};
171  }
172 
173  kind k = integer;
174 
175  while (c >= '0' and c <= '9') {
176  token += c;
177  if (not input_.get(c))
178  return k;
179  }
180  if (c == '.') {
181  k = floating_point;
182  token += c;
183  if (not input_.get(c))
184  throw syntax_error{"unterminated number: expected digit after the decimal point"};
185  if (c < '0' or c > '9') {
186  input_.unget();
187  throw syntax_error{"expected digit after decimal point, got " + charify(c)};
188  }
189  while (c >= '0' and c <= '9') {
190  token += c;
191  if (not input_.get(c))
192  return k;
193  }
194  }
195  if (c == 'e' or c == 'E') {
196  k = floating_point;
197  token += c;
198  if (not input_.get(c))
199  throw syntax_error{"unterminated number: expected digit in the exponent"};
200  if (c == '-' or c == '+') {
201  token += c;
202  if (not input_.get(c))
203  throw syntax_error{"unterminated number: expected digit after sign in the exponent"};
204  }
205  if (c < '0' or c > '9') {
206  input_.unget();
207  throw syntax_error{"expected digit in the exponent, got " + charify(c)};
208  }
209  while (c >= '0' and c <= '9') {
210  token += c;
211  if (not input_.get(c))
212  return k;
213  }
214  }
215  input_.unget();
216  return k;
217 }
void get_string(std::string &result, char delimiter)
Definition: parse.cpp:86
void get_identifier(std::string &identifier)
Definition: parse.cpp:102
std::string charify(char c)
Definition: parse.cpp:17
bool isalpha(char c) const
Definition: parse.hpp:185
std::string token_
One token push-back.
Definition: parse.hpp:204
std::istream & input_
Share the input stream.
Definition: parse.hpp:202
kind kind_
The kind of token that was pushed back.
Definition: parse.hpp:205
kind
Definition: parse.hpp:32
bool parser::get_unary ( node result)
private

Parse a unary expression.

UNARY ::= '-' PRIMARY | '+' PRIMARY | PRIMARY
Parameters
resultStore the result here
Returns
true to continue parsing or false to stop (end of file or error)

Definition at line 350 of file parse.cpp.

References eof, get_primary(), get_token(), and push_back().

Referenced by get_mul_expr().

351 {
352  std::string token{};
353  kind k = get_token(token);
354  if (k == eof)
355  return false;
356  if (k == '-') {
357  if (not get_primary(result))
358  throw syntax_error{"expected primary after unary " + token + ", got end of line"};
359  result = node(k, result);
360  return true;
361  } else if (k == '+') {
362  if (not get_primary(result))
363  throw syntax_error{"expected primary after unary +, got end of line"};
364  return true;
365  } else {
366  push_back(token, k);
367  return get_primary(result);
368  }
369 }
Definition: node.hpp:28
void push_back(std::string const &token, kind k)
Definition: parse.cpp:121
bool get_primary(node &result)
Definition: parse.cpp:392
kind get_token(std::string &token)
Definition: parse.cpp:130
kind
Definition: parse.hpp:32
bool parser::isalnum ( char  c) const
inlineprivate

Return true if c is alphanumeric. Use the locale of the input stream.

Parameters
cThe character to test.

Definition at line 190 of file parse.hpp.

References ctype_.

Referenced by get_identifier().

190 { return ctype_.is(ctype_.alnum, c); }
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
Definition: parse.hpp:203
bool parser::isalpha ( char  c) const
inlineprivate

Return true if c is alphabetic. Use the locale of the input stream.

Parameters
cThe character to test.

Definition at line 185 of file parse.hpp.

References ctype_.

Referenced by get_identifier(), and get_token().

185 { return ctype_.is(ctype_.alpha, c); }
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
Definition: parse.hpp:203
bool parser::isdigit ( char  c) const
inlineprivate

Return true if c is a digit. Use the locale of the input stream.

Parameters
cThe character to test.

Definition at line 195 of file parse.hpp.

References ctype_.

195 { return ctype_.is(ctype_.digit, c); }
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
Definition: parse.hpp:203
bool parser::isprint ( char  c) const
inlineprivate

Return true if c is printable. Use the locale of the input stream.

Parameters
cThe character to test.

Definition at line 200 of file parse.hpp.

References ctype_.

Referenced by charify().

200 { return ctype_.is(ctype_.print, c); }
std::ctype< char > const & ctype_
Cache the ctype facet for checking character categories.
Definition: parse.hpp:203
void parser::push_back ( std::string const &  token,
kind  k 
)
private

Push back a token. The next call to get_token() will return the pushed-back token.

Parameters
tokenThe token to push back.
kThe kind of token being pushed back

Definition at line 121 of file parse.cpp.

References eof, kind_, and token_.

Referenced by get_add_expr(), get_expr_list(), get_mul_expr(), get_primary(), get_statement(), and get_unary().

122 {
123  kind_ = k;
124  if (kind_ == eof)
125  token_ = "end of line";
126  else
127  token_ = token;
128 }
std::string token_
One token push-back.
Definition: parse.hpp:204
kind kind_
The kind of token that was pushed back.
Definition: parse.hpp:205

Member Data Documentation

std::ctype<char> const& parser::ctype_
private

Cache the ctype facet for checking character categories.

Definition at line 203 of file parse.hpp.

Referenced by get_escape(), isalnum(), isalpha(), isdigit(), and isprint().

std::istream& parser::input_
private

Share the input stream.

Definition at line 202 of file parse.hpp.

Referenced by get_escape(), get_identifier(), get_string(), and get_token().

kind parser::kind_
private

The kind of token that was pushed back.

Definition at line 205 of file parse.hpp.

Referenced by get_token(), and push_back().

std::string parser::token_
private

One token push-back.

Definition at line 204 of file parse.hpp.

Referenced by get_token(), and push_back().


The documentation for this class was generated from the following files: