9 /// Skip to the end of line
10 static int skipline(std::istream* s);
11 /// Skip to the next non-whitespace character
12 static int skipspace(std::istream* s, int c, std::size_t& line);
13 /// Check if the identifier is predefined literal
14 static bool literal_p(const std::string& name);
16 /// gettok - Return the next token from standard input.
19 // Skip any whitespace.
20 c = skipspace(input, c, line_num);
22 // identifier: [a-zA-Z][a-zA-Z0-9]*
32 if (unlikely(literal_p(str)))
33 return token_type::literal;
35 return token_type::identifier;
38 // Number: [0-9]+([.][0-9]*(eE[+-][0-9]+)*)*
39 if (isdigit(c) || c == '.') {
44 } while (isdigit(c) || c == '.');
45 if (c == 'E' || c == 'e') {
55 return token_type::number;
58 // Comment until end of line.
66 // Check for end of file. Don't eat the EOF.
68 return token_type::eof;
70 // Otherwise, just return the character as its ascii value.
76 static int skipline(std::istream* s)
81 } while (c != EOF && c != '\n' && c != '\r');
85 static int skipspace(std::istream* s, int c, std::size_t& line)
95 static bool literal_p(const std::string& name)
99 else if (name == "Pi")
101 else if (name == "Euler")
103 else if (name == "Catalan")
109 lexer::lexer(std::istream* in, std::ostream* out, std::ostream* err)
134 void lexer::switch_input(std::istream* in)
142 /// Symbolic name of current token (for error reporting)
143 std::string lexer::tok2str(const int tok) const
146 case lexer::token_type::identifier:
147 case lexer::token_type::number:
148 return std::string("\"") + str + "\"";
149 case lexer::token_type::eof:
150 return std::string("EOF");
152 return std::string("\"") + char(tok) + "\"";