mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Finished refactoring of simple keys so that they can refer to multiple tokens at a single level
This commit is contained in:
@@ -46,7 +46,13 @@ namespace YAML
|
|||||||
assert(!m_tokens.empty()); // should we be asserting here? I mean, we really just be checking
|
assert(!m_tokens.empty()); // should we be asserting here? I mean, we really just be checking
|
||||||
// if it's empty before peeking.
|
// if it's empty before peeking.
|
||||||
|
|
||||||
// std::cerr << "peek: (" << &m_tokens.front() << ") " << m_tokens.front() << "\n";
|
#if 0
|
||||||
|
static Token *pLast = 0;
|
||||||
|
if(pLast != &m_tokens.front())
|
||||||
|
std::cerr << "peek: " << m_tokens.front() << "\n";
|
||||||
|
pLast = &m_tokens.front();
|
||||||
|
#endif
|
||||||
|
|
||||||
return m_tokens.front();
|
return m_tokens.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,9 +104,6 @@ namespace YAML
|
|||||||
// 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!
|
||||||
// *****
|
// *****
|
||||||
@@ -187,7 +190,7 @@ namespace YAML
|
|||||||
INPUT.eat(n);
|
INPUT.eat(n);
|
||||||
|
|
||||||
// oh yeah, and let's get rid of that simple key
|
// oh yeah, and let's get rid of that simple key
|
||||||
VerifySimpleKey();
|
InvalidateSimpleKey();
|
||||||
|
|
||||||
// new line - we may be able to accept a simple key now
|
// new line - we may be able to accept a simple key now
|
||||||
if(m_flowLevel == 0)
|
if(m_flowLevel == 0)
|
||||||
@@ -235,7 +238,7 @@ namespace YAML
|
|||||||
INPUT.ResetColumn();
|
INPUT.ResetColumn();
|
||||||
|
|
||||||
PopAllIndents();
|
PopAllIndents();
|
||||||
VerifyAllSimpleKeys();
|
PopAllSimpleKeys();
|
||||||
|
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
m_endedStream = true;
|
m_endedStream = true;
|
||||||
@@ -321,8 +324,10 @@ namespace YAML
|
|||||||
IndentMarker indent = m_indents.top();
|
IndentMarker indent = m_indents.top();
|
||||||
IndentMarker::INDENT_TYPE type = indent.type;
|
IndentMarker::INDENT_TYPE type = indent.type;
|
||||||
m_indents.pop();
|
m_indents.pop();
|
||||||
if(!indent.isValid)
|
if(!indent.isValid) {
|
||||||
|
InvalidateSimpleKey();
|
||||||
return;
|
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()));
|
||||||
|
@@ -58,9 +58,12 @@ namespace YAML
|
|||||||
int GetTopIndent() const;
|
int GetTopIndent() const;
|
||||||
|
|
||||||
// checking input
|
// checking input
|
||||||
void InsertSimpleKey();
|
bool ExistsActiveSimpleKey() const;
|
||||||
bool VerifySimpleKey(bool force = false);
|
void InsertPotentialSimpleKey();
|
||||||
void VerifyAllSimpleKeys();
|
void InvalidateSimpleKey();
|
||||||
|
bool VerifySimpleKey();
|
||||||
|
void PopAllSimpleKeys();
|
||||||
|
|
||||||
void ThrowParserException(const std::string& msg) const;
|
void ThrowParserException(const std::string& msg) const;
|
||||||
|
|
||||||
bool IsWhitespaceToBeEaten(char ch);
|
bool IsWhitespaceToBeEaten(char ch);
|
||||||
|
@@ -20,7 +20,7 @@ namespace YAML
|
|||||||
|
|
||||||
// pop indents and simple keys
|
// pop indents and simple keys
|
||||||
PopAllIndents();
|
PopAllIndents();
|
||||||
VerifyAllSimpleKeys();
|
PopAllSimpleKeys();
|
||||||
|
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ namespace YAML
|
|||||||
void Scanner::ScanDocStart()
|
void Scanner::ScanDocStart()
|
||||||
{
|
{
|
||||||
PopAllIndents();
|
PopAllIndents();
|
||||||
VerifyAllSimpleKeys();
|
PopAllSimpleKeys();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
@@ -73,7 +73,7 @@ namespace YAML
|
|||||||
void Scanner::ScanDocEnd()
|
void Scanner::ScanDocEnd()
|
||||||
{
|
{
|
||||||
PopAllIndents();
|
PopAllIndents();
|
||||||
VerifyAllSimpleKeys();
|
PopAllSimpleKeys();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
@@ -86,7 +86,7 @@ namespace YAML
|
|||||||
void Scanner::ScanFlowStart()
|
void Scanner::ScanFlowStart()
|
||||||
{
|
{
|
||||||
// flows can be simple keys
|
// flows can be simple keys
|
||||||
InsertSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
m_flowLevel++;
|
m_flowLevel++;
|
||||||
m_simpleKeyAllowed = true;
|
m_simpleKeyAllowed = true;
|
||||||
|
|
||||||
@@ -103,6 +103,7 @@ namespace YAML
|
|||||||
if(m_flowLevel == 0)
|
if(m_flowLevel == 0)
|
||||||
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
|
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
|
||||||
|
|
||||||
|
InvalidateSimpleKey();
|
||||||
m_flowLevel--;
|
m_flowLevel--;
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
|
||||||
@@ -170,8 +171,13 @@ namespace YAML
|
|||||||
// Value
|
// Value
|
||||||
void Scanner::ScanValue()
|
void Scanner::ScanValue()
|
||||||
{
|
{
|
||||||
// does this follow a simple key?
|
// just in case we have an empty key
|
||||||
if(m_isLastKeyValid) {
|
InsertPotentialSimpleKey();
|
||||||
|
|
||||||
|
// and check that simple key
|
||||||
|
bool isSimpleKey = VerifySimpleKey();
|
||||||
|
|
||||||
|
if(isSimpleKey) {
|
||||||
// can't follow a simple key with another simple key (dunno why, though - it seems fine)
|
// can't follow a simple key with another simple key (dunno why, though - it seems fine)
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -181,19 +187,10 @@ namespace YAML
|
|||||||
throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
|
throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
|
||||||
|
|
||||||
PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
||||||
} else {
|
|
||||||
// we might have an empty key, so we should add it (as a simple key)
|
|
||||||
if(m_simpleKeyAllowed) {
|
|
||||||
InsertSimpleKey();
|
|
||||||
VerifySimpleKey();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// can only put a simple key here if we're in block context
|
// can only put a simple key here if we're in block context
|
||||||
if(m_flowLevel == 0)
|
m_simpleKeyAllowed = (m_flowLevel == 0);
|
||||||
m_simpleKeyAllowed = true;
|
|
||||||
else
|
|
||||||
m_simpleKeyAllowed = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eat
|
// eat
|
||||||
@@ -210,7 +207,7 @@ namespace YAML
|
|||||||
|
|
||||||
// insert a potential simple key
|
// insert a potential simple key
|
||||||
if(m_simpleKeyAllowed)
|
if(m_simpleKeyAllowed)
|
||||||
InsertSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
|
||||||
// eat the indicator
|
// eat the indicator
|
||||||
@@ -243,7 +240,7 @@ namespace YAML
|
|||||||
|
|
||||||
// insert a potential simple key
|
// insert a potential simple key
|
||||||
if(m_simpleKeyAllowed)
|
if(m_simpleKeyAllowed)
|
||||||
InsertSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
m_simpleKeyAllowed = false;
|
m_simpleKeyAllowed = false;
|
||||||
|
|
||||||
// eat the indicator
|
// eat the indicator
|
||||||
@@ -293,7 +290,7 @@ namespace YAML
|
|||||||
|
|
||||||
// insert a potential simple key
|
// insert a potential simple key
|
||||||
if(m_simpleKeyAllowed)
|
if(m_simpleKeyAllowed)
|
||||||
InsertSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
|
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
scalar = ScanScalar(INPUT, params);
|
scalar = ScanScalar(INPUT, params);
|
||||||
@@ -333,7 +330,7 @@ namespace YAML
|
|||||||
|
|
||||||
// insert a potential simple key
|
// insert a potential simple key
|
||||||
if(m_simpleKeyAllowed)
|
if(m_simpleKeyAllowed)
|
||||||
InsertSimpleKey();
|
InsertPotentialSimpleKey();
|
||||||
|
|
||||||
Mark mark = INPUT.mark();
|
Mark mark = INPUT.mark();
|
||||||
|
|
||||||
|
@@ -32,11 +32,26 @@ namespace YAML
|
|||||||
pKey->status = Token::INVALID;
|
pKey->status = Token::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertSimpleKey
|
// ExistsActiveSimpleKey
|
||||||
// . Adds a potential simple key to the queue,
|
// . Returns true if there's a potential simple key at our flow level
|
||||||
// and saves it on a stack.
|
// (there's allowed at most one per flow level, i.e., at the start of the flow start token)
|
||||||
void Scanner::InsertSimpleKey()
|
bool Scanner::ExistsActiveSimpleKey() const
|
||||||
{
|
{
|
||||||
|
if(m_simpleKeys.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const SimpleKey& key = m_simpleKeys.top();
|
||||||
|
return key.flowLevel == m_flowLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertPotentialSimpleKey
|
||||||
|
// . If we can, add a potential simple key to the queue,
|
||||||
|
// and save it on a stack.
|
||||||
|
void Scanner::InsertPotentialSimpleKey()
|
||||||
|
{
|
||||||
|
if(ExistsActiveSimpleKey())
|
||||||
|
return;
|
||||||
|
|
||||||
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
|
||||||
@@ -55,11 +70,26 @@ namespace YAML
|
|||||||
m_simpleKeys.push(key);
|
m_simpleKeys.push(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvalidateSimpleKey
|
||||||
|
// . Automatically invalidate the simple key in our flow level
|
||||||
|
void Scanner::InvalidateSimpleKey()
|
||||||
|
{
|
||||||
|
if(m_simpleKeys.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// grab top key
|
||||||
|
SimpleKey& key = m_simpleKeys.top();
|
||||||
|
if(key.flowLevel != m_flowLevel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
key.Invalidate();
|
||||||
|
m_simpleKeys.pop();
|
||||||
|
}
|
||||||
|
|
||||||
// VerifySimpleKey
|
// VerifySimpleKey
|
||||||
// . Determines whether the latest simple key to be added is valid,
|
// . Determines whether the latest simple key to be added is valid,
|
||||||
// and if so, makes it valid.
|
// and if so, makes it valid.
|
||||||
// . If 'force' is true, then we'll pop no matter what (whether we can verify it or not).
|
bool Scanner::VerifySimpleKey()
|
||||||
bool Scanner::VerifySimpleKey(bool force)
|
|
||||||
{
|
{
|
||||||
m_isLastKeyValid = false;
|
m_isLastKeyValid = false;
|
||||||
if(m_simpleKeys.empty())
|
if(m_simpleKeys.empty())
|
||||||
@@ -69,11 +99,8 @@ namespace YAML
|
|||||||
SimpleKey key = m_simpleKeys.top();
|
SimpleKey key = m_simpleKeys.top();
|
||||||
|
|
||||||
// only validate if we're in the correct flow level
|
// only validate if we're in the correct flow level
|
||||||
if(key.flowLevel != m_flowLevel) {
|
if(key.flowLevel != m_flowLevel)
|
||||||
if(force)
|
|
||||||
m_simpleKeys.pop();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
m_simpleKeys.pop();
|
m_simpleKeys.pop();
|
||||||
|
|
||||||
@@ -99,11 +126,9 @@ namespace YAML
|
|||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyAllSimplyKeys
|
void Scanner::PopAllSimpleKeys()
|
||||||
// . Pops all simple keys (with checking, but if we can't verify one, then pop it anyways).
|
|
||||||
void Scanner::VerifyAllSimpleKeys()
|
|
||||||
{
|
{
|
||||||
while(!m_simpleKeys.empty())
|
while(!m_simpleKeys.empty())
|
||||||
VerifySimpleKey(true);
|
m_simpleKeys.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -407,6 +407,54 @@ namespace Test
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AnchorInSimpleKey()
|
||||||
|
{
|
||||||
|
std::string input = "- &a b: c\n- *a";
|
||||||
|
|
||||||
|
std::stringstream stream(input);
|
||||||
|
YAML::Parser parser(stream);
|
||||||
|
YAML::Node doc;
|
||||||
|
parser.GetNextDocument(doc);
|
||||||
|
|
||||||
|
if(doc.size() != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string output;
|
||||||
|
doc[0]["b"] >> output;
|
||||||
|
if(output != "c")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
doc[1] >> output;
|
||||||
|
if(output != "b")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AliasAsSimpleKey()
|
||||||
|
{
|
||||||
|
std::string input = "- &a b\n- *a: c";
|
||||||
|
|
||||||
|
std::stringstream stream(input);
|
||||||
|
YAML::Parser parser(stream);
|
||||||
|
YAML::Node doc;
|
||||||
|
parser.GetNextDocument(doc);
|
||||||
|
|
||||||
|
if(doc.size() != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string output;
|
||||||
|
doc[0] >> output;
|
||||||
|
if(output != "b")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
doc[1]["b"] >> output;
|
||||||
|
if(output != "c")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ExplicitDoc()
|
bool ExplicitDoc()
|
||||||
{
|
{
|
||||||
std::string input = "---\n- one\n- two";
|
std::string input = "---\n- one\n- two";
|
||||||
|
@@ -275,6 +275,8 @@ namespace Test
|
|||||||
RunParserTest(&Parser::NullBlockMapValue, "null block map value", passed);
|
RunParserTest(&Parser::NullBlockMapValue, "null block map value", passed);
|
||||||
RunParserTest(&Parser::SimpleAlias, "simple alias", passed);
|
RunParserTest(&Parser::SimpleAlias, "simple alias", passed);
|
||||||
RunParserTest(&Parser::AliasWithNull, "alias with null", passed);
|
RunParserTest(&Parser::AliasWithNull, "alias with null", passed);
|
||||||
|
RunParserTest(&Parser::AnchorInSimpleKey, "anchor in simple key", passed);
|
||||||
|
RunParserTest(&Parser::AliasAsSimpleKey, "alias as simple key", passed);
|
||||||
RunParserTest(&Parser::ExplicitDoc, "explicit doc", passed);
|
RunParserTest(&Parser::ExplicitDoc, "explicit doc", passed);
|
||||||
RunParserTest(&Parser::MultipleDocs, "multiple docs", passed);
|
RunParserTest(&Parser::MultipleDocs, "multiple docs", passed);
|
||||||
RunParserTest(&Parser::ExplicitEndDoc, "explicit end doc", passed);
|
RunParserTest(&Parser::ExplicitEndDoc, "explicit end doc", passed);
|
||||||
|
@@ -42,6 +42,8 @@ namespace Test {
|
|||||||
bool NullBlockMapValue();
|
bool NullBlockMapValue();
|
||||||
bool SimpleAlias();
|
bool SimpleAlias();
|
||||||
bool AliasWithNull();
|
bool AliasWithNull();
|
||||||
|
bool AnchorInSimpleKey();
|
||||||
|
bool AliasAsSimpleKey();
|
||||||
bool ExplicitDoc();
|
bool ExplicitDoc();
|
||||||
bool MultipleDocs();
|
bool MultipleDocs();
|
||||||
bool ExplicitEndDoc();
|
bool ExplicitEndDoc();
|
||||||
|
Reference in New Issue
Block a user