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