token_(Token::NOT_STARTED)
{}
+ int skipComment(int c) {
+ if (c == ';') {
+ while (true) {
+ c = source_->getChar();
+ if (c == '\n' || c == InputSource::END_OF_STREAM) {
+ return (c);
+ }
+ }
+ }
+ return (c);
+ }
+
std::vector<InputSourcePtr> sources_;
InputSource* source_; // current source
size_t paren_count_;
return (START_STATE);
case CRLF:
return (CRLF_STATE);
- case EatLine:
- return (CRLF_STATE); // XXX
case String:
- return (STRING_STATE); // XXX
+ return (STRING_STATE);
}
}
+namespace {
inline void
cancelOptions(MasterLexer::Options& options,
MasterLexer::Options canceled_options)
options = static_cast<MasterLexer::Options>(
options & static_cast<MasterLexer::Options>(~canceled_options));
}
+}
const State*
Start::handle(MasterLexer& lexer, MasterLexer::Options& options) const {
size_t& paren_count = getLexerImpl(lexer)->paren_count_;
while (true) {
- const int c = getLexerImpl(lexer)->source_->getChar();
+ const int c = getLexerImpl(lexer)->skipComment(
+ getLexerImpl(lexer)->source_->getChar());
if (c == InputSource::END_OF_STREAM) {
if (paren_count != 0) {
getLexerImpl(lexer)->token_ = Token(Token::UNBALANCED_PAREN);
getLexerImpl(lexer)->token_ = Token(Token::UNBALANCED_PAREN);
return (NULL);
}
- --paren_count;
- if (paren_count == 0) {
+ if (--paren_count == 0) {
options = getLexerImpl(lexer)->orig_options_;
}
continue;
const State* const s_null;
const State& s_start;
const State& s_crlf;
+
const State& s_string;
std::stringstream ss;
MasterLexer::Options options, orig_options;
EXPECT_EQ(Token::UNBALANCED_PAREN, s_start.getToken(lexer).getErrorCode());
EXPECT_FALSE(s_start.wasLastEOL(lexer));
- // Reach EOF without a dangling open parenthesis.
+ // Reach EOF with a dangling open parenthesis.
ss << "(a";
EXPECT_EQ(&s_string, s_start.handle(lexer, options)); // consume '(a'
EXPECT_EQ(1, s_start.getParenCount(lexer));
EXPECT_EQ(s_null, s_start.handle(lexer, options)); // reach EOF
ASSERT_EQ(Token::ERROR, s_start.getToken(lexer).getType());
EXPECT_EQ(Token::UNBALANCED_PAREN, s_start.getToken(lexer).getErrorCode());
- EXPECT_EQ(0, s_start.getParenCount(lexer));
+ EXPECT_EQ(0, s_start.getParenCount(lexer)); // should be reset to 0
+}
+
+TEST_F(MasterLexerStateTest, startToComment) {
+ // Begin with 'start', skip space, then encounter a comment. Skip
+ // the rest of the line, and recognize the new line. Note that the
+ // second ';' is simply ignored.
+ ss << " ;a;\n";
+ EXPECT_EQ(s_null, s_start.handle(lexer, options));
+ EXPECT_EQ(Token::END_OF_LINE, s_start.getToken(lexer).getType());
+
+ // Likewise, but the comment ends with EOF.
+ ss << " ;a;";
+ EXPECT_EQ(s_null, s_start.handle(lexer, options));
+ EXPECT_EQ(Token::END_OF_FILE, s_start.getToken(lexer).getType());
}
}