You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
#include "scanner.h"
#include "token.h"
namespace YAML { struct Mark;
Scanner::SimpleKey::SimpleKey(const Mark& mark_, std::size_t flowLevel_) : mark(mark_), flowLevel(flowLevel_), pIndent(nullptr), pMapStart(nullptr), pKey(nullptr) {}
void Scanner::SimpleKey::Validate() { // Note: pIndent will *not* be garbage here;
// we "garbage collect" them so we can
// always refer to them
if (pIndent) pIndent->status = IndentMarker::VALID; if (pMapStart) pMapStart->status = Token::VALID; if (pKey) pKey->status = Token::VALID; }
void Scanner::SimpleKey::Invalidate() { if (pIndent) pIndent->status = IndentMarker::INVALID; if (pMapStart) pMapStart->status = Token::INVALID; if (pKey) pKey->status = Token::INVALID; }
// CanInsertPotentialSimpleKey
bool Scanner::CanInsertPotentialSimpleKey() const { if (!m_simpleKeyAllowed) return false;
return !ExistsActiveSimpleKey(); }
// 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 == GetFlowLevel(); }
// InsertPotentialSimpleKey
// . If we can, add a potential simple key to the queue,
// and save it on a stack.
void Scanner::InsertPotentialSimpleKey() { if (!CanInsertPotentialSimpleKey()) return;
SimpleKey key(INPUT.mark(), GetFlowLevel());
// first add a map start, if necessary
if (InBlockContext()) { key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP); if (key.pIndent) { key.pIndent->status = IndentMarker::UNKNOWN; key.pMapStart = key.pIndent->pStartToken; key.pMapStart->status = Token::UNVERIFIED; } }
// then add the (now unverified) key
m_tokens.push(Token(Token::KEY, INPUT.mark())); key.pKey = &m_tokens.back(); key.pKey->status = Token::UNVERIFIED;
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 != GetFlowLevel()) return;
key.Invalidate(); m_simpleKeys.pop(); }
// VerifySimpleKey
// . Determines whether the latest simple key to be added is valid,
// and if so, makes it valid.
bool Scanner::VerifySimpleKey() { if (m_simpleKeys.empty()) return false;
// grab top key
SimpleKey key = m_simpleKeys.top();
// only validate if we're in the correct flow level
if (key.flowLevel != GetFlowLevel()) return false;
m_simpleKeys.pop();
bool isValid = true;
// needs to be less than 1024 characters and inline
if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) isValid = false;
// invalidate key
if (isValid) key.Validate(); else key.Invalidate();
return isValid; }
void Scanner::PopAllSimpleKeys() { while (!m_simpleKeys.empty()) m_simpleKeys.pop(); } } // namespace YAML
|