From 9ce6937701cd28fb2aafdd3ec950fb0e70bae8cd Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Tue, 20 Dec 2011 10:42:52 +0000 Subject: [PATCH] Pulls the implementation of skip() into JSONParser. This is the first step towards migrating more of the parser implementation into the parser class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146971 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/JSONParser.h | 36 ++++++++++--------------------- lib/Support/JSONParser.cpp | 35 ++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/include/llvm/Support/JSONParser.h b/include/llvm/Support/JSONParser.h index 816f9a94839..0150646bc37 100644 --- a/include/llvm/Support/JSONParser.h +++ b/include/llvm/Support/JSONParser.h @@ -48,10 +48,6 @@ protected: JSONAtom(Kind MyKind) : MyKind(MyKind) {} private: - /// \brief Parses to the end of the object and returns whether parsing - /// was successful. - bool skip() const; - Kind MyKind; friend class JSONParser; @@ -76,8 +72,8 @@ public: /// \brief Returns the outermost JSON value (either an array or an object). /// /// Can return NULL if the input does not start with an array or an object. - /// The object is not parsed yet - the caller must either iterate over the - /// returned object or call 'skip' to trigger parsing. + /// The object is not parsed yet - the caller must iterate over the + /// returned object to trigger parsing. /// /// A JSONValue can be either a JSONString, JSONObject or JSONArray. JSONValue *parseRoot(); @@ -130,6 +126,13 @@ private: bool errorIfNotAt(char C, StringRef Message); /// } + /// \brief Skips all elements in the given container. + template + bool skipContainer(const ContainerT &Container); + + /// \brief Skips to the next position behind the given JSON atom. + bool skip(const JSONAtom &Atom); + /// All nodes are allocated by the parser and will be deallocated when the /// parser is destroyed. BumpPtrAllocator ValueAllocator; @@ -191,9 +194,6 @@ public: private: JSONString(StringRef RawText) : JSONValue(JK_String), RawText(RawText) {} - /// \brief Skips to the next position in the parse stream. - bool skip() const { return true; }; - StringRef RawText; friend class JSONAtom; @@ -223,9 +223,6 @@ private: JSONKeyValuePair(const JSONString *Key, const JSONValue *Value) : JSONAtom(JK_KeyValuePair), Key(Key), Value(Value) {} - /// \brief Skips to the next position in the parse stream. - bool skip() const { return Value->skip(); }; - friend class JSONAtom; friend class JSONParser; template friend class JSONContainer; @@ -243,8 +240,7 @@ public: /// \brief Implementation of JSON containers (arrays and objects). /// /// JSONContainers drive the lazy parsing of JSON arrays and objects via -/// forward iterators. Call 'skip' to validate parsing of all elements of the -/// container and to position the parse stream behind the container. +/// forward iterators. template class JSONContainer : public JSONValue { @@ -320,23 +316,13 @@ private: return const_iterator(this); } - /// \brief Skips to the next position in the parse stream. - bool skip() const { - for (const_iterator I = current(), E = end(); I != E; ++I) { - assert(*I != 0); - if (!(*I)->skip()) - return false; - } - return !Parser->failed(); - } - /// \brief Parse the next element in the container into the Current element. /// /// This routine is called as an iterator into this container walks through /// its elements. It mutates the container's internal current node to point to /// the next atom of the container. void parseNextElement() const { - Current->skip(); + Parser->skip(*Current); Position = Parser->parseNextElement(Current); } diff --git a/lib/Support/JSONParser.cpp b/lib/Support/JSONParser.cpp index 36da12d3764..02187409cbf 100644 --- a/lib/Support/JSONParser.cpp +++ b/lib/Support/JSONParser.cpp @@ -40,7 +40,30 @@ JSONValue *JSONParser::parseRoot() { } bool JSONParser::validate() { - return parseRoot()->skip(); + return skip(*parseRoot()); +} + +template +bool JSONParser::skipContainer(const ContainerT &Container) { + for (typename ContainerT::const_iterator I = Container.current(), + E = Container.end(); + I != E; ++I) { + assert(*I != 0); + if (!skip(**I)) + return false; + } + return !failed(); +} + +bool JSONParser::skip(const JSONAtom &Atom) { + switch(Atom.getKind()) { + case JSONAtom::JK_Array: return skipContainer(*cast(&Atom)); + case JSONAtom::JK_Object: return skipContainer(*cast(&Atom)); + case JSONAtom::JK_String: return true; + case JSONAtom::JK_KeyValuePair: + return skip(*cast(&Atom)->Value); + } + llvm_unreachable("Impossible enum value."); } // Sets the current error to: @@ -159,16 +182,6 @@ std::string JSONParser::getErrorMessage() const { return ErrorMessage; } -bool JSONAtom::skip() const { - switch (MyKind) { - case JK_Array: return cast(this)->skip(); - case JK_Object: return cast(this)->skip(); - case JK_String: return cast(this)->skip(); - case JK_KeyValuePair: return cast(this)->skip(); - } - llvm_unreachable("Impossible enum value."); -} - // Parses a JSONValue, assuming that the current position is at the first // character of the value. JSONValue *JSONParser::parseValue() { -- 2.34.1