mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Refactored simple keys so that validating doesn't require popping indents, and so popping indents (and adding the end map) is independent of when we validate the simple key
This commit is contained in:
@@ -95,12 +95,12 @@ namespace YAML
|
|||||||
// get rid of whitespace, etc. (in between tokens it should be irrelevent)
|
// get rid of whitespace, etc. (in between tokens it should be irrelevent)
|
||||||
ScanToNextToken();
|
ScanToNextToken();
|
||||||
|
|
||||||
// check the latest simple key
|
|
||||||
VerifySimpleKey();
|
|
||||||
|
|
||||||
// maybe need to end some blocks
|
// maybe need to end some blocks
|
||||||
PopIndentToHere();
|
PopIndentToHere();
|
||||||
|
|
||||||
|
// check the latest simple key
|
||||||
|
VerifySimpleKey();
|
||||||
|
|
||||||
// *****
|
// *****
|
||||||
// And now branch based on the next few characters!
|
// And now branch based on the next few characters!
|
||||||
// *****
|
// *****
|
||||||
@@ -244,8 +244,8 @@ namespace YAML
|
|||||||
// PushIndentTo
|
// PushIndentTo
|
||||||
// . Pushes an indentation onto the stack, and enqueues the
|
// . Pushes an indentation onto the stack, and enqueues the
|
||||||
// proper token (sequence start or mapping start).
|
// proper token (sequence start or mapping start).
|
||||||
// . Returns the token it generates (if any).
|
// . Returns the indent marker it generates (if any).
|
||||||
Token *Scanner::PushIndentTo(int column, IndentMarker::INDENT_TYPE type)
|
Scanner::IndentMarker *Scanner::PushIndentTo(int column, IndentMarker::INDENT_TYPE type)
|
||||||
{
|
{
|
||||||
// are we in flow?
|
// are we in flow?
|
||||||
if(m_flowLevel > 0)
|
if(m_flowLevel > 0)
|
||||||
@@ -260,16 +260,18 @@ namespace YAML
|
|||||||
if(indent.column == lastIndent.column && !(indent.type == IndentMarker::SEQ && lastIndent.type == IndentMarker::MAP))
|
if(indent.column == lastIndent.column && !(indent.type == IndentMarker::SEQ && lastIndent.type == IndentMarker::MAP))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// now push
|
// push a start token
|
||||||
m_indents.push(indent);
|
|
||||||
if(type == IndentMarker::SEQ)
|
if(type == IndentMarker::SEQ)
|
||||||
m_tokens.push(Token(Token::BLOCK_SEQ_START, INPUT.mark()));
|
m_tokens.push(Token(Token::BLOCK_SEQ_START, INPUT.mark()));
|
||||||
else if(type == IndentMarker::MAP)
|
else if(type == IndentMarker::MAP)
|
||||||
m_tokens.push(Token(Token::BLOCK_MAP_START, INPUT.mark()));
|
m_tokens.push(Token(Token::BLOCK_MAP_START, INPUT.mark()));
|
||||||
else
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
|
indent.pStartToken = &m_tokens.back();
|
||||||
|
|
||||||
return &m_tokens.back();
|
// and then the indent
|
||||||
|
m_indents.push(indent);
|
||||||
|
return &m_indents.top();
|
||||||
}
|
}
|
||||||
|
|
||||||
// PopIndentToHere
|
// PopIndentToHere
|
||||||
@@ -316,8 +318,12 @@ namespace YAML
|
|||||||
// . Pops a single indent, pushing the proper token
|
// . Pops a single indent, pushing the proper token
|
||||||
void Scanner::PopIndent()
|
void Scanner::PopIndent()
|
||||||
{
|
{
|
||||||
IndentMarker::INDENT_TYPE type = m_indents.top().type;
|
IndentMarker indent = m_indents.top();
|
||||||
|
IndentMarker::INDENT_TYPE type = indent.type;
|
||||||
m_indents.pop();
|
m_indents.pop();
|
||||||
|
if(!indent.isValid)
|
||||||
|
return;
|
||||||
|
|
||||||
if(type == IndentMarker::SEQ)
|
if(type == IndentMarker::SEQ)
|
||||||
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
|
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
|
||||||
else if(type == IndentMarker::MAP)
|
else if(type == IndentMarker::MAP)
|
||||||
|
@@ -36,10 +36,12 @@ namespace YAML
|
|||||||
private:
|
private:
|
||||||
struct IndentMarker {
|
struct IndentMarker {
|
||||||
enum INDENT_TYPE { MAP, SEQ, NONE };
|
enum INDENT_TYPE { MAP, SEQ, NONE };
|
||||||
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_) {}
|
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), isValid(true), pStartToken(0) {}
|
||||||
|
|
||||||
int column;
|
int column;
|
||||||
INDENT_TYPE type;
|
INDENT_TYPE type;
|
||||||
|
bool isValid;
|
||||||
|
Token *pStartToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -49,7 +51,7 @@ namespace YAML
|
|||||||
void ScanToNextToken();
|
void ScanToNextToken();
|
||||||
void StartStream();
|
void StartStream();
|
||||||
void EndStream();
|
void EndStream();
|
||||||
Token *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
|
IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
|
||||||
void PopIndentToHere();
|
void PopIndentToHere();
|
||||||
void PopAllIndents();
|
void PopAllIndents();
|
||||||
void PopIndent();
|
void PopIndent();
|
||||||
@@ -71,6 +73,7 @@ namespace YAML
|
|||||||
|
|
||||||
Mark mark;
|
Mark mark;
|
||||||
int flowLevel;
|
int flowLevel;
|
||||||
|
IndentMarker *pIndent;
|
||||||
Token *pMapStart, *pKey;
|
Token *pMapStart, *pKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -7,12 +7,15 @@
|
|||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_)
|
Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_)
|
||||||
: mark(mark_), flowLevel(flowLevel_), pMapStart(0), pKey(0)
|
: mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scanner::SimpleKey::Validate()
|
void Scanner::SimpleKey::Validate()
|
||||||
{
|
{
|
||||||
|
// Note: pIndent will *not* be garbage here; see below
|
||||||
|
if(pIndent)
|
||||||
|
pIndent->isValid = true;
|
||||||
if(pMapStart)
|
if(pMapStart)
|
||||||
pMapStart->status = Token::VALID;
|
pMapStart->status = Token::VALID;
|
||||||
if(pKey)
|
if(pKey)
|
||||||
@@ -21,6 +24,8 @@ namespace YAML
|
|||||||
|
|
||||||
void Scanner::SimpleKey::Invalidate()
|
void Scanner::SimpleKey::Invalidate()
|
||||||
{
|
{
|
||||||
|
// Note: pIndent might be a garbage pointer here, but that's ok
|
||||||
|
// An indent will only be popped if the simple key is invalid
|
||||||
if(pMapStart)
|
if(pMapStart)
|
||||||
pMapStart->status = Token::INVALID;
|
pMapStart->status = Token::INVALID;
|
||||||
if(pKey)
|
if(pKey)
|
||||||
@@ -35,9 +40,12 @@ namespace YAML
|
|||||||
SimpleKey key(INPUT.mark(), m_flowLevel);
|
SimpleKey key(INPUT.mark(), m_flowLevel);
|
||||||
|
|
||||||
// first add a map start, if necessary
|
// first add a map start, if necessary
|
||||||
key.pMapStart = PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
||||||
if(key.pMapStart)
|
if(key.pIndent) {
|
||||||
|
key.pIndent->isValid = false;
|
||||||
|
key.pMapStart = key.pIndent->pStartToken;
|
||||||
key.pMapStart->status = Token::UNVERIFIED;
|
key.pMapStart->status = Token::UNVERIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
// then add the (now unverified) key
|
// then add the (now unverified) key
|
||||||
m_tokens.push(Token(Token::KEY, INPUT.mark()));
|
m_tokens.push(Token(Token::KEY, INPUT.mark()));
|
||||||
@@ -87,13 +95,6 @@ namespace YAML
|
|||||||
else
|
else
|
||||||
key.Invalidate();
|
key.Invalidate();
|
||||||
|
|
||||||
// In block style, remember that we've pushed an indent for this potential simple key (if it was starting).
|
|
||||||
// If it was invalid, then we need to pop it off.
|
|
||||||
// Note: we're guaranteed to be popping the right one (i.e., there couldn't have been anything in
|
|
||||||
// between) since keys have to be inline, and will be invalidated immediately on a newline.
|
|
||||||
if(!isValid && m_flowLevel == 0)
|
|
||||||
m_indents.pop();
|
|
||||||
|
|
||||||
m_isLastKeyValid = isValid;
|
m_isLastKeyValid = isValid;
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user