Introduce llvm::sys::path::home_directory.
[oota-llvm.git] / include / llvm / Support / YAMLParser.h
1 //===--- YAMLParser.h - Simple YAML parser --------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This is a YAML 1.2 parser.
11 //
12 //  See http://www.yaml.org/spec/1.2/spec.html for the full standard.
13 //
14 //  This currently does not implement the following:
15 //    * Multi-line literal folding.
16 //    * Tag resolution.
17 //    * UTF-16.
18 //    * BOMs anywhere other than the first Unicode scalar value in the file.
19 //
20 //  The most important class here is Stream. This represents a YAML stream with
21 //  0, 1, or many documents.
22 //
23 //  SourceMgr sm;
24 //  StringRef input = getInput();
25 //  yaml::Stream stream(input, sm);
26 //
27 //  for (yaml::document_iterator di = stream.begin(), de = stream.end();
28 //       di != de; ++di) {
29 //    yaml::Node *n = di->getRoot();
30 //    if (n) {
31 //      // Do something with n...
32 //    } else
33 //      break;
34 //  }
35 //
36 //===----------------------------------------------------------------------===//
37
38 #ifndef LLVM_SUPPORT_YAMLPARSER_H
39 #define LLVM_SUPPORT_YAMLPARSER_H
40
41 #include "llvm/ADT/OwningPtr.h"
42 #include "llvm/ADT/SmallString.h"
43 #include "llvm/ADT/StringRef.h"
44 #include "llvm/Support/Allocator.h"
45 #include "llvm/Support/SMLoc.h"
46 #include <limits>
47 #include <map>
48 #include <utility>
49
50 namespace llvm {
51 class MemoryBuffer;
52 class SourceMgr;
53 class raw_ostream;
54 class Twine;
55
56 namespace yaml {
57
58 class document_iterator;
59 class Document;
60 class Node;
61 class Scanner;
62 struct Token;
63
64 /// @brief Dump all the tokens in this stream to OS.
65 /// @returns true if there was an error, false otherwise.
66 bool dumpTokens(StringRef Input, raw_ostream &);
67
68 /// @brief Scans all tokens in input without outputting anything. This is used
69 ///        for benchmarking the tokenizer.
70 /// @returns true if there was an error, false otherwise.
71 bool scanTokens(StringRef Input);
72
73 /// @brief Escape \a Input for a double quoted scalar.
74 std::string escape(StringRef Input);
75
76 /// @brief This class represents a YAML stream potentially containing multiple
77 ///        documents.
78 class Stream {
79 public:
80   /// @brief This keeps a reference to the string referenced by \p Input.
81   Stream(StringRef Input, SourceMgr &);
82
83   /// @brief This takes ownership of \p InputBuffer.
84   Stream(MemoryBuffer *InputBuffer, SourceMgr &);
85   ~Stream();
86
87   document_iterator begin();
88   document_iterator end();
89   void skip();
90   bool failed();
91   bool validate() {
92     skip();
93     return !failed();
94   }
95
96   void printError(Node *N, const Twine &Msg);
97
98 private:
99   OwningPtr<Scanner> scanner;
100   OwningPtr<Document> CurrentDoc;
101
102   friend class Document;
103 };
104
105 /// @brief Abstract base class for all Nodes.
106 class Node {
107    virtual void anchor();
108 public:
109   enum NodeKind {
110     NK_Null,
111     NK_Scalar,
112     NK_KeyValue,
113     NK_Mapping,
114     NK_Sequence,
115     NK_Alias
116   };
117
118   Node(unsigned int Type, OwningPtr<Document> &, StringRef Anchor,
119        StringRef Tag);
120
121   /// @brief Get the value of the anchor attached to this node. If it does not
122   ///        have one, getAnchor().size() will be 0.
123   StringRef getAnchor() const { return Anchor; }
124
125   /// \brief Get the tag as it was written in the document. This does not
126   ///   perform tag resolution.
127   StringRef getRawTag() const { return Tag; }
128
129   /// \brief Get the verbatium tag for a given Node. This performs tag resoluton
130   ///   and substitution.
131   std::string getVerbatimTag() const;
132
133   SMRange getSourceRange() const { return SourceRange; }
134   void setSourceRange(SMRange SR) { SourceRange = SR; }
135
136   // These functions forward to Document and Scanner.
137   Token &peekNext();
138   Token getNext();
139   Node *parseBlockNode();
140   BumpPtrAllocator &getAllocator();
141   void setError(const Twine &Message, Token &Location) const;
142   bool failed() const;
143
144   virtual void skip() {}
145
146   unsigned int getType() const { return TypeID; }
147
148   void *operator new ( size_t Size
149                      , BumpPtrAllocator &Alloc
150                      , size_t Alignment = 16) throw() {
151     return Alloc.Allocate(Size, Alignment);
152   }
153
154   void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t) throw() {
155     Alloc.Deallocate(Ptr);
156   }
157
158 protected:
159   OwningPtr<Document> &Doc;
160   SMRange SourceRange;
161
162   void operator delete(void *) throw() {}
163
164   virtual ~Node() {}
165
166 private:
167   unsigned int TypeID;
168   StringRef Anchor;
169   /// \brief The tag as typed in the document.
170   StringRef Tag;
171 };
172
173 /// @brief A null value.
174 ///
175 /// Example:
176 ///   !!null null
177 class NullNode : public Node {
178   virtual void anchor();
179 public:
180   NullNode(OwningPtr<Document> &D)
181       : Node(NK_Null, D, StringRef(), StringRef()) {}
182
183   static inline bool classof(const Node *N) {
184     return N->getType() == NK_Null;
185   }
186 };
187
188 /// @brief A scalar node is an opaque datum that can be presented as a
189 ///        series of zero or more Unicode scalar values.
190 ///
191 /// Example:
192 ///   Adena
193 class ScalarNode : public Node {
194   virtual void anchor();
195 public:
196   ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
197              StringRef Val)
198       : Node(NK_Scalar, D, Anchor, Tag), Value(Val) {
199     SMLoc Start = SMLoc::getFromPointer(Val.begin());
200     SMLoc End = SMLoc::getFromPointer(Val.end());
201     SourceRange = SMRange(Start, End);
202   }
203
204   // Return Value without any escaping or folding or other fun YAML stuff. This
205   // is the exact bytes that are contained in the file (after conversion to
206   // utf8).
207   StringRef getRawValue() const { return Value; }
208
209   /// @brief Gets the value of this node as a StringRef.
210   ///
211   /// @param Storage is used to store the content of the returned StringRef iff
212   ///        it requires any modification from how it appeared in the source.
213   ///        This happens with escaped characters and multi-line literals.
214   StringRef getValue(SmallVectorImpl<char> &Storage) const;
215
216   static inline bool classof(const Node *N) {
217     return N->getType() == NK_Scalar;
218   }
219
220 private:
221   StringRef Value;
222
223   StringRef unescapeDoubleQuoted( StringRef UnquotedValue
224                                 , StringRef::size_type Start
225                                 , SmallVectorImpl<char> &Storage) const;
226 };
227
228 /// @brief A key and value pair. While not technically a Node under the YAML
229 ///        representation graph, it is easier to treat them this way.
230 ///
231 /// TODO: Consider making this not a child of Node.
232 ///
233 /// Example:
234 ///   Section: .text
235 class KeyValueNode : public Node {
236   virtual void anchor();
237 public:
238   KeyValueNode(OwningPtr<Document> &D)
239     : Node(NK_KeyValue, D, StringRef(), StringRef())
240     , Key(0)
241     , Value(0)
242   {}
243
244   /// @brief Parse and return the key.
245   ///
246   /// This may be called multiple times.
247   ///
248   /// @returns The key, or nullptr if failed() == true.
249   Node *getKey();
250
251   /// @brief Parse and return the value.
252   ///
253   /// This may be called multiple times.
254   ///
255   /// @returns The value, or nullptr if failed() == true.
256   Node *getValue();
257
258   virtual void skip() LLVM_OVERRIDE {
259     getKey()->skip();
260     getValue()->skip();
261   }
262
263   static inline bool classof(const Node *N) {
264     return N->getType() == NK_KeyValue;
265   }
266
267 private:
268   Node *Key;
269   Node *Value;
270 };
271
272 /// @brief This is an iterator abstraction over YAML collections shared by both
273 ///        sequences and maps.
274 ///
275 /// BaseT must have a ValueT* member named CurrentEntry and a member function
276 /// increment() which must set CurrentEntry to 0 to create an end iterator.
277 template <class BaseT, class ValueT>
278 class basic_collection_iterator
279   : public std::iterator<std::forward_iterator_tag, ValueT> {
280 public:
281   basic_collection_iterator() : Base(0) {}
282   basic_collection_iterator(BaseT *B) : Base(B) {}
283
284   ValueT *operator ->() const {
285     assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
286     return Base->CurrentEntry;
287   }
288
289   ValueT &operator *() const {
290     assert(Base && Base->CurrentEntry &&
291            "Attempted to dereference end iterator!");
292     return *Base->CurrentEntry;
293   }
294
295   operator ValueT*() const {
296     assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
297     return Base->CurrentEntry;
298   }
299
300   bool operator !=(const basic_collection_iterator &Other) const {
301     if(Base != Other.Base)
302       return true;
303     return (Base && Other.Base) && Base->CurrentEntry
304                                    != Other.Base->CurrentEntry;
305   }
306
307   basic_collection_iterator &operator++() {
308     assert(Base && "Attempted to advance iterator past end!");
309     Base->increment();
310     // Create an end iterator.
311     if (Base->CurrentEntry == 0)
312       Base = 0;
313     return *this;
314   }
315
316 private:
317   BaseT *Base;
318 };
319
320 // The following two templates are used for both MappingNode and Sequence Node.
321 template <class CollectionType>
322 typename CollectionType::iterator begin(CollectionType &C) {
323   assert(C.IsAtBeginning && "You may only iterate over a collection once!");
324   C.IsAtBeginning = false;
325   typename CollectionType::iterator ret(&C);
326   ++ret;
327   return ret;
328 }
329
330 template <class CollectionType>
331 void skip(CollectionType &C) {
332   // TODO: support skipping from the middle of a parsed collection ;/
333   assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!");
334   if (C.IsAtBeginning)
335     for (typename CollectionType::iterator i = begin(C), e = C.end();
336                                            i != e; ++i)
337       i->skip();
338 }
339
340 /// @brief Represents a YAML map created from either a block map for a flow map.
341 ///
342 /// This parses the YAML stream as increment() is called.
343 ///
344 /// Example:
345 ///   Name: _main
346 ///   Scope: Global
347 class MappingNode : public Node {
348   virtual void anchor();
349 public:
350   enum MappingType {
351     MT_Block,
352     MT_Flow,
353     MT_Inline ///< An inline mapping node is used for "[key: value]".
354   };
355
356   MappingNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
357               MappingType MT)
358       : Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
359         IsAtEnd(false), CurrentEntry(0) {}
360
361   friend class basic_collection_iterator<MappingNode, KeyValueNode>;
362   typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
363   template <class T> friend typename T::iterator yaml::begin(T &);
364   template <class T> friend void yaml::skip(T &);
365
366   iterator begin() {
367     return yaml::begin(*this);
368   }
369
370   iterator end() { return iterator(); }
371
372   virtual void skip() LLVM_OVERRIDE {
373     yaml::skip(*this);
374   }
375
376   static inline bool classof(const Node *N) {
377     return N->getType() == NK_Mapping;
378   }
379
380 private:
381   MappingType Type;
382   bool IsAtBeginning;
383   bool IsAtEnd;
384   KeyValueNode *CurrentEntry;
385
386   void increment();
387 };
388
389 /// @brief Represents a YAML sequence created from either a block sequence for a
390 ///        flow sequence.
391 ///
392 /// This parses the YAML stream as increment() is called.
393 ///
394 /// Example:
395 ///   - Hello
396 ///   - World
397 class SequenceNode : public Node {
398   virtual void anchor();
399 public:
400   enum SequenceType {
401     ST_Block,
402     ST_Flow,
403     // Use for:
404     //
405     // key:
406     // - val1
407     // - val2
408     //
409     // As a BlockMappingEntry and BlockEnd are not created in this case.
410     ST_Indentless
411   };
412
413   SequenceNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag,
414                SequenceType ST)
415       : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
416         IsAtEnd(false),
417         WasPreviousTokenFlowEntry(true), // Start with an imaginary ','.
418         CurrentEntry(0) {}
419
420   friend class basic_collection_iterator<SequenceNode, Node>;
421   typedef basic_collection_iterator<SequenceNode, Node> iterator;
422   template <class T> friend typename T::iterator yaml::begin(T &);
423   template <class T> friend void yaml::skip(T &);
424
425   void increment();
426
427   iterator begin() {
428     return yaml::begin(*this);
429   }
430
431   iterator end() { return iterator(); }
432
433   virtual void skip() LLVM_OVERRIDE {
434     yaml::skip(*this);
435   }
436
437   static inline bool classof(const Node *N) {
438     return N->getType() == NK_Sequence;
439   }
440
441 private:
442   SequenceType SeqType;
443   bool IsAtBeginning;
444   bool IsAtEnd;
445   bool WasPreviousTokenFlowEntry;
446   Node *CurrentEntry;
447 };
448
449 /// @brief Represents an alias to a Node with an anchor.
450 ///
451 /// Example:
452 ///   *AnchorName
453 class AliasNode : public Node {
454   virtual void anchor();
455 public:
456   AliasNode(OwningPtr<Document> &D, StringRef Val)
457     : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
458
459   StringRef getName() const { return Name; }
460   Node *getTarget();
461
462   static inline bool classof(const Node *N) {
463     return N->getType() == NK_Alias;
464   }
465
466 private:
467   StringRef Name;
468 };
469
470 /// @brief A YAML Stream is a sequence of Documents. A document contains a root
471 ///        node.
472 class Document {
473 public:
474   /// @brief Root for parsing a node. Returns a single node.
475   Node *parseBlockNode();
476
477   Document(Stream &ParentStream);
478
479   /// @brief Finish parsing the current document and return true if there are
480   ///        more. Return false otherwise.
481   bool skip();
482
483   /// @brief Parse and return the root level node.
484   Node *getRoot() {
485     if (Root)
486       return Root;
487     return Root = parseBlockNode();
488   }
489
490   const std::map<StringRef, StringRef> &getTagMap() const {
491     return TagMap;
492   }
493
494 private:
495   friend class Node;
496   friend class document_iterator;
497
498   /// @brief Stream to read tokens from.
499   Stream &stream;
500
501   /// @brief Used to allocate nodes to. All are destroyed without calling their
502   ///        destructor when the document is destroyed.
503   BumpPtrAllocator NodeAllocator;
504
505   /// @brief The root node. Used to support skipping a partially parsed
506   ///        document.
507   Node *Root;
508
509   /// \brief Maps tag prefixes to their expansion.
510   std::map<StringRef, StringRef> TagMap;
511
512   Token &peekNext();
513   Token getNext();
514   void setError(const Twine &Message, Token &Location) const;
515   bool failed() const;
516
517   /// @brief Parse %BLAH directives and return true if any were encountered.
518   bool parseDirectives();
519
520   /// \brief Parse %YAML
521   void parseYAMLDirective();
522
523   /// \brief Parse %TAG
524   void parseTAGDirective();
525
526   /// @brief Consume the next token and error if it is not \a TK.
527   bool expectToken(int TK);
528 };
529
530 /// @brief Iterator abstraction for Documents over a Stream.
531 class document_iterator {
532 public:
533   document_iterator() : Doc(0) {}
534   document_iterator(OwningPtr<Document> &D) : Doc(&D) {}
535
536   bool operator ==(const document_iterator &Other) {
537     if (isAtEnd() || Other.isAtEnd())
538       return isAtEnd() && Other.isAtEnd();
539
540     return Doc == Other.Doc;
541   }
542   bool operator !=(const document_iterator &Other) {
543     return !(*this == Other);
544   }
545
546   document_iterator operator ++() {
547     assert(Doc != 0 && "incrementing iterator past the end.");
548     if (!(*Doc)->skip()) {
549       Doc->reset(0);
550     } else {
551       Stream &S = (*Doc)->stream;
552       Doc->reset(new Document(S));
553     }
554     return *this;
555   }
556
557   Document &operator *() {
558     return *Doc->get();
559   }
560
561   OwningPtr<Document> &operator ->() {
562     return *Doc;
563   }
564
565 private:
566   bool isAtEnd() const {
567     return !Doc || !*Doc;
568   }
569
570   OwningPtr<Document> *Doc;
571 };
572
573 }
574 }
575
576 #endif