Go to the documentation of this file.00001 #ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66_PM
00002 #define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66_PM
00003
00004 #if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
00005 #pragma once
00006 #endif
00007
00008
00009 #include <ios>
00010 #include <string>
00011 #include <queue>
00012 #include <stack>
00013 #include <set>
00014 #include <map>
00015 #include "ptr_vector.h"
00016 #include "stream.h"
00017 #include "token.h"
00018
00019 namespace YAML_PM
00020 {
00021 class Node;
00022 class RegEx;
00023
00024 class Scanner
00025 {
00026 public:
00027 Scanner(std::istream& in);
00028 ~Scanner();
00029
00030
00031 bool empty();
00032 void pop();
00033 Token& peek();
00034
00035 private:
00036 struct IndentMarker {
00037 enum INDENT_TYPE { MAP, SEQ, NONE };
00038 enum STATUS { VALID, INVALID, UNKNOWN };
00039 IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), status(VALID), pStartToken(0) {}
00040
00041 int column;
00042 INDENT_TYPE type;
00043 STATUS status;
00044 Token *pStartToken;
00045 };
00046
00047 enum FLOW_MARKER { FLOW_MAP, FLOW_SEQ };
00048
00049 private:
00050
00051 void EnsureTokensInQueue();
00052 void ScanNextToken();
00053 void ScanToNextToken();
00054 void StartStream();
00055 void EndStream();
00056 Token *PushToken(Token::TYPE type);
00057
00058 bool InFlowContext() const { return !m_flows.empty(); }
00059 bool InBlockContext() const { return m_flows.empty(); }
00060 int GetFlowLevel() const { return m_flows.size(); }
00061
00062 Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const;
00063 IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
00064 void PopIndentToHere();
00065 void PopAllIndents();
00066 void PopIndent();
00067 int GetTopIndent() const;
00068
00069
00070 bool CanInsertPotentialSimpleKey() const;
00071 bool ExistsActiveSimpleKey() const;
00072 void InsertPotentialSimpleKey();
00073 void InvalidateSimpleKey();
00074 bool VerifySimpleKey();
00075 void PopAllSimpleKeys();
00076
00077 void ThrowParserException(const std::string& msg) const;
00078
00079 bool IsWhitespaceToBeEaten(char ch);
00080 const RegEx& GetValueRegex() const;
00081
00082 struct SimpleKey {
00083 SimpleKey(const Mark& mark_, int flowLevel_);
00084
00085 void Validate();
00086 void Invalidate();
00087
00088 Mark mark;
00089 int flowLevel;
00090 IndentMarker *pIndent;
00091 Token *pMapStart, *pKey;
00092 };
00093
00094
00095 void ScanDirective();
00096 void ScanDocStart();
00097 void ScanDocEnd();
00098 void ScanBlockSeqStart();
00099 void ScanBlockMapSTart();
00100 void ScanBlockEnd();
00101 void ScanBlockEntry();
00102 void ScanFlowStart();
00103 void ScanFlowEnd();
00104 void ScanFlowEntry();
00105 void ScanKey();
00106 void ScanValue();
00107 void ScanAnchorOrAlias();
00108 void ScanTag();
00109 void ScanPlainScalar();
00110 void ScanQuotedScalar();
00111 void ScanBlockScalar();
00112
00113 private:
00114
00115 Stream INPUT;
00116
00117
00118 std::queue<Token> m_tokens;
00119
00120
00121 bool m_startedStream, m_endedStream;
00122 bool m_simpleKeyAllowed;
00123 bool m_canBeJSONFlow;
00124 std::stack<SimpleKey> m_simpleKeys;
00125 std::stack<IndentMarker *> m_indents;
00126 ptr_vector<IndentMarker> m_indentRefs;
00127 std::stack<FLOW_MARKER> m_flows;
00128 };
00129 }
00130
00131 #endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66_PM
00132