remove button colors from quarks gui (cocoa + swing)
[supercollider.git] / external_libraries / yaml-cpp-0.2.6 / src / singledocparser.cpp
blob47759c324fa329fb62acb1e6c723615e0d070ade
1 #include "singledocparser.h"
2 #include "collectionstack.h"
3 #include "directives.h"
4 #include "yaml-cpp/eventhandler.h"
5 #include "yaml-cpp/exceptions.h"
6 #include "scanner.h"
7 #include "tag.h"
8 #include "token.h"
9 #include <sstream>
10 #include <cstdio>
11 #include <algorithm>
13 namespace YAML
15 SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0)
19 SingleDocParser::~SingleDocParser()
23 // HandleDocument
24 // . Handles the next document
25 // . Throws a ParserException on error.
26 void SingleDocParser::HandleDocument(EventHandler& eventHandler)
28 assert(!m_scanner.empty()); // guaranteed that there are tokens
29 assert(!m_curAnchor);
31 eventHandler.OnDocumentStart(m_scanner.peek().mark);
33 // eat doc start
34 if(m_scanner.peek().type == Token::DOC_START)
35 m_scanner.pop();
37 // recurse!
38 HandleNode(eventHandler);
40 eventHandler.OnDocumentEnd();
42 // and finally eat any doc ends we see
43 while(!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
44 m_scanner.pop();
47 void SingleDocParser::HandleNode(EventHandler& eventHandler)
49 // an empty node *is* a possibility
50 if(m_scanner.empty()) {
51 eventHandler.OnNull(Mark::null(), NullAnchor);
52 return;
55 // save location
56 Mark mark = m_scanner.peek().mark;
58 // special case: a value node by itself must be a map, with no header
59 if(m_scanner.peek().type == Token::VALUE) {
60 eventHandler.OnMapStart(mark, "", NullAnchor);
61 HandleMap(eventHandler);
62 eventHandler.OnMapEnd();
63 return;
66 // special case: an alias node
67 if(m_scanner.peek().type == Token::ALIAS) {
68 eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
69 m_scanner.pop();
70 return;
73 std::string tag;
74 anchor_t anchor;
75 ParseProperties(tag, anchor);
77 const Token& token = m_scanner.peek();
79 // add non-specific tags
80 if(tag.empty())
81 tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
83 // now split based on what kind of node we should be
84 switch(token.type) {
85 case Token::PLAIN_SCALAR:
86 case Token::NON_PLAIN_SCALAR:
87 eventHandler.OnScalar(mark, tag, anchor, token.value);
88 m_scanner.pop();
89 return;
90 case Token::FLOW_SEQ_START:
91 case Token::BLOCK_SEQ_START:
92 eventHandler.OnSequenceStart(mark, tag, anchor);
93 HandleSequence(eventHandler);
94 eventHandler.OnSequenceEnd();
95 return;
96 case Token::FLOW_MAP_START:
97 case Token::BLOCK_MAP_START:
98 eventHandler.OnMapStart(mark, tag, anchor);
99 HandleMap(eventHandler);
100 eventHandler.OnMapEnd();
101 return;
102 case Token::KEY:
103 // compact maps can only go in a flow sequence
104 if(m_pCollectionStack->GetCurCollectionType() == CollectionType::FlowSeq) {
105 eventHandler.OnMapStart(mark, tag, anchor);
106 HandleMap(eventHandler);
107 eventHandler.OnMapEnd();
108 return;
110 break;
111 default:
112 break;
115 if(tag == "?")
116 eventHandler.OnNull(mark, anchor);
117 else
118 eventHandler.OnScalar(mark, tag, anchor, "");
121 void SingleDocParser::HandleSequence(EventHandler& eventHandler)
123 // split based on start token
124 switch(m_scanner.peek().type) {
125 case Token::BLOCK_SEQ_START: HandleBlockSequence(eventHandler); break;
126 case Token::FLOW_SEQ_START: HandleFlowSequence(eventHandler); break;
127 default: break;
131 void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler)
133 // eat start token
134 m_scanner.pop();
135 m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
137 while(1) {
138 if(m_scanner.empty())
139 throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
141 Token token = m_scanner.peek();
142 if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
143 throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
145 m_scanner.pop();
146 if(token.type == Token::BLOCK_SEQ_END)
147 break;
149 // check for null
150 if(!m_scanner.empty()) {
151 const Token& token = m_scanner.peek();
152 if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END) {
153 eventHandler.OnNull(token.mark, NullAnchor);
154 continue;
158 HandleNode(eventHandler);
161 m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
164 void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler)
166 // eat start token
167 m_scanner.pop();
168 m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
170 while(1) {
171 if(m_scanner.empty())
172 throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
174 // first check for end
175 if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
176 m_scanner.pop();
177 break;
180 // then read the node
181 HandleNode(eventHandler);
183 // now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
184 Token& token = m_scanner.peek();
185 if(token.type == Token::FLOW_ENTRY)
186 m_scanner.pop();
187 else if(token.type != Token::FLOW_SEQ_END)
188 throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
191 m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
194 void SingleDocParser::HandleMap(EventHandler& eventHandler)
196 // split based on start token
197 switch(m_scanner.peek().type) {
198 case Token::BLOCK_MAP_START: HandleBlockMap(eventHandler); break;
199 case Token::FLOW_MAP_START: HandleFlowMap(eventHandler); break;
200 case Token::KEY: HandleCompactMap(eventHandler); break;
201 case Token::VALUE: HandleCompactMapWithNoKey(eventHandler); break;
202 default: break;
206 void SingleDocParser::HandleBlockMap(EventHandler& eventHandler)
208 // eat start token
209 m_scanner.pop();
210 m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
212 while(1) {
213 if(m_scanner.empty())
214 throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
216 Token token = m_scanner.peek();
217 if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
218 throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
220 if(token.type == Token::BLOCK_MAP_END) {
221 m_scanner.pop();
222 break;
225 // grab key (if non-null)
226 if(token.type == Token::KEY) {
227 m_scanner.pop();
228 HandleNode(eventHandler);
229 } else {
230 eventHandler.OnNull(token.mark, NullAnchor);
233 // now grab value (optional)
234 if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
235 m_scanner.pop();
236 HandleNode(eventHandler);
237 } else {
238 eventHandler.OnNull(token.mark, NullAnchor);
242 m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
245 void SingleDocParser::HandleFlowMap(EventHandler& eventHandler)
247 // eat start token
248 m_scanner.pop();
249 m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
251 while(1) {
252 if(m_scanner.empty())
253 throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
255 Token& token = m_scanner.peek();
256 // first check for end
257 if(token.type == Token::FLOW_MAP_END) {
258 m_scanner.pop();
259 break;
262 // grab key (if non-null)
263 if(token.type == Token::KEY) {
264 m_scanner.pop();
265 HandleNode(eventHandler);
266 } else {
267 eventHandler.OnNull(token.mark, NullAnchor);
270 // now grab value (optional)
271 if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
272 m_scanner.pop();
273 HandleNode(eventHandler);
274 } else {
275 eventHandler.OnNull(token.mark, NullAnchor);
278 // now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
279 Token& nextToken = m_scanner.peek();
280 if(nextToken.type == Token::FLOW_ENTRY)
281 m_scanner.pop();
282 else if(nextToken.type != Token::FLOW_MAP_END)
283 throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
286 m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
289 // . Single "key: value" pair in a flow sequence
290 void SingleDocParser::HandleCompactMap(EventHandler& eventHandler)
292 m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
294 // grab key
295 Mark mark = m_scanner.peek().mark;
296 m_scanner.pop();
297 HandleNode(eventHandler);
299 // now grab value (optional)
300 if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
301 m_scanner.pop();
302 HandleNode(eventHandler);
303 } else {
304 eventHandler.OnNull(mark, NullAnchor);
307 m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
310 // . Single ": value" pair in a flow sequence
311 void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler)
313 m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
315 // null key
316 eventHandler.OnNull(m_scanner.peek().mark, NullAnchor);
318 // grab value
319 m_scanner.pop();
320 HandleNode(eventHandler);
322 m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
325 // ParseProperties
326 // . Grabs any tag or anchor tokens and deals with them.
327 void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor)
329 tag.clear();
330 anchor = NullAnchor;
332 while(1) {
333 if(m_scanner.empty())
334 return;
336 switch(m_scanner.peek().type) {
337 case Token::TAG: ParseTag(tag); break;
338 case Token::ANCHOR: ParseAnchor(anchor); break;
339 default: return;
344 void SingleDocParser::ParseTag(std::string& tag)
346 Token& token = m_scanner.peek();
347 if(!tag.empty())
348 throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
350 Tag tagInfo(token);
351 tag = tagInfo.Translate(m_directives);
352 m_scanner.pop();
355 void SingleDocParser::ParseAnchor(anchor_t& anchor)
357 Token& token = m_scanner.peek();
358 if(anchor)
359 throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
361 anchor = RegisterAnchor(token.value);
362 m_scanner.pop();
365 anchor_t SingleDocParser::RegisterAnchor(const std::string& name)
367 if(name.empty())
368 return NullAnchor;
370 return m_anchors[name] = ++m_curAnchor;
373 anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const
375 Anchors::const_iterator it = m_anchors.find(name);
376 if(it == m_anchors.end())
377 throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
379 return it->second;