singledocparser.cpp
Go to the documentation of this file.
1 #include "singledocparser.h"
2 #include "collectionstack.h"
3 #include "directives.h"
6 #include "scanner.h"
7 #include "tag.h"
8 #include "token.h"
9 #include <sstream>
10 #include <cstdio>
11 #include <algorithm>
12 
13 namespace YAML_PM
14 {
15  SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0)
16  {
17  }
18 
20  {
21  }
22 
23  // HandleDocument
24  // . Handles the next document
25  // . Throws a ParserException on error.
27  {
28  assert(!m_scanner.empty()); // guaranteed that there are tokens
29  assert(!m_curAnchor);
30 
31  eventHandler.OnDocumentStart(m_scanner.peek().mark);
32 
33  // eat doc start
35  m_scanner.pop();
36 
37  // recurse!
38  HandleNode(eventHandler);
39 
40  eventHandler.OnDocumentEnd();
41 
42  // and finally eat any doc ends we see
44  m_scanner.pop();
45  }
46 
48  {
49  // an empty node *is* a possibility
50  if(m_scanner.empty()) {
51  eventHandler.OnNull(Mark::null(), NullAnchor);
52  return;
53  }
54 
55  // save location
56  Mark mark = m_scanner.peek().mark;
57 
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;
64  }
65 
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;
71  }
72 
73  std::string tag;
74  anchor_t anchor;
75  ParseProperties(tag, anchor);
76 
77  const Token& token = m_scanner.peek();
78 
79  // add non-specific tags
80  if(tag.empty())
81  tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
82 
83  // now split based on what kind of node we should be
84  switch(token.type) {
87  eventHandler.OnScalar(mark, tag, anchor, token.value);
88  m_scanner.pop();
89  return;
92  eventHandler.OnSequenceStart(mark, tag, anchor);
93  HandleSequence(eventHandler);
94  eventHandler.OnSequenceEnd();
95  return;
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;
109  }
110  break;
111  default:
112  break;
113  }
114 
115  if(tag == "?")
116  eventHandler.OnNull(mark, anchor);
117  else
118  eventHandler.OnScalar(mark, tag, anchor, "");
119  }
120 
122  {
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;
128  }
129  }
130 
132  {
133  // eat start token
134  m_scanner.pop();
135  m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
136 
137  while(1) {
138  if(m_scanner.empty())
140 
141  Token token = m_scanner.peek();
142  if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
144 
145  m_scanner.pop();
146  if(token.type == Token::BLOCK_SEQ_END)
147  break;
148 
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;
155  }
156  }
157 
158  HandleNode(eventHandler);
159  }
160 
161  m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
162  }
163 
165  {
166  // eat start token
167  m_scanner.pop();
168  m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
169 
170  while(1) {
171  if(m_scanner.empty())
173 
174  // first check for end
176  m_scanner.pop();
177  break;
178  }
179 
180  // then read the node
181  HandleNode(eventHandler);
182 
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)
189  }
190 
191  m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
192  }
193 
195  {
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;
203  }
204  }
205 
207  {
208  // eat start token
209  m_scanner.pop();
210  m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
211 
212  while(1) {
213  if(m_scanner.empty())
215 
216  Token token = m_scanner.peek();
217  if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
219 
220  if(token.type == Token::BLOCK_MAP_END) {
221  m_scanner.pop();
222  break;
223  }
224 
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);
231  }
232 
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);
239  }
240  }
241 
242  m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
243  }
244 
246  {
247  // eat start token
248  m_scanner.pop();
249  m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
250 
251  while(1) {
252  if(m_scanner.empty())
254 
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;
260  }
261 
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);
268  }
269 
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);
276  }
277 
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)
284  }
285 
286  m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
287  }
288 
289  // . Single "key: value" pair in a flow sequence
291  {
292  m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
293 
294  // grab key
295  Mark mark = m_scanner.peek().mark;
296  m_scanner.pop();
297  HandleNode(eventHandler);
298 
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);
305  }
306 
308  }
309 
310  // . Single ": value" pair in a flow sequence
312  {
313  m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
314 
315  // null key
316  eventHandler.OnNull(m_scanner.peek().mark, NullAnchor);
317 
318  // grab value
319  m_scanner.pop();
320  HandleNode(eventHandler);
321 
323  }
324 
325  // ParseProperties
326  // . Grabs any tag or anchor tokens and deals with them.
328  {
329  tag.clear();
330  anchor = NullAnchor;
331 
332  while(1) {
333  if(m_scanner.empty())
334  return;
335 
336  switch(m_scanner.peek().type) {
337  case Token::TAG: ParseTag(tag); break;
338  case Token::ANCHOR: ParseAnchor(anchor); break;
339  default: return;
340  }
341  }
342  }
343 
345  {
346  Token& token = m_scanner.peek();
347  if(!tag.empty())
349 
350  Tag tagInfo(token);
351  tag = tagInfo.Translate(m_directives);
352  m_scanner.pop();
353  }
354 
356  {
357  Token& token = m_scanner.peek();
358  if(anchor)
360 
361  anchor = RegisterAnchor(token.value);
362  m_scanner.pop();
363  }
364 
366  {
367  if(name.empty())
368  return NullAnchor;
369 
370  return m_anchors[name] = ++m_curAnchor;
371  }
372 
373  anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const
374  {
375  Anchors::const_iterator it = m_anchors.find(name);
376  if(it == m_anchors.end())
378 
379  return it->second;
380  }
381 }
singledocparser.h
YAML_PM::CollectionType::BlockMap
@ BlockMap
Definition: collectionstack.h:15
YAML_PM::Token::BLOCK_MAP_START
@ BLOCK_MAP_START
Definition: token.h:47
YAML_PM::Token::FLOW_MAP_START
@ FLOW_MAP_START
Definition: token.h:52
YAML_PM::Scanner::pop
void pop()
Definition: scanner.cpp:29
YAML_PM::Token::KEY
@ KEY
Definition: token.h:57
YAML_PM::ErrorMsg::END_OF_MAP
const char *const END_OF_MAP
Definition: exceptions.h:29
exceptions.h
YAML_PM::Token::PLAIN_SCALAR
@ PLAIN_SCALAR
Definition: token.h:62
YAML_PM::SingleDocParser::SingleDocParser
SingleDocParser(Scanner &scanner, const Directives &directives)
Definition: singledocparser.cpp:15
YAML_PM::SingleDocParser::HandleCompactMapWithNoKey
void HandleCompactMapWithNoKey(EventHandler &eventHandler)
Definition: singledocparser.cpp:311
YAML_PM::SingleDocParser::ParseAnchor
void ParseAnchor(anchor_t &anchor)
Definition: singledocparser.cpp:355
YAML_PM::SingleDocParser::~SingleDocParser
~SingleDocParser()
Definition: singledocparser.cpp:19
YAML_PM::Token::BLOCK_SEQ_END
@ BLOCK_SEQ_END
Definition: token.h:48
YAML_PM
Definition: aliasmanager.h:11
YAML_PM::Token::mark
Mark mark
Definition: token.h:78
YAML_PM::Tag
Definition: tag.h:15
YAML_PM::Token::NON_PLAIN_SCALAR
@ NON_PLAIN_SCALAR
Definition: token.h:63
YAML_PM::Token::FLOW_SEQ_END
@ FLOW_SEQ_END
Definition: token.h:53
YAML_PM::Mark::null
static const Mark null()
Definition: mark.h:16
YAML_PM::ErrorMsg::UNKNOWN_ANCHOR
const char *const UNKNOWN_ANCHOR
Definition: exceptions.h:56
YAML_PM::SingleDocParser::HandleBlockMap
void HandleBlockMap(EventHandler &eventHandler)
Definition: singledocparser.cpp:206
YAML_PM::Directives
Definition: directives.h:19
YAML_PM::EventHandler
Definition: eventhandler.h:15
YAML_PM::Token::BLOCK_SEQ_START
@ BLOCK_SEQ_START
Definition: token.h:46
collectionstack.h
YAML_PM::EventHandler::OnSequenceStart
virtual void OnSequenceStart(const Mark &mark, const std::string &tag, anchor_t anchor)=0
YAML_PM::SingleDocParser::HandleMap
void HandleMap(EventHandler &eventHandler)
Definition: singledocparser.cpp:194
YAML_PM::CollectionType::FlowSeq
@ FlowSeq
Definition: collectionstack.h:15
YAML_PM::SingleDocParser::m_curAnchor
anchor_t m_curAnchor
Definition: singledocparser.h:61
YAML_PM::ErrorMsg::MULTIPLE_TAGS
const char *const MULTIPLE_TAGS
Definition: exceptions.h:33
YAML_PM::SingleDocParser::ParseProperties
void ParseProperties(std::string &tag, anchor_t &anchor)
Definition: singledocparser.cpp:327
YAML_PM::Token::value
std::string value
Definition: token.h:79
eventhandler.h
directives.h
YAML_PM::SingleDocParser::ParseTag
void ParseTag(std::string &tag)
Definition: singledocparser.cpp:344
YAML_PM::SingleDocParser::LookupAnchor
anchor_t LookupAnchor(const Mark &mark, const std::string &name) const
Definition: singledocparser.cpp:373
testing::internal::string
::std::string string
Definition: gtest.h:1979
YAML_PM::Token::BLOCK_ENTRY
@ BLOCK_ENTRY
Definition: token.h:50
YAML_PM::SingleDocParser::HandleSequence
void HandleSequence(EventHandler &eventHandler)
Definition: singledocparser.cpp:121
YAML_PM::Token::TAG
@ TAG
Definition: token.h:61
YAML_PM::ParserException
Definition: exceptions.h:110
YAML_PM::EventHandler::OnDocumentStart
virtual void OnDocumentStart(const Mark &mark)=0
YAML_PM::CollectionStack
Definition: collectionstack.h:18
YAML_PM::ErrorMsg::MULTIPLE_ANCHORS
const char *const MULTIPLE_ANCHORS
Definition: exceptions.h:34
YAML_PM::Token::FLOW_ENTRY
@ FLOW_ENTRY
Definition: token.h:56
YAML_PM::NullAnchor
const anchor_t NullAnchor
Definition: anchor.h:13
YAML_PM::SingleDocParser::m_anchors
Anchors m_anchors
Definition: singledocparser.h:59
YAML_PM::SingleDocParser::HandleBlockSequence
void HandleBlockSequence(EventHandler &eventHandler)
Definition: singledocparser.cpp:131
YAML_PM::SingleDocParser::HandleFlowMap
void HandleFlowMap(EventHandler &eventHandler)
Definition: singledocparser.cpp:245
YAML_PM::CollectionType::CompactMap
@ CompactMap
Definition: collectionstack.h:15
YAML_PM::SingleDocParser::HandleDocument
void HandleDocument(EventHandler &eventHandler)
Definition: singledocparser.cpp:26
YAML_PM::ErrorMsg::END_OF_SEQ_FLOW
const char *const END_OF_SEQ_FLOW
Definition: exceptions.h:32
YAML_PM::EventHandler::OnSequenceEnd
virtual void OnSequenceEnd()=0
YAML_PM::Token::BLOCK_MAP_END
@ BLOCK_MAP_END
Definition: token.h:49
YAML_PM::Token::DOC_START
@ DOC_START
Definition: token.h:44
YAML_PM::SingleDocParser::HandleFlowSequence
void HandleFlowSequence(EventHandler &eventHandler)
Definition: singledocparser.cpp:164
YAML_PM::SingleDocParser::m_scanner
Scanner & m_scanner
Definition: singledocparser.h:54
YAML_PM::SingleDocParser::HandleCompactMap
void HandleCompactMap(EventHandler &eventHandler)
Definition: singledocparser.cpp:290
YAML_PM::EventHandler::OnScalar
virtual void OnScalar(const Mark &mark, const std::string &tag, anchor_t anchor, const std::string &value)=0
YAML_PM::Token::type
TYPE type
Definition: token.h:77
YAML_PM::EventHandler::OnAlias
virtual void OnAlias(const Mark &mark, anchor_t anchor)=0
YAML_PM::SingleDocParser::m_directives
const Directives & m_directives
Definition: singledocparser.h:55
YAML_PM::Token::DOC_END
@ DOC_END
Definition: token.h:45
YAML_PM::CollectionType::BlockSeq
@ BlockSeq
Definition: collectionstack.h:15
YAML_PM::Token::ANCHOR
@ ANCHOR
Definition: token.h:59
YAML_PM::Mark
Definition: mark.h:13
YAML_PM::EventHandler::OnNull
virtual void OnNull(const Mark &mark, anchor_t anchor)=0
YAML_PM::Token::FLOW_MAP_END
@ FLOW_MAP_END
Definition: token.h:54
YAML_PM::Token::VALUE
@ VALUE
Definition: token.h:58
tag.h
YAML_PM::SingleDocParser::m_pCollectionStack
std::auto_ptr< CollectionStack > m_pCollectionStack
Definition: singledocparser.h:56
YAML_PM::Tag::Translate
const std::string Translate(const Directives &directives)
Definition: tag.cpp:32
YAML_PM::Token
Definition: token.h:39
YAML_PM::Token::FLOW_SEQ_START
@ FLOW_SEQ_START
Definition: token.h:51
YAML_PM::SingleDocParser::RegisterAnchor
anchor_t RegisterAnchor(const std::string &name)
Definition: singledocparser.cpp:365
YAML_PM::ErrorMsg::END_OF_SEQ
const char *const END_OF_SEQ
Definition: exceptions.h:31
scanner.h
YAML_PM::Scanner::peek
Token & peek()
Definition: scanner.cpp:38
YAML_PM::anchor_t
std::size_t anchor_t
Definition: anchor.h:12
YAML_PM::CollectionType::FlowMap
@ FlowMap
Definition: collectionstack.h:15
YAML_PM::Scanner
Definition: scanner.h:24
token.h
YAML_PM::SingleDocParser::HandleNode
void HandleNode(EventHandler &eventHandler)
Definition: singledocparser.cpp:47
YAML_PM::Scanner::empty
bool empty()
Definition: scanner.cpp:21
YAML_PM::EventHandler::OnDocumentEnd
virtual void OnDocumentEnd()=0
YAML_PM::EventHandler::OnMapEnd
virtual void OnMapEnd()=0
YAML_PM::ErrorMsg::END_OF_MAP_FLOW
const char *const END_OF_MAP_FLOW
Definition: exceptions.h:30
YAML_PM::EventHandler::OnMapStart
virtual void OnMapStart(const Mark &mark, const std::string &tag, anchor_t anchor)=0
YAML_PM::Token::ALIAS
@ ALIAS
Definition: token.h:60


mp2p_icp
Author(s):
autogenerated on Fri Dec 20 2024 03:46:00