4 * Created on: Aug 26, 2012
14 bool Tokenizer::HasMore() {
15 if (isPutback) return true;
17 if (!in) return false;
19 putback = ReadToken();
21 if (!skipComments || putback.type != Token::COMMENT) return true;
23 while (in && putback.type == Token::COMMENT) {
24 putback = ReadToken();
27 return putback.type != Token::COMMENT;
30 void Tokenizer::ScanSpace() {
31 std::istream::char_type c;
33 while (in && std::isspace(c)) {
44 void Tokenizer::Putback(const Token &t) {
46 throw LexerError(line, "Tokenizer: double putback not supported");
53 const Tokenizer::Token &Tokenizer::Peek() {
61 Tokenizer::Token Tokenizer::GetNext() {
63 throw LexerError(line, "read beyond last token");
73 Tokenizer::Token Tokenizer::ReadToken() {
75 std::istream::char_type c;
78 case Token::ANGLE_BRACKET_OPEN:
79 case Token::ANGLE_BRACKET_CLOSE:
80 case Token::CHEVRON_OPEN:
81 case Token::CHEVRON_CLOSE:
84 case Token::BRACKET_OPEN:
85 case Token::BRACKET_CLOSE:
86 case Token::PARENTHESIS_OPEN:
87 case Token::PARENTHESIS_CLOSE:
88 return Token ((Token::Type) c);
90 case '0': case '1': case '2': case '3': case '4':
91 case '5': case '6': case '7': case '8': case '9':
99 std::istream::char_type c2;
102 return ReadComment();
103 } else if (c2 == '*') {
104 return ReadMultilineComment();
106 throw LexerError(line, std::string("Tokenizer: cannot parse token: ") + c + c2 + ": expected / or *");
113 Token t(ReadIdentifier());
114 if (std::isupper(c)) {
115 t.type = Token::TYPE_NAME;
116 } else if (std::islower(c)) {
119 throw LexerError(line, std::string("Tokenizer: cannot parse token: ") + c);
126 Tokenizer::Token Tokenizer::ReadNumber() {
127 Token t(Token::NUMBER);
128 bool isNegative(false);
130 std::istream::char_type c;
134 } else if (c != '+') {
139 if (!std::isdigit(c)) {
147 if (isNegative) t.number *= -1;
152 Tokenizer::Token Tokenizer::ReadString() {
153 Token t(Token::STRING);
156 std::istream::char_type c;
159 throw LexerError(line, "Tokenizer: strings must begin with '\"'");
167 t.str.push_back('\n');
170 t.str.push_back('\r');
173 t.str.push_back('\t');
179 } else if (c == '"') {
181 } else if (c == '\\') {
191 Tokenizer::Token Tokenizer::ReadIdentifier() {
192 Token t(Token::IDENTIFIER);
194 std::istream::char_type c;
196 if (std::isalnum(c) || c == '_') {
207 Tokenizer::Token Tokenizer::ReadComment() {
208 std::istream::char_type c;
209 while (in.get(c) && c != '\n');
211 return Token(Token::COMMENT);
214 Tokenizer::Token Tokenizer::ReadMultilineComment() {
215 std::istream::char_type c;
218 std::istream::char_type c2;
219 if (in.get(c2) && c2 == '/') {
222 } else if (c == '\n') {
226 return Token(Token::COMMENT);
229 bool Tokenizer::CheckKeyword(Token &t) {
230 if (t.str == "export") {
231 t.type = Token::KEYWORD_EXPORT;
233 } else if (t.str == "false") {
234 t.type = Token::KEYWORD_FALSE;
236 } else if (t.str == "include") {
237 t.type = Token::KEYWORD_INCLUDE;
239 } else if (t.str == "true") {
240 t.type = Token::KEYWORD_TRUE;