mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 20:51:16 +00:00
Small changes in the iterator code.
Changed the public interface of Scanner to resemble an STL container.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// for memory leaks
|
// for detecting memory leaks
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
|
||||||
#define _CRTDBG_MAP_ALLOC
|
#define _CRTDBG_MAP_ALLOC
|
||||||
|
@@ -13,15 +13,16 @@ namespace YAML
|
|||||||
Iterator(const Iterator& rhs);
|
Iterator(const Iterator& rhs);
|
||||||
~Iterator();
|
~Iterator();
|
||||||
|
|
||||||
friend bool operator == (const Iterator& it, const Iterator& jt);
|
|
||||||
friend bool operator != (const Iterator& it, const Iterator& jt);
|
|
||||||
Iterator& operator = (const Iterator& rhs);
|
Iterator& operator = (const Iterator& rhs);
|
||||||
Iterator& operator ++ ();
|
Iterator& operator ++ ();
|
||||||
Iterator operator ++ (int);
|
Iterator operator ++ (int);
|
||||||
const Node& operator * ();
|
const Node& operator * () const;
|
||||||
const Node *operator -> ();
|
const Node *operator -> () const;
|
||||||
const Node& first();
|
const Node& first() const;
|
||||||
const Node& second();
|
const Node& second() const;
|
||||||
|
|
||||||
|
friend bool operator == (const Iterator& it, const Iterator& jt);
|
||||||
|
friend bool operator != (const Iterator& it, const Iterator& jt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IterPriv *m_pData;
|
IterPriv *m_pData;
|
||||||
|
@@ -30,6 +30,11 @@ namespace YAML
|
|||||||
void HandleYamlDirective(Token *pToken);
|
void HandleYamlDirective(Token *pToken);
|
||||||
void HandleTagDirective(Token *pToken);
|
void HandleTagDirective(Token *pToken);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// can't copy this
|
||||||
|
Parser(const Parser& rhs) {}
|
||||||
|
Parser& operator = (const Parser& rhs) { return *this; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scanner *m_pScanner;
|
Scanner *m_pScanner;
|
||||||
ParserState m_state;
|
ParserState m_state;
|
||||||
|
@@ -56,7 +56,7 @@ namespace YAML
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node& Iterator::operator * ()
|
const Node& Iterator::operator * () const
|
||||||
{
|
{
|
||||||
if(m_pData->type == IterPriv::IT_SEQ)
|
if(m_pData->type == IterPriv::IT_SEQ)
|
||||||
return **m_pData->seqIter;
|
return **m_pData->seqIter;
|
||||||
@@ -64,15 +64,15 @@ namespace YAML
|
|||||||
throw BadDereference();
|
throw BadDereference();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node *Iterator::operator -> ()
|
const Node *Iterator::operator -> () const
|
||||||
{
|
{
|
||||||
if(m_pData->type == IterPriv::IT_SEQ)
|
if(m_pData->type == IterPriv::IT_SEQ)
|
||||||
return &**m_pData->seqIter;
|
return *m_pData->seqIter;
|
||||||
|
|
||||||
throw BadDereference();
|
throw BadDereference();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node& Iterator::first()
|
const Node& Iterator::first() const
|
||||||
{
|
{
|
||||||
if(m_pData->type == IterPriv::IT_MAP)
|
if(m_pData->type == IterPriv::IT_MAP)
|
||||||
return *m_pData->mapIter->first;
|
return *m_pData->mapIter->first;
|
||||||
@@ -80,7 +80,7 @@ namespace YAML
|
|||||||
throw BadDereference();
|
throw BadDereference();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Node& Iterator::second()
|
const Node& Iterator::second() const
|
||||||
{
|
{
|
||||||
if(m_pData->type == IterPriv::IT_MAP)
|
if(m_pData->type == IterPriv::IT_MAP)
|
||||||
return *m_pData->mapIter->second;
|
return *m_pData->mapIter->second;
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
#include "crt.h"
|
|
||||||
#include "iterpriv.h"
|
|
||||||
|
|
||||||
namespace YAML
|
|
||||||
{
|
|
||||||
IterPriv::IterPriv(): type(IT_NONE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
IterPriv::IterPriv(std::vector <Node *>::const_iterator it): seqIter(it), type(IT_SEQ)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
IterPriv::IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it): mapIter(it), type(IT_MAP)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@@ -8,11 +8,13 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
|
// IterPriv
|
||||||
|
// . The implementation for iterators - essentially a union of sequence and map iterators.
|
||||||
struct IterPriv
|
struct IterPriv
|
||||||
{
|
{
|
||||||
IterPriv();
|
IterPriv(): type(IT_NONE) {}
|
||||||
IterPriv(std::vector <Node *>::const_iterator it);
|
IterPriv(std::vector <Node *>::const_iterator it): seqIter(it), type(IT_SEQ) {}
|
||||||
IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it);
|
IterPriv(std::map <Node *, Node *, ltnode>::const_iterator it): mapIter(it), type(IT_MAP) {}
|
||||||
|
|
||||||
enum ITER_TYPE { IT_NONE, IT_SEQ, IT_MAP };
|
enum ITER_TYPE { IT_NONE, IT_SEQ, IT_MAP };
|
||||||
ITER_TYPE type;
|
ITER_TYPE type;
|
||||||
|
34
src/map.cpp
34
src/map.cpp
@@ -42,9 +42,7 @@ namespace YAML
|
|||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
// split based on start token
|
// split based on start token
|
||||||
Token& token = pScanner->PeekToken();
|
switch(pScanner->peek().type) {
|
||||||
|
|
||||||
switch(token.type) {
|
|
||||||
case TT_BLOCK_MAP_START: ParseBlock(pScanner, state); break;
|
case TT_BLOCK_MAP_START: ParseBlock(pScanner, state); break;
|
||||||
case TT_FLOW_MAP_START: ParseFlow(pScanner, state); break;
|
case TT_FLOW_MAP_START: ParseFlow(pScanner, state); break;
|
||||||
}
|
}
|
||||||
@@ -53,17 +51,17 @@ namespace YAML
|
|||||||
void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
|
void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(pScanner->IsEmpty())
|
if(pScanner->empty())
|
||||||
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP);
|
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP);
|
||||||
|
|
||||||
Token token = pScanner->PeekToken();
|
Token token = pScanner->peek();
|
||||||
if(token.type != TT_KEY && token.type != TT_BLOCK_END)
|
if(token.type != TT_KEY && token.type != TT_BLOCK_END)
|
||||||
throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP);
|
throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP);
|
||||||
|
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
if(token.type == TT_BLOCK_END)
|
if(token.type == TT_BLOCK_END)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -75,8 +73,8 @@ namespace YAML
|
|||||||
pKey->Parse(pScanner, state);
|
pKey->Parse(pScanner, state);
|
||||||
|
|
||||||
// now grab value (optional)
|
// now grab value (optional)
|
||||||
if(!pScanner->IsEmpty() && pScanner->PeekToken().type == TT_VALUE) {
|
if(!pScanner->empty() && pScanner->peek().type == TT_VALUE) {
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
pValue->Parse(pScanner, state);
|
pValue->Parse(pScanner, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,16 +90,16 @@ namespace YAML
|
|||||||
void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
|
void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(pScanner->IsEmpty())
|
if(pScanner->empty())
|
||||||
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP_FLOW);
|
throw ParserException(-1, -1, ErrorMsg::END_OF_MAP_FLOW);
|
||||||
|
|
||||||
Token& token = pScanner->PeekToken();
|
Token& token = pScanner->peek();
|
||||||
// first check for end
|
// first check for end
|
||||||
if(token.type == TT_FLOW_MAP_END) {
|
if(token.type == TT_FLOW_MAP_END) {
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +107,7 @@ namespace YAML
|
|||||||
if(token.type != TT_KEY)
|
if(token.type != TT_KEY)
|
||||||
throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP_FLOW);
|
throw ParserException(token.line, token.column, ErrorMsg::END_OF_MAP_FLOW);
|
||||||
|
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
|
|
||||||
Node *pKey = new Node;
|
Node *pKey = new Node;
|
||||||
Node *pValue = new Node;
|
Node *pValue = new Node;
|
||||||
@@ -119,15 +117,15 @@ namespace YAML
|
|||||||
pKey->Parse(pScanner, state);
|
pKey->Parse(pScanner, state);
|
||||||
|
|
||||||
// now grab value (optional)
|
// now grab value (optional)
|
||||||
if(!pScanner->IsEmpty() && pScanner->PeekToken().type == TT_VALUE) {
|
if(!pScanner->empty() && pScanner->peek().type == TT_VALUE) {
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
pValue->Parse(pScanner, state);
|
pValue->Parse(pScanner, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
// 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 = pScanner->PeekToken();
|
Token& nextToken = pScanner->peek();
|
||||||
if(nextToken.type == TT_FLOW_ENTRY)
|
if(nextToken.type == TT_FLOW_ENTRY)
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
else if(nextToken.type != TT_FLOW_MAP_END)
|
else if(nextToken.type != TT_FLOW_MAP_END)
|
||||||
throw ParserException(nextToken.line, nextToken.column, ErrorMsg::END_OF_MAP_FLOW);
|
throw ParserException(nextToken.line, nextToken.column, ErrorMsg::END_OF_MAP_FLOW);
|
||||||
|
|
||||||
|
18
src/node.cpp
18
src/node.cpp
@@ -44,7 +44,7 @@ namespace YAML
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// now split based on what kind of node we should be
|
// now split based on what kind of node we should be
|
||||||
switch(pScanner->PeekToken().type) {
|
switch(pScanner->peek().type) {
|
||||||
case TT_SCALAR:
|
case TT_SCALAR:
|
||||||
m_pContent = new Scalar;
|
m_pContent = new Scalar;
|
||||||
m_pContent->Parse(pScanner, state);
|
m_pContent->Parse(pScanner, state);
|
||||||
@@ -68,10 +68,10 @@ namespace YAML
|
|||||||
void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
|
void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
if(pScanner->IsEmpty())
|
if(pScanner->empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch(pScanner->PeekToken().type) {
|
switch(pScanner->peek().type) {
|
||||||
case TT_TAG: ParseTag(pScanner, state); break;
|
case TT_TAG: ParseTag(pScanner, state); break;
|
||||||
case TT_ANCHOR: ParseAnchor(pScanner, state); break;
|
case TT_ANCHOR: ParseAnchor(pScanner, state); break;
|
||||||
case TT_ALIAS: ParseAlias(pScanner, state); break;
|
case TT_ALIAS: ParseAlias(pScanner, state); break;
|
||||||
@@ -82,7 +82,7 @@ namespace YAML
|
|||||||
|
|
||||||
void Node::ParseTag(Scanner *pScanner, const ParserState& state)
|
void Node::ParseTag(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Token& token = pScanner->PeekToken();
|
Token& token = pScanner->peek();
|
||||||
if(m_tag != "")
|
if(m_tag != "")
|
||||||
throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_TAGS);
|
throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_TAGS);
|
||||||
|
|
||||||
@@ -90,23 +90,23 @@ namespace YAML
|
|||||||
|
|
||||||
for(unsigned i=0;i<token.params.size();i++)
|
for(unsigned i=0;i<token.params.size();i++)
|
||||||
m_tag += token.params[i];
|
m_tag += token.params[i];
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ParseAnchor(Scanner *pScanner, const ParserState& state)
|
void Node::ParseAnchor(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Token& token = pScanner->PeekToken();
|
Token& token = pScanner->peek();
|
||||||
if(m_anchor != "")
|
if(m_anchor != "")
|
||||||
throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ANCHORS);
|
throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ANCHORS);
|
||||||
|
|
||||||
m_anchor = token.value;
|
m_anchor = token.value;
|
||||||
m_alias = false;
|
m_alias = false;
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::ParseAlias(Scanner *pScanner, const ParserState& state)
|
void Node::ParseAlias(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Token& token = pScanner->PeekToken();
|
Token& token = pScanner->peek();
|
||||||
if(m_anchor != "")
|
if(m_anchor != "")
|
||||||
throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ALIASES);
|
throw ParserException(token.line, token.column, ErrorMsg::MULTIPLE_ALIASES);
|
||||||
if(m_tag != "")
|
if(m_tag != "")
|
||||||
@@ -114,7 +114,7 @@ namespace YAML
|
|||||||
|
|
||||||
m_anchor = token.value;
|
m_anchor = token.value;
|
||||||
m_alias = true;
|
m_alias = true;
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const
|
void Node::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine) const
|
||||||
|
@@ -19,7 +19,7 @@ namespace YAML
|
|||||||
|
|
||||||
Parser::operator bool() const
|
Parser::operator bool() const
|
||||||
{
|
{
|
||||||
return !m_pScanner->IsEmpty();
|
return !m_pScanner->empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Load(std::istream& in)
|
void Parser::Load(std::istream& in)
|
||||||
@@ -41,19 +41,19 @@ namespace YAML
|
|||||||
ParseDirectives();
|
ParseDirectives();
|
||||||
|
|
||||||
// we better have some tokens in the queue
|
// we better have some tokens in the queue
|
||||||
if(m_pScanner->IsEmpty())
|
if(m_pScanner->empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// first eat doc start (optional)
|
// first eat doc start (optional)
|
||||||
if(m_pScanner->PeekToken().type == TT_DOC_START)
|
if(m_pScanner->peek().type == TT_DOC_START)
|
||||||
m_pScanner->PopToken();
|
m_pScanner->pop();
|
||||||
|
|
||||||
// now parse our root node
|
// now parse our root node
|
||||||
document.Parse(m_pScanner, m_state);
|
document.Parse(m_pScanner, m_state);
|
||||||
|
|
||||||
// and finally eat any doc ends we see
|
// and finally eat any doc ends we see
|
||||||
while(!m_pScanner->IsEmpty() && m_pScanner->PeekToken().type == TT_DOC_END)
|
while(!m_pScanner->empty() && m_pScanner->peek().type == TT_DOC_END)
|
||||||
m_pScanner->PopToken();
|
m_pScanner->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseDirectives
|
// ParseDirectives
|
||||||
@@ -63,10 +63,10 @@ namespace YAML
|
|||||||
bool readDirective = false;
|
bool readDirective = false;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(m_pScanner->IsEmpty())
|
if(m_pScanner->empty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Token& token = m_pScanner->PeekToken();
|
Token& token = m_pScanner->peek();
|
||||||
if(token.type != TT_DIRECTIVE)
|
if(token.type != TT_DIRECTIVE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ namespace YAML
|
|||||||
|
|
||||||
readDirective = true;
|
readDirective = true;
|
||||||
HandleDirective(&token);
|
HandleDirective(&token);
|
||||||
m_pScanner->PopToken();
|
m_pScanner->pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +123,11 @@ namespace YAML
|
|||||||
void Parser::PrintTokens(std::ostream& out)
|
void Parser::PrintTokens(std::ostream& out)
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
if(m_pScanner->IsEmpty())
|
if(m_pScanner->empty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
out << m_pScanner->PeekToken() << std::endl;
|
out << m_pScanner->peek() << std::endl;
|
||||||
m_pScanner->PopToken();
|
m_pScanner->pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,9 +17,9 @@ namespace YAML
|
|||||||
|
|
||||||
void Scalar::Parse(Scanner *pScanner, const ParserState& state)
|
void Scalar::Parse(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
Token& token = pScanner->PeekToken();
|
Token& token = pScanner->peek();
|
||||||
m_data = token.value;
|
m_data = token.value;
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scalar::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine)
|
void Scalar::Write(std::ostream& out, int indent, bool startedLine, bool onlyOneCharOnLine)
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include "exceptions.h"
|
#include "exceptions.h"
|
||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
@@ -15,34 +16,46 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEmpty
|
// empty
|
||||||
// . Returns true if there are no more tokens to be read
|
// . Returns true if there are no more tokens to be read
|
||||||
bool Scanner::IsEmpty()
|
bool Scanner::empty()
|
||||||
{
|
{
|
||||||
PeekToken(); // to ensure that there are tokens in the queue, if possible
|
EnsureTokensInQueue();
|
||||||
return m_tokens.empty();
|
return m_tokens.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PopToken
|
// pop
|
||||||
// . Simply removes the next token on the queue.
|
// . Simply removes the next token on the queue.
|
||||||
void Scanner::PopToken()
|
void Scanner::pop()
|
||||||
{
|
{
|
||||||
PeekToken(); // to ensure that there are tokens in the queue
|
EnsureTokensInQueue();
|
||||||
if(!m_tokens.empty())
|
if(!m_tokens.empty())
|
||||||
m_tokens.pop();
|
m_tokens.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeekToken
|
// peek
|
||||||
// . Returns (but does not remove) the next token on the queue, and scans if only we need to.
|
// . Returns (but does not remove) the next token on the queue.
|
||||||
Token& Scanner::PeekToken()
|
Token& Scanner::peek()
|
||||||
|
{
|
||||||
|
EnsureTokensInQueue();
|
||||||
|
assert(!m_tokens.empty()); // should we be asserting here? I mean, we really just be checking
|
||||||
|
// if it's empty before peeking.
|
||||||
|
|
||||||
|
return m_tokens.front();
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnsureTokensInQueue
|
||||||
|
// . Scan until there's a valid token at the front of the queue,
|
||||||
|
// or we're sure the queue is empty.
|
||||||
|
void Scanner::EnsureTokensInQueue()
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!m_tokens.empty()) {
|
if(!m_tokens.empty()) {
|
||||||
Token& token = m_tokens.front();
|
Token& token = m_tokens.front();
|
||||||
|
|
||||||
// return this guy if it's valid
|
// if this guy's valid, then we're done
|
||||||
if(token.status == TS_VALID)
|
if(token.status == TS_VALID)
|
||||||
return token;
|
return;
|
||||||
|
|
||||||
// here's where we clean up the impossible tokens
|
// here's where we clean up the impossible tokens
|
||||||
if(token.status == TS_INVALID) {
|
if(token.status == TS_INVALID) {
|
||||||
@@ -55,13 +68,11 @@ namespace YAML
|
|||||||
|
|
||||||
// no token? maybe we've actually finished
|
// no token? maybe we've actually finished
|
||||||
if(m_endedStream)
|
if(m_endedStream)
|
||||||
break;
|
return;
|
||||||
|
|
||||||
// no? then scan...
|
// no? then scan...
|
||||||
ScanNextToken();
|
ScanNextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: find something to return here, or assert (but can't do that! maybe split into two functions?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScanNextToken
|
// ScanNextToken
|
||||||
|
@@ -16,16 +16,18 @@ namespace YAML
|
|||||||
Scanner(std::istream& in);
|
Scanner(std::istream& in);
|
||||||
~Scanner();
|
~Scanner();
|
||||||
|
|
||||||
bool IsEmpty();
|
// token queue management (hopefully this looks kinda stl-ish)
|
||||||
void PopToken();
|
bool empty();
|
||||||
Token& PeekToken();
|
void pop();
|
||||||
|
Token& peek();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// scanning
|
// scanning
|
||||||
void StartStream();
|
void EnsureTokensInQueue();
|
||||||
void EndStream();
|
|
||||||
void ScanNextToken();
|
void ScanNextToken();
|
||||||
void ScanToNextToken();
|
void ScanToNextToken();
|
||||||
|
void StartStream();
|
||||||
|
void EndStream();
|
||||||
Token *PushIndentTo(int column, bool sequence);
|
Token *PushIndentTo(int column, bool sequence);
|
||||||
void PopIndentTo(int column);
|
void PopIndentTo(int column);
|
||||||
|
|
||||||
|
@@ -52,9 +52,7 @@ namespace YAML
|
|||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
// split based on start token
|
// split based on start token
|
||||||
Token& token = pScanner->PeekToken();
|
switch(pScanner->peek().type) {
|
||||||
|
|
||||||
switch(token.type) {
|
|
||||||
case TT_BLOCK_SEQ_START: ParseBlock(pScanner, state); break;
|
case TT_BLOCK_SEQ_START: ParseBlock(pScanner, state); break;
|
||||||
case TT_BLOCK_ENTRY: ParseImplicit(pScanner, state); break;
|
case TT_BLOCK_ENTRY: ParseImplicit(pScanner, state); break;
|
||||||
case TT_FLOW_SEQ_START: ParseFlow(pScanner, state); break;
|
case TT_FLOW_SEQ_START: ParseFlow(pScanner, state); break;
|
||||||
@@ -64,17 +62,17 @@ namespace YAML
|
|||||||
void Sequence::ParseBlock(Scanner *pScanner, const ParserState& state)
|
void Sequence::ParseBlock(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(pScanner->IsEmpty())
|
if(pScanner->empty())
|
||||||
throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ);
|
throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ);
|
||||||
|
|
||||||
Token token = pScanner->PeekToken();
|
Token token = pScanner->peek();
|
||||||
if(token.type != TT_BLOCK_ENTRY && token.type != TT_BLOCK_END)
|
if(token.type != TT_BLOCK_ENTRY && token.type != TT_BLOCK_END)
|
||||||
throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ);
|
throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ);
|
||||||
|
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
if(token.type == TT_BLOCK_END)
|
if(token.type == TT_BLOCK_END)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -88,15 +86,15 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
// we're actually *allowed* to have no tokens at some point
|
// we're actually *allowed* to have no tokens at some point
|
||||||
if(pScanner->IsEmpty())
|
if(pScanner->empty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// and we end at anything other than a block entry
|
// and we end at anything other than a block entry
|
||||||
Token& token = pScanner->PeekToken();
|
Token& token = pScanner->peek();
|
||||||
if(token.type != TT_BLOCK_ENTRY)
|
if(token.type != TT_BLOCK_ENTRY)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
|
|
||||||
Node *pNode = new Node;
|
Node *pNode = new Node;
|
||||||
m_data.push_back(pNode);
|
m_data.push_back(pNode);
|
||||||
@@ -107,15 +105,15 @@ namespace YAML
|
|||||||
void Sequence::ParseFlow(Scanner *pScanner, const ParserState& state)
|
void Sequence::ParseFlow(Scanner *pScanner, const ParserState& state)
|
||||||
{
|
{
|
||||||
// eat start token
|
// eat start token
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(pScanner->IsEmpty())
|
if(pScanner->empty())
|
||||||
throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ_FLOW);
|
throw ParserException(-1, -1, ErrorMsg::END_OF_SEQ_FLOW);
|
||||||
|
|
||||||
// first check for end
|
// first check for end
|
||||||
if(pScanner->PeekToken().type == TT_FLOW_SEQ_END) {
|
if(pScanner->peek().type == TT_FLOW_SEQ_END) {
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,9 +123,9 @@ namespace YAML
|
|||||||
pNode->Parse(pScanner, state);
|
pNode->Parse(pScanner, state);
|
||||||
|
|
||||||
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
// 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 = pScanner->PeekToken();
|
Token& token = pScanner->peek();
|
||||||
if(token.type == TT_FLOW_ENTRY)
|
if(token.type == TT_FLOW_ENTRY)
|
||||||
pScanner->PopToken();
|
pScanner->pop();
|
||||||
else if(token.type != TT_FLOW_SEQ_END)
|
else if(token.type != TT_FLOW_SEQ_END)
|
||||||
throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ_FLOW);
|
throw ParserException(token.line, token.column, ErrorMsg::END_OF_SEQ_FLOW);
|
||||||
}
|
}
|
||||||
|
@@ -175,10 +175,6 @@
|
|||||||
RelativePath=".\src\iterator.cpp"
|
RelativePath=".\src\iterator.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\src\iterpriv.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\map.cpp"
|
RelativePath=".\src\map.cpp"
|
||||||
>
|
>
|
||||||
|
Reference in New Issue
Block a user