Fixed bug where the parser doesn't find the end of a map or seq flow

This commit is contained in:
Jesse Beder
2012-06-09 14:39:00 -05:00
parent 2d815c5d6a
commit 68dd9b5d18
5 changed files with 47 additions and 13 deletions

View File

@@ -51,6 +51,13 @@ namespace YAML
return m_tokens.front();
}
// mark
// . Returns the current mark in the stream
Mark Scanner::mark() const
{
return INPUT.mark();
}
// EnsureTokensInQueue
// . Scan until there's a valid token at the front of the queue,
// or we're sure the queue is empty.

View File

@@ -31,6 +31,7 @@ namespace YAML
bool empty();
void pop();
Token& peek();
Mark mark() const;
private:
struct IndentMarker {

View File

@@ -48,7 +48,7 @@ namespace YAML
{
// an empty node *is* a possibility
if(m_scanner.empty()) {
eventHandler.OnNull(Mark::null(), NullAnchor);
eventHandler.OnNull(m_scanner.mark(), NullAnchor);
return;
}
@@ -136,7 +136,7 @@ namespace YAML
while(1) {
if(m_scanner.empty())
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ);
Token token = m_scanner.peek();
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
@@ -169,7 +169,7 @@ namespace YAML
while(1) {
if(m_scanner.empty())
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
// first check for end
if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
@@ -179,6 +179,9 @@ namespace YAML
// then read the node
HandleNode(eventHandler);
if(m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
Token& token = m_scanner.peek();
@@ -211,7 +214,7 @@ namespace YAML
while(1) {
if(m_scanner.empty())
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP);
Token token = m_scanner.peek();
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
@@ -250,7 +253,7 @@ namespace YAML
while(1) {
if(m_scanner.empty())
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
Token& token = m_scanner.peek();
const Mark mark = token.mark;
@@ -275,6 +278,9 @@ namespace YAML
} else {
eventHandler.OnNull(mark, NullAnchor);
}
if(m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
Token& nextToken = m_scanner.peek();

View File

@@ -6,12 +6,12 @@
namespace Test
{
namespace Parser {
TEST BadDocStart()
TEST NoEndOfMapFlow()
{
try {
HANDLE("---{header: {id: 1");
} catch(const YAML::ParserException& e) {
YAML_ASSERT(true);
YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::END_OF_MAP_FLOW));
return true;
}
return " no exception caught";
@@ -43,7 +43,7 @@ namespace Test
{
int passed = 0;
int total = 0;
RunParserTest(&Parser::BadDocStart, "Bad doc start", passed, total);
RunParserTest(&Parser::NoEndOfMapFlow, "No end of map flow", passed, total);
std::cout << "Parser tests: " << passed << "/" << total << " passed\n";
return passed == total;

View File

@@ -1,12 +1,32 @@
#include "yaml-cpp/yaml.h"
#include "yaml-cpp/eventhandler.h"
#include <iostream>
class NullEventHandler: public YAML::EventHandler
{
public:
typedef YAML::Mark Mark;
typedef YAML::anchor_t anchor_t;
NullEventHandler() {}
virtual void OnDocumentStart(const Mark&) {}
virtual void OnDocumentEnd() {}
virtual void OnNull(const Mark&, anchor_t) {}
virtual void OnAlias(const Mark&, anchor_t) {}
virtual void OnScalar(const Mark&, const std::string&, anchor_t, const std::string&) {}
virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {}
virtual void OnSequenceEnd() {}
virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {}
virtual void OnMapEnd() {}
};
int main()
{
YAML::Emitter out(std::cout);
out << YAML::BeginSeq;
out << "item 1";
out << YAML::BeginSeq << "foo 1" << "bar 2" << YAML::EndSeq;
out << YAML::EndSeq;
std::stringstream stream("---{header: {id: 1");
YAML::Parser parser(stream);
// parser.PrintTokens(std::cout);
NullEventHandler handler;
parser.HandleNextDocument(handler);
return 0;
}