3 * Implementation of GiNaC's lexer. */
6 * GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 /// Skip to the end of line
34 static int skipline(std::istream* s);
35 /// Skip to the next non-whitespace character
36 static int skipspace(std::istream* s, int c, std::size_t& line);
37 /// Check if the identifier is predefined literal
38 static bool literal_p(const std::string& name);
40 /// gettok - Return the next token from standard input.
43 // Skip any whitespace.
44 c = skipspace(input, c, line_num);
46 // identifier: [a-zA-Z][a-zA-Z0-9_]*
51 if ( isalnum(c) || c=='_' )
56 if (unlikely(literal_p(str)))
57 return token_type::literal;
59 return token_type::identifier;
62 // Number: [0-9]+([.][0-9]*(eE[+-][0-9]+)*)*
63 if (isdigit(c) || c == '.') {
68 } while (isdigit(c) || c == '.');
69 if (c == 'E' || c == 'e') {
79 return token_type::number;
82 // Comment until end of line.
90 // Check for end of file. Don't eat the EOF.
92 return token_type::eof;
94 // Otherwise, just return the character as its ascii value.
100 static int skipline(std::istream* s)
105 } while (c != EOF && c != '\n' && c != '\r');
109 static int skipspace(std::istream* s, int c, std::size_t& line)
119 static bool literal_p(const std::string& name)
123 else if (name == "Pi")
125 else if (name == "Euler")
127 else if (name == "Catalan")
133 lexer::lexer(std::istream* in, std::ostream* out, std::ostream* err)
158 void lexer::switch_input(std::istream* in)
166 /// Symbolic name of current token (for error reporting)
167 std::string lexer::tok2str(const int tok) const
170 case lexer::token_type::identifier:
171 case lexer::token_type::number:
172 return std::string("\"") + str + "\"";
173 case lexer::token_type::eof:
174 return std::string("EOF");
176 return std::string("\"") + char(tok) + "\"";