// And get the token
// This actually handles EOF internally too.
- for (const State *state = start(options); state != NULL;
- state = state->handle(*this)) {
- // Do nothing here. All is handled in the for cycle header itself.
+ const State* state = start(options);
+ if (state != NULL) {
+ state->handle(*this);
}
// Make sure a token was produced. Since this Can Not Happen, we assert
// here instead of throwing.
public:
CRLF() {}
virtual ~CRLF() {} // see the base class for the destructor
- virtual const State* handle(MasterLexer& lexer) const {
+ virtual void handle(MasterLexer& lexer) const {
// We've just seen '\r'. If this is part of a sequence of '\r\n',
// we combine them as a single END-OF-LINE. Otherwise we treat the
// single '\r' as an EOL and continue tokeniziation from the character
}
getLexerImpl(lexer)->token_ = Token(Token::END_OF_LINE);
getLexerImpl(lexer)->last_was_eol_ = true;
- return (NULL);
}
};
public:
String() {}
virtual ~String() {} // see the base class for the destructor
- virtual const State* handle(MasterLexer& lexer) const;
+ virtual void handle(MasterLexer& lexer) const;
};
class QString : public State {
public:
QString() {}
virtual ~QString() {} // see the base class for the destructor
- virtual const State* handle(MasterLexer& lexer) const;
+ virtual void handle(MasterLexer& lexer) const;
};
// We use a common instance of a each state in a singleton-like way to save
}
}
-const State*
+void
String::handle(MasterLexer& lexer) const {
std::vector<char>& data = getLexerImpl(lexer)->data_;
data.clear();
getLexerImpl(lexer)->source_->ungetChar();
getLexerImpl(lexer)->token_ =
MasterLexer::Token(&data.at(0), data.size());
- return (NULL);
+ return;
}
escaped = (c == '\\' && !escaped);
data.push_back(c);
}
}
-const State*
+void
QString::handle(MasterLexer& lexer) const {
MasterLexer::Token& token = getLexerImpl(lexer)->token_;
std::vector<char>& data = getLexerImpl(lexer)->data_;
const int c = getLexerImpl(lexer)->source_->getChar();
if (c == InputSource::END_OF_STREAM) {
token = Token(Token::UNEXPECTED_END);
- return (NULL);
+ return;
} else if (c == '"') {
if (escaped) {
// found escaped '"'. overwrite the preceding backslash.
data.back() = '"';
} else {
token = MasterLexer::Token(&data.at(0), data.size(), true);
- return (NULL);
+ return;
}
} else if (c == '\n' && !escaped) {
getLexerImpl(lexer)->source_->ungetChar();
token = Token(Token::UNBALANCED_QUOTES);
- return (NULL);
+ return;
} else {
escaped = (c == '\\' && !escaped);
data.push_back(c);
set_eol_(set_eol),
callback_(callback)
{}
- virtual const State* handle(MasterLexer& lexer) const {
+ virtual void handle(MasterLexer& lexer) const {
std::string input;
for (size_t i = 0; i < eat_chars_; ++i) {
input += getLexerImpl(lexer)->source_->getChar();
if (set_eol_ != NULL) {
getLexerImpl(lexer)->last_was_eol_ = *set_eol_;
}
- return (next_);
}
private:
const State* const next_;
// 1. A sequence of \r, \n is recognized as a single 'end-of-line'
EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r'
- EXPECT_EQ(s_null, s_crlf.handle(lexer)); // recognize '\n'
+ s_crlf.handle(lexer); // recognize '\n'
EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
EXPECT_TRUE(s_crlf.wasLastEOL(lexer));
// 'end-of-line'. then there will be "initial WS"
EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r'
// see ' ', "unget" it
- EXPECT_EQ(s_null, s_crlf.handle(lexer));
+ s_crlf.handle(lexer);
EXPECT_EQ(s_null, State::start(lexer, common_options)); // recognize ' '
EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType());
// 3. comment between \r and \n
EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r'
// skip comments, recognize '\n'
- EXPECT_EQ(s_null, s_crlf.handle(lexer));
+ s_crlf.handle(lexer);
EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // skip 'a'
+ s_string.handle(lexer); // skip 'a'
// 4. \r then EOF
EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r'
// see EOF, then "unget" it
- EXPECT_EQ(s_null, s_crlf.handle(lexer));
+ s_crlf.handle(lexer);
EXPECT_EQ(s_null, State::start(lexer, common_options)); // recognize EOF
EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
}
lexer.pushSource(ss);
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see \n
+ s_string.handle(lexer); // recognize str, see \n
EXPECT_FALSE(s_string.wasLastEOL(lexer));
stringTokenCheck("followed-by-EOL", s_string.getToken(lexer));
EXPECT_EQ(s_null, State::start(lexer, common_options)); // skip \n
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see \r
+ s_string.handle(lexer); // recognize str, see \r
stringTokenCheck("followed-by-CR", s_string.getToken(lexer));
EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // handle \r...
- EXPECT_EQ(s_null, s_crlf.handle(lexer)); // ...and skip it
+ s_crlf.handle(lexer); // ...and skip it
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' '
+ s_string.handle(lexer); // recognize str, see ' '
stringTokenCheck("followed-by-space", s_string.getToken(lexer));
// skip ' ', then recognize the next string
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see \t
+ s_string.handle(lexer); // recognize str, see \t
stringTokenCheck("followed-by-tab", s_string.getToken(lexer));
// skip \t, then recognize the next string
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see comment
+ s_string.handle(lexer); // recognize str, see comment
stringTokenCheck("followed-by-comment", s_string.getToken(lexer));
EXPECT_EQ(s_null, State::start(lexer, common_options)); // skip \n after it
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see '('
+ s_string.handle(lexer); // recognize str, see '('
stringTokenCheck("followed-by-paren", s_string.getToken(lexer));
EXPECT_EQ(&s_string, State::start(lexer, common_options)); // str in ()
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize the str, see ')'
+ s_string.handle(lexer); // recognize the str, see ')'
stringTokenCheck("closing", s_string.getToken(lexer));
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see EOF
+ s_string.handle(lexer); // recognize str, see EOF
stringTokenCheck("followed-by-EOF", s_string.getToken(lexer));
}
lexer.pushSource(ss);
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+ s_string.handle(lexer); // recognize str, see ' ' at end
stringTokenCheck("escaped\\ space", s_string.getToken(lexer));
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+ s_string.handle(lexer); // recognize str, see ' ' at end
stringTokenCheck("escaped\\\ttab", s_string.getToken(lexer));
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+ s_string.handle(lexer); // recognize str, see ' ' at end
stringTokenCheck("escaped\\(paren", s_string.getToken(lexer));
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+ s_string.handle(lexer); // recognize str, see ' ' at end
stringTokenCheck("escaped\\)close", s_string.getToken(lexer));
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+ s_string.handle(lexer); // recognize str, see ' ' at end
stringTokenCheck("escaped\\;comment", s_string.getToken(lexer));
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' in mid
+ s_string.handle(lexer); // recognize str, see ' ' in mid
stringTokenCheck("escaped\\\\", s_string.getToken(lexer));
// Confirm the word that follows the escaped '\' is correctly recognized.
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see ' ' at end
+ s_string.handle(lexer); // recognize str, see ' ' at end
stringTokenCheck("backslash", s_string.getToken(lexer));
}
// by default, '"' doesn't have any special meaning and part of string
EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(s_null, s_string.handle(lexer)); // recognize str, see \n
+ s_string.handle(lexer); // recognize str, see \n
stringTokenCheck("\"ignore-quotes\"", s_string.getToken(lexer));
EXPECT_EQ(s_null, State::start(lexer, common_options)); // skip \n after it
EXPECT_TRUE(s_string.wasLastEOL(lexer));
const MasterLexer::Options options = common_options | MasterLexer::QSTRING;
EXPECT_EQ(&s_qstring, State::start(lexer, options));
EXPECT_FALSE(s_string.wasLastEOL(lexer)); // EOL is canceled due to '"'
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
stringTokenCheck("quoted string", s_string.getToken(lexer), true);
// Also checks other separator characters within a qstring
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
stringTokenCheck("quoted()\t\rstring", s_string.getToken(lexer), true);
// escape character mostly doesn't have any effect in the qstring
// processing
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
stringTokenCheck("escape\\ in quote", s_string.getToken(lexer), true);
// The only exception is the quotation mark itself. Note that the escape
// only works on the quotation mark immediately after it.
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
stringTokenCheck("escaped\"", s_string.getToken(lexer), true);
// quoted '\' then '"'. Unlike the previous case '"' shouldn't be
// escaped.
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
stringTokenCheck("escaped backslash\\\\", s_string.getToken(lexer), true);
// ';' has no meaning in a quoted string (not indicating a comment)
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
stringTokenCheck("no;comment", s_string.getToken(lexer), true);
}
// EOL is encountered without closing the quote
const MasterLexer::Options options = common_options | MasterLexer::QSTRING;
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
ASSERT_EQ(Token::ERROR, s_qstring.getToken(lexer).getType());
EXPECT_EQ(Token::UNBALANCED_QUOTES,
s_qstring.getToken(lexer).getErrorCode());
// \n is okay in a quoted string if escaped
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
stringTokenCheck("quoted\\\n", s_string.getToken(lexer), true);
// EOF is encountered without closing the quote
EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_EQ(s_null, s_qstring.handle(lexer));
+ s_qstring.handle(lexer);
ASSERT_EQ(Token::ERROR, s_qstring.getToken(lexer).getType());
EXPECT_EQ(Token::UNEXPECTED_END, s_qstring.getToken(lexer).getErrorCode());
// If we continue we'll simply see the EOF