Commit b991213a authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2506] added another version of getNextToken, basic part

parent c6c7cdee
......@@ -192,6 +192,34 @@ MasterLexer::getNextToken(Options options) {
return (impl_->token_);
}
const MasterToken&
MasterLexer::getNextToken(MasterToken::Type expect, bool eol_ok) {
Options options = NONE;
if (expect == MasterToken::QSTRING) {
options = options | QSTRING;
}
getNextToken(options); // the result should be set in impl_->token_
const bool is_eol_like =
(impl_->token_.getType() == MasterToken::END_OF_LINE ||
impl_->token_.getType() == MasterToken::END_OF_FILE);
if (eol_ok && is_eol_like) {
return (impl_->token_);
}
if (impl_->token_.getType() == MasterToken::STRING &&
expect == MasterToken::QSTRING) {
return (impl_->token_);
}
if (impl_->token_.getType() != expect) {
ungetToken();
throw LexerError(__FILE__, __LINE__,
MasterToken(MasterToken::UNEXPECTED_END));
}
return (impl_->token_);
}
void
MasterLexer::ungetToken() {
if (impl_->has_previous_) {
......
......@@ -306,6 +306,15 @@ public:
{}
};
class LexerError : public Exception {
public:
LexerError(const char* file, size_t line, MasterToken error_token) :
Exception(file, line, error_token.getErrorText().c_str()),
token_(error_token)
{}
const MasterToken token_;
};
/// \brief Options for getNextToken.
///
/// A compound option, indicating multiple options are set, can be
......@@ -442,6 +451,9 @@ public:
/// or the token fail.
const MasterToken& getNextToken(Options options = NONE);
const MasterToken& getNextToken(MasterToken::Type expect,
bool eol_ok = false);
/// \brief Return the last token back to the lexer.
///
/// The method undoes the lasts call to getNextToken(). If you call the
......
......@@ -284,4 +284,76 @@ TEST_F(MasterLexerTest, ungetAfterSwitch) {
EXPECT_THROW(lexer.ungetToken(), isc::InvalidOperation);
}
// Common checks regarding expected/unexpected end-of-line
void
eolCheck(MasterLexer& lexer, MasterToken::Type expect) {
// If EOL is found and eol_ok is true, we get it.
EXPECT_EQ(MasterToken::END_OF_LINE,
lexer.getNextToken(expect, true).getType());
// We'll see the second '\n'; by default it will fail.
EXPECT_THROW(lexer.getNextToken(expect), MasterLexer::LexerError);
// Same if eol_ok is explicitly set to false. This also checks the
// offending '\n' was "ungotten".
EXPECT_THROW(lexer.getNextToken(expect, false), MasterLexer::LexerError);
// And also check the error token set in the exception object.
bool thrown = false;
try {
lexer.getNextToken(expect);
} catch (const MasterLexer::LexerError& error) {
EXPECT_EQ(MasterToken::UNEXPECTED_END, error.token_.getErrorCode());
thrown = true;
}
EXPECT_TRUE(thrown);
}
// Common checks regarding expected/unexpected end-of-file
void
eofCheck(MasterLexer& lexer, MasterToken::Type expect) {
EXPECT_EQ(MasterToken::END_OF_FILE,
lexer.getNextToken(expect, true).getType());
EXPECT_THROW(lexer.getNextToken(expect), MasterLexer::LexerError);
EXPECT_THROW(lexer.getNextToken(expect, false), MasterLexer::LexerError);
}
TEST_F(MasterLexerTest, getNextTokenString) {
ss << "normal-string\n";
ss << "\n";
ss << "another-string";
lexer.pushSource(ss);
// Normal successful case: Expecting a string and get one.
EXPECT_EQ("normal-string",
lexer.getNextToken(MasterToken::STRING).getString());
eolCheck(lexer, MasterToken::STRING);
// Skip the 2nd '\n'
EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
// Same set of tests but for end-of-file
EXPECT_EQ("another-string",
lexer.getNextToken(MasterToken::STRING, true).getString());
eofCheck(lexer, MasterToken::STRING);
}
TEST_F(MasterLexerTest, getNextTokenQString) {
ss << "\"quoted-string\"\n";
ss << "\n";
ss << "normal-string";
lexer.pushSource(ss);
// Expecting a quoted string and get one.
EXPECT_EQ("quoted-string",
lexer.getNextToken(MasterToken::QSTRING).getString());
eolCheck(lexer, MasterToken::QSTRING);
// Skip the 2nd '\n'
EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
// Expecting a quoted string but see a normal string. It's okay.
EXPECT_EQ("normal-string",
lexer.getNextToken(MasterToken::QSTRING).getString());
eofCheck(lexer, MasterToken::QSTRING);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment