#pragma once #include #include #include #include #include namespace YAML { struct Token; class Scanner { public: Scanner(std::istream& in); ~Scanner(); Token *GetNextToken(); void ScanNextToken(); void ScanToNextToken(); Token *PushIndentTo(int column, bool sequence); void PopIndentTo(int column); void IncreaseFlowLevel(); void DecreaseFlowLevel(); void InsertSimpleKey(); bool ValidateSimpleKey(); void ValidateAllSimpleKeys(); void Scan(); private: char GetChar(); std::string GetChar(int n); void Eat(int n = 1); void EatLineBreak(); bool IsWhitespaceToBeEaten(char ch); bool IsDocumentStart(); bool IsDocumentEnd(); bool IsBlockEntry(); bool IsKey(); bool IsValue(); bool IsPlainScalar(); void GetBlockIndentation(int& indent, std::string& breaks); struct WhitespaceInfo { WhitespaceInfo(); void SetChompers(char ch); void AddBlank(char ch); void AddBreak(const std::string& line); std::string Join(bool lastline = false); bool leadingBlanks; bool fold; std::string whitespace, leadingBreaks, trailingBreaks; int chomp, increment; }; struct SimpleKey { SimpleKey(int pos_, int line_, int column_, int flowLevel_); void Validate(); void Invalidate(); int pos, line, column, flowLevel; bool required; Token *pMapStart, *pKey; }; template void ScanAndEnqueue(T *pToken); template T *ScanToken(T *pToken); private: // the stream std::istream& INPUT; int m_line, m_column; // the output (tokens) std::queue m_tokens; std::set m_limboTokens; // state info bool m_startedStream, m_endedStream; bool m_simpleKeyAllowed; int m_flowLevel; // number of unclosed '[' and '{' indicators bool m_isLastKeyValid; std::stack m_simpleKeys; std::stack m_indents; }; }