Finished refactoring of simple keys so that they can refer to multiple tokens at a single level

This commit is contained in:
Jesse Beder
2009-09-05 03:49:38 +00:00
parent 0e1638d7b5
commit 75477ade65
7 changed files with 126 additions and 44 deletions

View File

@@ -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()));

View File

@@ -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);

View File

@@ -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();

View File

@@ -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();
} }
} }

View File

@@ -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";

View File

@@ -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);

View File

@@ -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();