File indexing completed on 2026-05-10 08:44:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef LLVM_SUPPORT_YAMLPARSER_H
0037 #define LLVM_SUPPORT_YAMLPARSER_H
0038
0039 #include "llvm/ADT/StringRef.h"
0040 #include "llvm/Support/Allocator.h"
0041 #include "llvm/Support/SMLoc.h"
0042 #include "llvm/Support/SourceMgr.h"
0043 #include <cassert>
0044 #include <cstddef>
0045 #include <iterator>
0046 #include <map>
0047 #include <memory>
0048 #include <optional>
0049 #include <string>
0050 #include <system_error>
0051
0052 namespace llvm {
0053
0054 class MemoryBufferRef;
0055 class raw_ostream;
0056 class Twine;
0057
0058 namespace yaml {
0059
0060 class Document;
0061 class document_iterator;
0062 class Node;
0063 class Scanner;
0064 struct Token;
0065
0066
0067
0068 bool dumpTokens(StringRef Input, raw_ostream &);
0069
0070
0071
0072
0073 bool scanTokens(StringRef Input);
0074
0075
0076
0077
0078
0079 std::string escape(StringRef Input, bool EscapePrintable = true);
0080
0081
0082 std::optional<bool> parseBool(StringRef S);
0083
0084
0085
0086 class Stream {
0087 public:
0088
0089 Stream(StringRef Input, SourceMgr &, bool ShowColors = true,
0090 std::error_code *EC = nullptr);
0091
0092 Stream(MemoryBufferRef InputBuffer, SourceMgr &, bool ShowColors = true,
0093 std::error_code *EC = nullptr);
0094 ~Stream();
0095
0096 document_iterator begin();
0097 document_iterator end();
0098 void skip();
0099 bool failed();
0100
0101 bool validate() {
0102 skip();
0103 return !failed();
0104 }
0105
0106 void printError(Node *N, const Twine &Msg,
0107 SourceMgr::DiagKind Kind = SourceMgr::DK_Error);
0108 void printError(const SMRange &Range, const Twine &Msg,
0109 SourceMgr::DiagKind Kind = SourceMgr::DK_Error);
0110
0111 private:
0112 friend class Document;
0113
0114 std::unique_ptr<Scanner> scanner;
0115 std::unique_ptr<Document> CurrentDoc;
0116 };
0117
0118
0119 class Node {
0120 virtual void anchor();
0121
0122 public:
0123 enum NodeKind {
0124 NK_Null,
0125 NK_Scalar,
0126 NK_BlockScalar,
0127 NK_KeyValue,
0128 NK_Mapping,
0129 NK_Sequence,
0130 NK_Alias
0131 };
0132
0133 Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor,
0134 StringRef Tag);
0135
0136
0137
0138 Node(const Node &) = delete;
0139 void operator=(const Node &) = delete;
0140
0141 void *operator new(size_t Size, BumpPtrAllocator &Alloc,
0142 size_t Alignment = 16) noexcept {
0143 return Alloc.Allocate(Size, Alignment);
0144 }
0145
0146 void operator delete(void *Ptr, BumpPtrAllocator &Alloc,
0147 size_t Size) noexcept {
0148 Alloc.Deallocate(Ptr, Size, 0);
0149 }
0150
0151 void operator delete(void *) noexcept = delete;
0152
0153
0154
0155 StringRef getAnchor() const { return Anchor; }
0156
0157
0158
0159 StringRef getRawTag() const { return Tag; }
0160
0161
0162
0163 std::string getVerbatimTag() const;
0164
0165 SMRange getSourceRange() const { return SourceRange; }
0166 void setSourceRange(SMRange SR) { SourceRange = SR; }
0167
0168
0169 Token &peekNext();
0170 Token getNext();
0171 Node *parseBlockNode();
0172 BumpPtrAllocator &getAllocator();
0173 void setError(const Twine &Message, Token &Location) const;
0174 bool failed() const;
0175
0176 virtual void skip() {}
0177
0178 unsigned int getType() const { return TypeID; }
0179
0180 protected:
0181 std::unique_ptr<Document> &Doc;
0182 SMRange SourceRange;
0183
0184 ~Node() = default;
0185
0186 private:
0187 unsigned int TypeID;
0188 StringRef Anchor;
0189
0190 StringRef Tag;
0191 };
0192
0193
0194
0195
0196
0197 class NullNode final : public Node {
0198 void anchor() override;
0199
0200 public:
0201 NullNode(std::unique_ptr<Document> &D)
0202 : Node(NK_Null, D, StringRef(), StringRef()) {}
0203
0204 static bool classof(const Node *N) { return N->getType() == NK_Null; }
0205 };
0206
0207
0208
0209
0210
0211
0212 class ScalarNode final : public Node {
0213 void anchor() override;
0214
0215 public:
0216 ScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
0217 StringRef Val)
0218 : Node(NK_Scalar, D, Anchor, Tag), Value(Val) {
0219 SMLoc Start = SMLoc::getFromPointer(Val.begin());
0220 SMLoc End = SMLoc::getFromPointer(Val.end());
0221 SourceRange = SMRange(Start, End);
0222 }
0223
0224
0225
0226
0227 StringRef getRawValue() const { return Value; }
0228
0229
0230
0231
0232
0233
0234 StringRef getValue(SmallVectorImpl<char> &Storage) const;
0235
0236 static bool classof(const Node *N) {
0237 return N->getType() == NK_Scalar;
0238 }
0239
0240 private:
0241 StringRef Value;
0242
0243 StringRef getDoubleQuotedValue(StringRef UnquotedValue,
0244 SmallVectorImpl<char> &Storage) const;
0245
0246 static StringRef getSingleQuotedValue(StringRef RawValue,
0247 SmallVectorImpl<char> &Storage);
0248
0249 static StringRef getPlainValue(StringRef RawValue,
0250 SmallVectorImpl<char> &Storage);
0251 };
0252
0253
0254
0255
0256
0257
0258
0259
0260 class BlockScalarNode final : public Node {
0261 void anchor() override;
0262
0263 public:
0264 BlockScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
0265 StringRef Value, StringRef RawVal)
0266 : Node(NK_BlockScalar, D, Anchor, Tag), Value(Value) {
0267 SMLoc Start = SMLoc::getFromPointer(RawVal.begin());
0268 SMLoc End = SMLoc::getFromPointer(RawVal.end());
0269 SourceRange = SMRange(Start, End);
0270 }
0271
0272
0273 StringRef getValue() const { return Value; }
0274
0275 static bool classof(const Node *N) {
0276 return N->getType() == NK_BlockScalar;
0277 }
0278
0279 private:
0280 StringRef Value;
0281 };
0282
0283
0284
0285
0286
0287
0288
0289
0290 class KeyValueNode final : public Node {
0291 void anchor() override;
0292
0293 public:
0294 KeyValueNode(std::unique_ptr<Document> &D)
0295 : Node(NK_KeyValue, D, StringRef(), StringRef()) {}
0296
0297
0298
0299
0300
0301
0302 Node *getKey();
0303
0304
0305
0306
0307
0308
0309 Node *getValue();
0310
0311 void skip() override {
0312 if (Node *Key = getKey()) {
0313 Key->skip();
0314 if (Node *Val = getValue())
0315 Val->skip();
0316 }
0317 }
0318
0319 static bool classof(const Node *N) {
0320 return N->getType() == NK_KeyValue;
0321 }
0322
0323 private:
0324 Node *Key = nullptr;
0325 Node *Value = nullptr;
0326 };
0327
0328
0329
0330
0331
0332
0333 template <class BaseT, class ValueT> class basic_collection_iterator {
0334 public:
0335 using iterator_category = std::input_iterator_tag;
0336 using value_type = ValueT;
0337 using difference_type = std::ptrdiff_t;
0338 using pointer = value_type *;
0339 using reference = value_type &;
0340
0341 basic_collection_iterator() = default;
0342 basic_collection_iterator(BaseT *B) : Base(B) {}
0343
0344 ValueT *operator->() const {
0345 assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
0346 return Base->CurrentEntry;
0347 }
0348
0349 ValueT &operator*() const {
0350 assert(Base && Base->CurrentEntry &&
0351 "Attempted to dereference end iterator!");
0352 return *Base->CurrentEntry;
0353 }
0354
0355 operator ValueT *() const {
0356 assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
0357 return Base->CurrentEntry;
0358 }
0359
0360
0361
0362
0363
0364
0365
0366
0367 bool operator==(const basic_collection_iterator &Other) const {
0368 if (Base && (Base == Other.Base)) {
0369 assert((Base->CurrentEntry == Other.Base->CurrentEntry)
0370 && "Equal Bases expected to point to equal Entries");
0371 }
0372
0373 return Base == Other.Base;
0374 }
0375
0376 bool operator!=(const basic_collection_iterator &Other) const {
0377 return !(Base == Other.Base);
0378 }
0379
0380 basic_collection_iterator &operator++() {
0381 assert(Base && "Attempted to advance iterator past end!");
0382 Base->increment();
0383
0384 if (!Base->CurrentEntry)
0385 Base = nullptr;
0386 return *this;
0387 }
0388
0389 private:
0390 BaseT *Base = nullptr;
0391 };
0392
0393
0394 template <class CollectionType>
0395 typename CollectionType::iterator begin(CollectionType &C) {
0396 assert(C.IsAtBeginning && "You may only iterate over a collection once!");
0397 C.IsAtBeginning = false;
0398 typename CollectionType::iterator ret(&C);
0399 ++ret;
0400 return ret;
0401 }
0402
0403 template <class CollectionType> void skip(CollectionType &C) {
0404
0405 assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!");
0406 if (C.IsAtBeginning)
0407 for (typename CollectionType::iterator i = begin(C), e = C.end(); i != e;
0408 ++i)
0409 i->skip();
0410 }
0411
0412
0413
0414
0415
0416
0417
0418
0419 class MappingNode final : public Node {
0420 void anchor() override;
0421
0422 public:
0423 enum MappingType {
0424 MT_Block,
0425 MT_Flow,
0426 MT_Inline
0427 };
0428
0429 MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
0430 MappingType MT)
0431 : Node(NK_Mapping, D, Anchor, Tag), Type(MT) {}
0432
0433 friend class basic_collection_iterator<MappingNode, KeyValueNode>;
0434
0435 using iterator = basic_collection_iterator<MappingNode, KeyValueNode>;
0436
0437 template <class T> friend typename T::iterator yaml::begin(T &);
0438 template <class T> friend void yaml::skip(T &);
0439
0440 iterator begin() { return yaml::begin(*this); }
0441
0442 iterator end() { return iterator(); }
0443
0444 void skip() override { yaml::skip(*this); }
0445
0446 static bool classof(const Node *N) {
0447 return N->getType() == NK_Mapping;
0448 }
0449
0450 private:
0451 MappingType Type;
0452 bool IsAtBeginning = true;
0453 bool IsAtEnd = false;
0454 KeyValueNode *CurrentEntry = nullptr;
0455
0456 void increment();
0457 };
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467 class SequenceNode final : public Node {
0468 void anchor() override;
0469
0470 public:
0471 enum SequenceType {
0472 ST_Block,
0473 ST_Flow,
0474
0475
0476
0477
0478
0479
0480
0481 ST_Indentless
0482 };
0483
0484 SequenceNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
0485 SequenceType ST)
0486 : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST) {}
0487
0488 friend class basic_collection_iterator<SequenceNode, Node>;
0489
0490 using iterator = basic_collection_iterator<SequenceNode, Node>;
0491
0492 template <class T> friend typename T::iterator yaml::begin(T &);
0493 template <class T> friend void yaml::skip(T &);
0494
0495 void increment();
0496
0497 iterator begin() { return yaml::begin(*this); }
0498
0499 iterator end() { return iterator(); }
0500
0501 void skip() override { yaml::skip(*this); }
0502
0503 static bool classof(const Node *N) {
0504 return N->getType() == NK_Sequence;
0505 }
0506
0507 private:
0508 SequenceType SeqType;
0509 bool IsAtBeginning = true;
0510 bool IsAtEnd = false;
0511 bool WasPreviousTokenFlowEntry = true;
0512 Node *CurrentEntry = nullptr;
0513 };
0514
0515
0516
0517
0518
0519 class AliasNode final : public Node {
0520 void anchor() override;
0521
0522 public:
0523 AliasNode(std::unique_ptr<Document> &D, StringRef Val)
0524 : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
0525
0526 StringRef getName() const { return Name; }
0527
0528 static bool classof(const Node *N) { return N->getType() == NK_Alias; }
0529
0530 private:
0531 StringRef Name;
0532 };
0533
0534
0535
0536 class Document {
0537 public:
0538 Document(Stream &ParentStream);
0539
0540
0541 Node *parseBlockNode();
0542
0543
0544
0545 bool skip();
0546
0547
0548 Node *getRoot() {
0549 if (Root)
0550 return Root;
0551 return Root = parseBlockNode();
0552 }
0553
0554 const std::map<StringRef, StringRef> &getTagMap() const { return TagMap; }
0555
0556 private:
0557 friend class Node;
0558 friend class document_iterator;
0559
0560
0561 Stream &stream;
0562
0563
0564
0565 BumpPtrAllocator NodeAllocator;
0566
0567
0568
0569 Node *Root;
0570
0571
0572 std::map<StringRef, StringRef> TagMap;
0573
0574 Token &peekNext();
0575 Token getNext();
0576 void setError(const Twine &Message, Token &Location) const;
0577 bool failed() const;
0578
0579
0580 bool parseDirectives();
0581
0582
0583 void parseYAMLDirective();
0584
0585
0586 void parseTAGDirective();
0587
0588
0589 bool expectToken(int TK);
0590 };
0591
0592
0593 class document_iterator {
0594 public:
0595 document_iterator() = default;
0596 document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {}
0597
0598 bool operator==(const document_iterator &Other) const {
0599 if (isAtEnd() || Other.isAtEnd())
0600 return isAtEnd() && Other.isAtEnd();
0601
0602 return Doc == Other.Doc;
0603 }
0604 bool operator!=(const document_iterator &Other) const {
0605 return !(*this == Other);
0606 }
0607
0608 document_iterator operator++() {
0609 assert(Doc && "incrementing iterator past the end.");
0610 if (!(*Doc)->skip()) {
0611 Doc->reset(nullptr);
0612 } else {
0613 Stream &S = (*Doc)->stream;
0614 Doc->reset(new Document(S));
0615 }
0616 return *this;
0617 }
0618
0619 Document &operator*() { return **Doc; }
0620
0621 std::unique_ptr<Document> &operator->() { return *Doc; }
0622
0623 private:
0624 bool isAtEnd() const { return !Doc || !*Doc; }
0625
0626 std::unique_ptr<Document> *Doc = nullptr;
0627 };
0628
0629 }
0630
0631 }
0632
0633 #endif