[llvm] r194644 - Add simple support for tags in YAML I/O

Sean Silva silvas at purdue.edu
Wed Nov 13 17:13:26 PST 2013


This is great!

-- Sean Silva


On Wed, Nov 13, 2013 at 8:00 PM, Nick Kledzik <kledzik at apple.com> wrote:

> Author: kledzik
> Date: Wed Nov 13 18:59:59 2013
> New Revision: 194644
>
> URL: http://llvm.org/viewvc/llvm-project?rev=194644&view=rev
> Log:
> Add simple support for tags in YAML I/O
>
> Modified:
>     llvm/trunk/docs/YamlIO.rst
>     llvm/trunk/include/llvm/Support/YAMLTraits.h
>     llvm/trunk/lib/Support/YAMLTraits.cpp
>     llvm/trunk/unittests/Support/YAMLIOTest.cpp
>
> Modified: llvm/trunk/docs/YamlIO.rst
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/YamlIO.rst?rev=194644&r1=194643&r2=194644&view=diff
>
> ==============================================================================
> --- llvm/trunk/docs/YamlIO.rst (original)
> +++ llvm/trunk/docs/YamlIO.rst Wed Nov 13 18:59:59 2013
> @@ -633,6 +633,20 @@ This works for both reading and writing.
>      };
>
>
> +Tags
> +----
> +
> +The YAML syntax supports tags as a way to specify the type of a node
> before
> +it is parsed. This allows dynamic types of nodes.  But the YAML I/O model
> uses
> +static typing, so there are limits to how you can use tags with the YAML
> I/O
> +model. Recently, we added support to YAML I/O for checking/setting the
> optional
> +tag on a map. Using this functionality it is even possbile to support
> differnt
> +mappings, as long as they are convertable.
> +
> +To check a tag, inside your mapping() method you can use io.mapTag() to
> specify
> +what the tag should be.  This will also add that tag when writing yaml.
> +
> +
>  Sequence
>  ========
>
>
> Modified: llvm/trunk/include/llvm/Support/YAMLTraits.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/YAMLTraits.h?rev=194644&r1=194643&r2=194644&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/YAMLTraits.h (original)
> +++ llvm/trunk/include/llvm/Support/YAMLTraits.h Wed Nov 13 18:59:59 2013
> @@ -330,6 +330,7 @@ public:
>    virtual void postflightFlowElement(void*) = 0;
>    virtual void endFlowSequence() = 0;
>
> +  virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
>    virtual void beginMapping() = 0;
>    virtual void endMapping() = 0;
>    virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
> @@ -404,8 +405,7 @@ public:
>    void mapOptional(const char* Key, T& Val, const T& Default) {
>      this->processKeyWithDefault(Key, Val, Default, false);
>    }
> -
> -
> +
>  private:
>    template <typename T>
>    void processKeyWithDefault(const char *Key, T &Val, const T&
> DefaultValue,
> @@ -696,6 +696,7 @@ public:
>
>  private:
>    virtual bool outputting();
> +  virtual bool mapTag(StringRef, bool);
>    virtual void beginMapping();
>    virtual void endMapping();
>    virtual bool preflightKey(const char *, bool, bool, bool &, void *&);
> @@ -819,6 +820,7 @@ public:
>    virtual ~Output();
>
>    virtual bool outputting();
> +  virtual bool mapTag(StringRef, bool);
>    virtual void beginMapping();
>    virtual void endMapping();
>    virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);
>
> Modified: llvm/trunk/lib/Support/YAMLTraits.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLTraits.cpp?rev=194644&r1=194643&r2=194644&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Support/YAMLTraits.cpp (original)
> +++ llvm/trunk/lib/Support/YAMLTraits.cpp Wed Nov 13 18:59:59 2013
> @@ -81,6 +81,16 @@ bool Input::setCurrentDocument() {
>  void Input::nextDocument() {
>    ++DocIterator;
>  }
> +
> +bool Input::mapTag(StringRef Tag, bool Default) {
> +  StringRef foundTag = CurrentNode->_node->getVerbatimTag();
> +  if (foundTag.empty()) {
> +    // If no tag found and 'Tag' is the default, say it was found.
> +    return Default;
> +  }
> +  // Return true iff found tag matches supplied tag.
> +  return Tag.equals(foundTag);
> +}
>
>  void Input::beginMapping() {
>    if (EC)
> @@ -381,6 +391,14 @@ void Output::beginMapping() {
>    NeedsNewLine = true;
>  }
>
> +bool Output::mapTag(StringRef Tag, bool Use) {
> +  if (Use) {
> +    this->output(" ");
> +    this->output(Tag);
> +  }
> +  return Use;
> +}
> +
>  void Output::endMapping() {
>    StateStack.pop_back();
>  }
>
> Modified: llvm/trunk/unittests/Support/YAMLIOTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/YAMLIOTest.cpp?rev=194644&r1=194643&r2=194644&view=diff
>
> ==============================================================================
> --- llvm/trunk/unittests/Support/YAMLIOTest.cpp (original)
> +++ llvm/trunk/unittests/Support/YAMLIOTest.cpp Wed Nov 13 18:59:59 2013
> @@ -989,6 +989,91 @@ TEST(YAMLIO, TestSequenceDocListWriteAnd
>    }
>  }
>
>
> +//===----------------------------------------------------------------------===//
> +//  Test document tags
>
> +//===----------------------------------------------------------------------===//
> +
> +struct MyDouble {
> +  MyDouble() : value(0.0) { }
> +  MyDouble(double x) : value(x) { }
> +  double value;
> +};
> +
> +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble);
> +
> +
> +namespace llvm {
> +namespace yaml {
> +  template <>
> +  struct MappingTraits<MyDouble> {
> +    static void mapping(IO &io, MyDouble &d) {
> +      if (io.mapTag("!decimal", true)) {
> +        mappingDecimal(io, d);
> +      } else if (io.mapTag("!fraction")) {
> +        mappingFraction(io, d);
> +      }
> +    }
> +    static void mappingDecimal(IO &io, MyDouble &d) {
> +      io.mapRequired("value", d.value);
> +    }
> +    static void mappingFraction(IO &io, MyDouble &d) {
> +        double num, denom;
> +        io.mapRequired("numerator",      num);
> +        io.mapRequired("denominator",    denom);
> +        // convert fraction to double
> +        d.value = num/denom;
> +    }
> +  };
> + }
> +}
> +
> +
> +//
> +// Test the reading of two different tagged yaml documents.
> +//
> +TEST(YAMLIO, TestTaggedDocuments) {
> +  std::vector<MyDouble> docList;
> +  Input yin("--- !decimal\nvalue:  3.0\n"
> +            "--- !fraction\nnumerator:  9.0\ndenominator:  2\n...\n");
> +  yin >> docList;
> +  EXPECT_FALSE(yin.error());
> +  EXPECT_EQ(docList.size(), 2UL);
> +  EXPECT_EQ(docList[0].value, 3.0);
> +  EXPECT_EQ(docList[1].value, 4.5);
> +}
> +
> +
> +
> +//
> +// Test writing then reading back tagged documents
> +//
> +TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
> +  std::string intermediate;
> +  {
> +    MyDouble a(10.25);
> +    MyDouble b(-3.75);
> +    std::vector<MyDouble> docList;
> +    docList.push_back(a);
> +    docList.push_back(b);
> +
> +    llvm::raw_string_ostream ostr(intermediate);
> +    Output yout(ostr);
> +    yout << docList;
> +  }
> +
> +  {
> +    Input yin(intermediate);
> +    std::vector<MyDouble> docList2;
> +    yin >> docList2;
> +
> +    EXPECT_FALSE(yin.error());
> +    EXPECT_EQ(docList2.size(), 2UL);
> +    EXPECT_EQ(docList2[0].value, 10.25);
> +    EXPECT_EQ(docList2[1].value, -3.75);
> +  }
> +}
> +
> +
>
>
>  //===----------------------------------------------------------------------===//
>  //  Test error handling
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131113/8336d645/attachment.html>


More information about the llvm-commits mailing list