1 #ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 #define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 4 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 5 #pragma once 6 #endif 7 8 9 #include <ios> 10 #include <string> 11 #include <queue> 12 #include <stack> 13 #include <set> 14 #include <map> 15 #include "ptr_vector.h" 16 #include "stream.h" 17 #include "token.h" 18 19 namespace YAML 20 { 21 class Node; 22 class RegEx; 23 24 class Scanner 25 { 26 public: 27 Scanner(std::istream& in); 28 ~Scanner(); 29 30 // token queue management (hopefully this looks kinda stl-ish) 31 bool empty(); 32 void pop(); 33 Token& peek(); 34 35 private: 36 struct IndentMarker { 37 enum INDENT_TYPE { MAP, SEQ, NONE }; 38 enum STATUS { VALID, INVALID, UNKNOWN }; IndentMarkerIndentMarker39 IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), status(VALID), pStartToken(0) {} 40 41 int column; 42 INDENT_TYPE type; 43 STATUS status; 44 Token *pStartToken; 45 }; 46 47 enum FLOW_MARKER { FLOW_MAP, FLOW_SEQ }; 48 49 private: 50 // scanning 51 void EnsureTokensInQueue(); 52 void ScanNextToken(); 53 void ScanToNextToken(); 54 void StartStream(); 55 void EndStream(); 56 Token *PushToken(Token::TYPE type); 57 InFlowContext()58 bool InFlowContext() const { return !m_flows.empty(); } InBlockContext()59 bool InBlockContext() const { return m_flows.empty(); } GetFlowLevel()60 int GetFlowLevel() const { return m_flows.size(); } 61 62 Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const; 63 IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type); 64 void PopIndentToHere(); 65 void PopAllIndents(); 66 void PopIndent(); 67 int GetTopIndent() const; 68 69 // checking input 70 bool CanInsertPotentialSimpleKey() const; 71 bool ExistsActiveSimpleKey() const; 72 void InsertPotentialSimpleKey(); 73 void InvalidateSimpleKey(); 74 bool VerifySimpleKey(); 75 void PopAllSimpleKeys(); 76 77 void ThrowParserException(const std::string& msg) const; 78 79 bool IsWhitespaceToBeEaten(char ch); 80 const RegEx& GetValueRegex() const; 81 82 struct SimpleKey { 83 SimpleKey(const Mark& mark_, int flowLevel_); 84 85 void Validate(); 86 void Invalidate(); 87 88 Mark mark; 89 int flowLevel; 90 IndentMarker *pIndent; 91 Token *pMapStart, *pKey; 92 }; 93 94 // and the tokens 95 void ScanDirective(); 96 void ScanDocStart(); 97 void ScanDocEnd(); 98 void ScanBlockSeqStart(); 99 void ScanBlockMapSTart(); 100 void ScanBlockEnd(); 101 void ScanBlockEntry(); 102 void ScanFlowStart(); 103 void ScanFlowEnd(); 104 void ScanFlowEntry(); 105 void ScanKey(); 106 void ScanValue(); 107 void ScanAnchorOrAlias(); 108 void ScanTag(); 109 void ScanPlainScalar(); 110 void ScanQuotedScalar(); 111 void ScanBlockScalar(); 112 113 private: 114 // the stream 115 Stream INPUT; 116 117 // the output (tokens) 118 std::queue<Token> m_tokens; 119 120 // state info 121 bool m_startedStream, m_endedStream; 122 bool m_simpleKeyAllowed; 123 bool m_canBeJSONFlow; 124 std::stack<SimpleKey> m_simpleKeys; 125 std::stack<IndentMarker *> m_indents; 126 ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection" 127 std::stack<FLOW_MARKER> m_flows; 128 }; 129 } 130 131 #endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 132 133