Go to the documentation of this file.00001 #include "singledocparser.h"
00002 #include "collectionstack.h"
00003 #include "directives.h"
00004 #include "yaml-cpp-pm/eventhandler.h"
00005 #include "yaml-cpp-pm/exceptions.h"
00006 #include "scanner.h"
00007 #include "tag.h"
00008 #include "token.h"
00009 #include <sstream>
00010 #include <cstdio>
00011 #include <algorithm>
00012
00013 namespace YAML_PM
00014 {
00015 SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0)
00016 {
00017 }
00018
00019 SingleDocParser::~SingleDocParser()
00020 {
00021 }
00022
00023
00024
00025
00026 void SingleDocParser::HandleDocument(EventHandler& eventHandler)
00027 {
00028 assert(!m_scanner.empty());
00029 assert(!m_curAnchor);
00030
00031 eventHandler.OnDocumentStart(m_scanner.peek().mark);
00032
00033
00034 if(m_scanner.peek().type == Token::DOC_START)
00035 m_scanner.pop();
00036
00037
00038 HandleNode(eventHandler);
00039
00040 eventHandler.OnDocumentEnd();
00041
00042
00043 while(!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
00044 m_scanner.pop();
00045 }
00046
00047 void SingleDocParser::HandleNode(EventHandler& eventHandler)
00048 {
00049
00050 if(m_scanner.empty()) {
00051 eventHandler.OnNull(Mark::null(), NullAnchor);
00052 return;
00053 }
00054
00055
00056 Mark mark = m_scanner.peek().mark;
00057
00058
00059 if(m_scanner.peek().type == Token::VALUE) {
00060 eventHandler.OnMapStart(mark, "", NullAnchor);
00061 HandleMap(eventHandler);
00062 eventHandler.OnMapEnd();
00063 return;
00064 }
00065
00066
00067 if(m_scanner.peek().type == Token::ALIAS) {
00068 eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
00069 m_scanner.pop();
00070 return;
00071 }
00072
00073 std::string tag;
00074 anchor_t anchor;
00075 ParseProperties(tag, anchor);
00076
00077 const Token& token = m_scanner.peek();
00078
00079
00080 if(tag.empty())
00081 tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
00082
00083
00084 switch(token.type) {
00085 case Token::PLAIN_SCALAR:
00086 case Token::NON_PLAIN_SCALAR:
00087 eventHandler.OnScalar(mark, tag, anchor, token.value);
00088 m_scanner.pop();
00089 return;
00090 case Token::FLOW_SEQ_START:
00091 case Token::BLOCK_SEQ_START:
00092 eventHandler.OnSequenceStart(mark, tag, anchor);
00093 HandleSequence(eventHandler);
00094 eventHandler.OnSequenceEnd();
00095 return;
00096 case Token::FLOW_MAP_START:
00097 case Token::BLOCK_MAP_START:
00098 eventHandler.OnMapStart(mark, tag, anchor);
00099 HandleMap(eventHandler);
00100 eventHandler.OnMapEnd();
00101 return;
00102 case Token::KEY:
00103
00104 if(m_pCollectionStack->GetCurCollectionType() == CollectionType::FlowSeq) {
00105 eventHandler.OnMapStart(mark, tag, anchor);
00106 HandleMap(eventHandler);
00107 eventHandler.OnMapEnd();
00108 return;
00109 }
00110 break;
00111 default:
00112 break;
00113 }
00114
00115 if(tag == "?")
00116 eventHandler.OnNull(mark, anchor);
00117 else
00118 eventHandler.OnScalar(mark, tag, anchor, "");
00119 }
00120
00121 void SingleDocParser::HandleSequence(EventHandler& eventHandler)
00122 {
00123
00124 switch(m_scanner.peek().type) {
00125 case Token::BLOCK_SEQ_START: HandleBlockSequence(eventHandler); break;
00126 case Token::FLOW_SEQ_START: HandleFlowSequence(eventHandler); break;
00127 default: break;
00128 }
00129 }
00130
00131 void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler)
00132 {
00133
00134 m_scanner.pop();
00135 m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
00136
00137 while(1) {
00138 if(m_scanner.empty())
00139 throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
00140
00141 Token token = m_scanner.peek();
00142 if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
00143 throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
00144
00145 m_scanner.pop();
00146 if(token.type == Token::BLOCK_SEQ_END)
00147 break;
00148
00149
00150 if(!m_scanner.empty()) {
00151 const Token& token = m_scanner.peek();
00152 if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END) {
00153 eventHandler.OnNull(token.mark, NullAnchor);
00154 continue;
00155 }
00156 }
00157
00158 HandleNode(eventHandler);
00159 }
00160
00161 m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
00162 }
00163
00164 void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler)
00165 {
00166
00167 m_scanner.pop();
00168 m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
00169
00170 while(1) {
00171 if(m_scanner.empty())
00172 throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
00173
00174
00175 if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
00176 m_scanner.pop();
00177 break;
00178 }
00179
00180
00181 HandleNode(eventHandler);
00182
00183
00184 Token& token = m_scanner.peek();
00185 if(token.type == Token::FLOW_ENTRY)
00186 m_scanner.pop();
00187 else if(token.type != Token::FLOW_SEQ_END)
00188 throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
00189 }
00190
00191 m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
00192 }
00193
00194 void SingleDocParser::HandleMap(EventHandler& eventHandler)
00195 {
00196
00197 switch(m_scanner.peek().type) {
00198 case Token::BLOCK_MAP_START: HandleBlockMap(eventHandler); break;
00199 case Token::FLOW_MAP_START: HandleFlowMap(eventHandler); break;
00200 case Token::KEY: HandleCompactMap(eventHandler); break;
00201 case Token::VALUE: HandleCompactMapWithNoKey(eventHandler); break;
00202 default: break;
00203 }
00204 }
00205
00206 void SingleDocParser::HandleBlockMap(EventHandler& eventHandler)
00207 {
00208
00209 m_scanner.pop();
00210 m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
00211
00212 while(1) {
00213 if(m_scanner.empty())
00214 throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
00215
00216 Token token = m_scanner.peek();
00217 if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
00218 throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
00219
00220 if(token.type == Token::BLOCK_MAP_END) {
00221 m_scanner.pop();
00222 break;
00223 }
00224
00225
00226 if(token.type == Token::KEY) {
00227 m_scanner.pop();
00228 HandleNode(eventHandler);
00229 } else {
00230 eventHandler.OnNull(token.mark, NullAnchor);
00231 }
00232
00233
00234 if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
00235 m_scanner.pop();
00236 HandleNode(eventHandler);
00237 } else {
00238 eventHandler.OnNull(token.mark, NullAnchor);
00239 }
00240 }
00241
00242 m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
00243 }
00244
00245 void SingleDocParser::HandleFlowMap(EventHandler& eventHandler)
00246 {
00247
00248 m_scanner.pop();
00249 m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
00250
00251 while(1) {
00252 if(m_scanner.empty())
00253 throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
00254
00255 Token& token = m_scanner.peek();
00256
00257 if(token.type == Token::FLOW_MAP_END) {
00258 m_scanner.pop();
00259 break;
00260 }
00261
00262
00263 if(token.type == Token::KEY) {
00264 m_scanner.pop();
00265 HandleNode(eventHandler);
00266 } else {
00267 eventHandler.OnNull(token.mark, NullAnchor);
00268 }
00269
00270
00271 if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
00272 m_scanner.pop();
00273 HandleNode(eventHandler);
00274 } else {
00275 eventHandler.OnNull(token.mark, NullAnchor);
00276 }
00277
00278
00279 Token& nextToken = m_scanner.peek();
00280 if(nextToken.type == Token::FLOW_ENTRY)
00281 m_scanner.pop();
00282 else if(nextToken.type != Token::FLOW_MAP_END)
00283 throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
00284 }
00285
00286 m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
00287 }
00288
00289
00290 void SingleDocParser::HandleCompactMap(EventHandler& eventHandler)
00291 {
00292 m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
00293
00294
00295 Mark mark = m_scanner.peek().mark;
00296 m_scanner.pop();
00297 HandleNode(eventHandler);
00298
00299
00300 if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
00301 m_scanner.pop();
00302 HandleNode(eventHandler);
00303 } else {
00304 eventHandler.OnNull(mark, NullAnchor);
00305 }
00306
00307 m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
00308 }
00309
00310
00311 void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler)
00312 {
00313 m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
00314
00315
00316 eventHandler.OnNull(m_scanner.peek().mark, NullAnchor);
00317
00318
00319 m_scanner.pop();
00320 HandleNode(eventHandler);
00321
00322 m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
00323 }
00324
00325
00326
00327 void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor)
00328 {
00329 tag.clear();
00330 anchor = NullAnchor;
00331
00332 while(1) {
00333 if(m_scanner.empty())
00334 return;
00335
00336 switch(m_scanner.peek().type) {
00337 case Token::TAG: ParseTag(tag); break;
00338 case Token::ANCHOR: ParseAnchor(anchor); break;
00339 default: return;
00340 }
00341 }
00342 }
00343
00344 void SingleDocParser::ParseTag(std::string& tag)
00345 {
00346 Token& token = m_scanner.peek();
00347 if(!tag.empty())
00348 throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
00349
00350 Tag tagInfo(token);
00351 tag = tagInfo.Translate(m_directives);
00352 m_scanner.pop();
00353 }
00354
00355 void SingleDocParser::ParseAnchor(anchor_t& anchor)
00356 {
00357 Token& token = m_scanner.peek();
00358 if(anchor)
00359 throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
00360
00361 anchor = RegisterAnchor(token.value);
00362 m_scanner.pop();
00363 }
00364
00365 anchor_t SingleDocParser::RegisterAnchor(const std::string& name)
00366 {
00367 if(name.empty())
00368 return NullAnchor;
00369
00370 return m_anchors[name] = ++m_curAnchor;
00371 }
00372
00373 anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const
00374 {
00375 Anchors::const_iterator it = m_anchors.find(name);
00376 if(it == m_anchors.end())
00377 throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
00378
00379 return it->second;
00380 }
00381 }