Finished refactoring of simple keys so that they can refer to multiple tokens at a single level
This commit is contained in:
parent
0e1638d7b5
commit
75477ade65
@ -46,7 +46,13 @@ namespace YAML
|
||||
assert(!m_tokens.empty()); // should we be asserting here? I mean, we really just be checking
|
||||
// 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();
|
||||
}
|
||||
|
||||
@ -98,9 +104,6 @@ namespace YAML
|
||||
// maybe need to end some blocks
|
||||
PopIndentToHere();
|
||||
|
||||
// check the latest simple key
|
||||
VerifySimpleKey();
|
||||
|
||||
// *****
|
||||
// And now branch based on the next few characters!
|
||||
// *****
|
||||
@ -187,7 +190,7 @@ namespace YAML
|
||||
INPUT.eat(n);
|
||||
|
||||
// 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
|
||||
if(m_flowLevel == 0)
|
||||
@ -235,7 +238,7 @@ namespace YAML
|
||||
INPUT.ResetColumn();
|
||||
|
||||
PopAllIndents();
|
||||
VerifyAllSimpleKeys();
|
||||
PopAllSimpleKeys();
|
||||
|
||||
m_simpleKeyAllowed = false;
|
||||
m_endedStream = true;
|
||||
@ -321,8 +324,10 @@ namespace YAML
|
||||
IndentMarker indent = m_indents.top();
|
||||
IndentMarker::INDENT_TYPE type = indent.type;
|
||||
m_indents.pop();
|
||||
if(!indent.isValid)
|
||||
if(!indent.isValid) {
|
||||
InvalidateSimpleKey();
|
||||
return;
|
||||
}
|
||||
|
||||
if(type == IndentMarker::SEQ)
|
||||
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
|
||||
|
@ -58,9 +58,12 @@ namespace YAML
|
||||
int GetTopIndent() const;
|
||||
|
||||
// checking input
|
||||
void InsertSimpleKey();
|
||||
bool VerifySimpleKey(bool force = false);
|
||||
void VerifyAllSimpleKeys();
|
||||
bool ExistsActiveSimpleKey() const;
|
||||
void InsertPotentialSimpleKey();
|
||||
void InvalidateSimpleKey();
|
||||
bool VerifySimpleKey();
|
||||
void PopAllSimpleKeys();
|
||||
|
||||
void ThrowParserException(const std::string& msg) const;
|
||||
|
||||
bool IsWhitespaceToBeEaten(char ch);
|
||||
|
@ -20,7 +20,7 @@ namespace YAML
|
||||
|
||||
// pop indents and simple keys
|
||||
PopAllIndents();
|
||||
VerifyAllSimpleKeys();
|
||||
PopAllSimpleKeys();
|
||||
|
||||
m_simpleKeyAllowed = false;
|
||||
|
||||
@ -60,7 +60,7 @@ namespace YAML
|
||||
void Scanner::ScanDocStart()
|
||||
{
|
||||
PopAllIndents();
|
||||
VerifyAllSimpleKeys();
|
||||
PopAllSimpleKeys();
|
||||
m_simpleKeyAllowed = false;
|
||||
|
||||
// eat
|
||||
@ -73,7 +73,7 @@ namespace YAML
|
||||
void Scanner::ScanDocEnd()
|
||||
{
|
||||
PopAllIndents();
|
||||
VerifyAllSimpleKeys();
|
||||
PopAllSimpleKeys();
|
||||
m_simpleKeyAllowed = false;
|
||||
|
||||
// eat
|
||||
@ -86,7 +86,7 @@ namespace YAML
|
||||
void Scanner::ScanFlowStart()
|
||||
{
|
||||
// flows can be simple keys
|
||||
InsertSimpleKey();
|
||||
InsertPotentialSimpleKey();
|
||||
m_flowLevel++;
|
||||
m_simpleKeyAllowed = true;
|
||||
|
||||
@ -103,6 +103,7 @@ namespace YAML
|
||||
if(m_flowLevel == 0)
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
|
||||
|
||||
InvalidateSimpleKey();
|
||||
m_flowLevel--;
|
||||
m_simpleKeyAllowed = false;
|
||||
|
||||
@ -170,8 +171,13 @@ namespace YAML
|
||||
// Value
|
||||
void Scanner::ScanValue()
|
||||
{
|
||||
// does this follow a simple key?
|
||||
if(m_isLastKeyValid) {
|
||||
// just in case we have an empty key
|
||||
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)
|
||||
m_simpleKeyAllowed = false;
|
||||
} else {
|
||||
@ -181,19 +187,10 @@ namespace YAML
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
|
||||
|
||||
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
|
||||
if(m_flowLevel == 0)
|
||||
m_simpleKeyAllowed = true;
|
||||
else
|
||||
m_simpleKeyAllowed = false;
|
||||
m_simpleKeyAllowed = (m_flowLevel == 0);
|
||||
}
|
||||
|
||||
// eat
|
||||
@ -210,7 +207,7 @@ namespace YAML
|
||||
|
||||
// insert a potential simple key
|
||||
if(m_simpleKeyAllowed)
|
||||
InsertSimpleKey();
|
||||
InsertPotentialSimpleKey();
|
||||
m_simpleKeyAllowed = false;
|
||||
|
||||
// eat the indicator
|
||||
@ -243,7 +240,7 @@ namespace YAML
|
||||
|
||||
// insert a potential simple key
|
||||
if(m_simpleKeyAllowed)
|
||||
InsertSimpleKey();
|
||||
InsertPotentialSimpleKey();
|
||||
m_simpleKeyAllowed = false;
|
||||
|
||||
// eat the indicator
|
||||
@ -293,7 +290,7 @@ namespace YAML
|
||||
|
||||
// insert a potential simple key
|
||||
if(m_simpleKeyAllowed)
|
||||
InsertSimpleKey();
|
||||
InsertPotentialSimpleKey();
|
||||
|
||||
Mark mark = INPUT.mark();
|
||||
scalar = ScanScalar(INPUT, params);
|
||||
@ -333,7 +330,7 @@ namespace YAML
|
||||
|
||||
// insert a potential simple key
|
||||
if(m_simpleKeyAllowed)
|
||||
InsertSimpleKey();
|
||||
InsertPotentialSimpleKey();
|
||||
|
||||
Mark mark = INPUT.mark();
|
||||
|
||||
|
@ -32,11 +32,26 @@ namespace YAML
|
||||
pKey->status = Token::INVALID;
|
||||
}
|
||||
|
||||
// InsertSimpleKey
|
||||
// . Adds a potential simple key to the queue,
|
||||
// and saves it on a stack.
|
||||
void Scanner::InsertSimpleKey()
|
||||
// ExistsActiveSimpleKey
|
||||
// . Returns true if there's a potential simple key at our flow level
|
||||
// (there's allowed at most one per flow level, i.e., at the start of the flow start token)
|
||||
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);
|
||||
|
||||
// first add a map start, if necessary
|
||||
@ -55,11 +70,26 @@ namespace YAML
|
||||
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
|
||||
// . Determines whether the latest simple key to be added is 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 force)
|
||||
bool Scanner::VerifySimpleKey()
|
||||
{
|
||||
m_isLastKeyValid = false;
|
||||
if(m_simpleKeys.empty())
|
||||
@ -69,11 +99,8 @@ namespace YAML
|
||||
SimpleKey key = m_simpleKeys.top();
|
||||
|
||||
// only validate if we're in the correct flow level
|
||||
if(key.flowLevel != m_flowLevel) {
|
||||
if(force)
|
||||
m_simpleKeys.pop();
|
||||
if(key.flowLevel != m_flowLevel)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_simpleKeys.pop();
|
||||
|
||||
@ -99,11 +126,9 @@ namespace YAML
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// VerifyAllSimplyKeys
|
||||
// . Pops all simple keys (with checking, but if we can't verify one, then pop it anyways).
|
||||
void Scanner::VerifyAllSimpleKeys()
|
||||
void Scanner::PopAllSimpleKeys()
|
||||
{
|
||||
while(!m_simpleKeys.empty())
|
||||
VerifySimpleKey(true);
|
||||
m_simpleKeys.pop();
|
||||
}
|
||||
}
|
||||
|
@ -407,6 +407,54 @@ namespace Test
|
||||
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()
|
||||
{
|
||||
std::string input = "---\n- one\n- two";
|
||||
|
@ -275,6 +275,8 @@ namespace Test
|
||||
RunParserTest(&Parser::NullBlockMapValue, "null block map value", passed);
|
||||
RunParserTest(&Parser::SimpleAlias, "simple alias", 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::MultipleDocs, "multiple docs", passed);
|
||||
RunParserTest(&Parser::ExplicitEndDoc, "explicit end doc", passed);
|
||||
|
@ -42,6 +42,8 @@ namespace Test {
|
||||
bool NullBlockMapValue();
|
||||
bool SimpleAlias();
|
||||
bool AliasWithNull();
|
||||
bool AnchorInSimpleKey();
|
||||
bool AliasAsSimpleKey();
|
||||
bool ExplicitDoc();
|
||||
bool MultipleDocs();
|
||||
bool ExplicitEndDoc();
|
||||
|
Loading…
Reference in New Issue
Block a user