diff options
author | Manuel Klimek <klimek@google.com> | 2012-01-17 09:34:07 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2012-01-17 09:34:07 +0000 |
commit | 44b920fac47e8047acd0ffdbd3b169b4fdfed06b (patch) | |
tree | 4a7a924dadbfb1fbb028aaf1d94b14ff84a62992 /lib/Support | |
parent | a16d441430440d9255fe16441cea7a38e8f3c461 (diff) | |
download | external_llvm-44b920fac47e8047acd0ffdbd3b169b4fdfed06b.zip external_llvm-44b920fac47e8047acd0ffdbd3b169b4fdfed06b.tar.gz external_llvm-44b920fac47e8047acd0ffdbd3b169b4fdfed06b.tar.bz2 |
Removes template magic to build up containers.
Instead, we now put the attributes of the container into members.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148302 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/JSONParser.cpp | 89 |
1 files changed, 82 insertions, 7 deletions
diff --git a/lib/Support/JSONParser.cpp b/lib/Support/JSONParser.cpp index 205ac05..0832ec3 100644 --- a/lib/Support/JSONParser.cpp +++ b/lib/Support/JSONParser.cpp @@ -55,9 +55,11 @@ bool JSONParser::validate() { bool JSONParser::skip(const JSONAtom &Atom) { switch(Atom.getKind()) { - case JSONAtom::JK_Array: return skipContainer(*cast<JSONArray>(&Atom)); - case JSONAtom::JK_Object: return skipContainer(*cast<JSONObject>(&Atom)); - case JSONAtom::JK_String: return true; + case JSONAtom::JK_Array: + case JSONAtom::JK_Object: + return skipContainer(*cast<JSONContainer>(&Atom)); + case JSONAtom::JK_String: + return true; case JSONAtom::JK_KeyValuePair: return skip(*cast<JSONKeyValuePair>(&Atom)->Value); } @@ -218,10 +220,83 @@ JSONKeyValuePair *JSONParser::parseKeyValuePair() { JSONKeyValuePair(Key, Value); } -template <> JSONValue *JSONParser::parseElement() { - return parseValue(); +/// \brief Parses the first element of a JSON array or object, or closes the +/// array. +/// +/// The method assumes that the current position is before the first character +/// of the element, with possible white space in between. When successful, it +/// returns the new position after parsing the element. Otherwise, if there is +/// no next value, it returns a default constructed StringRef::iterator. +StringRef::iterator JSONParser::parseFirstElement(JSONAtom::Kind ContainerKind, + char StartChar, char EndChar, + const JSONAtom *&Element) { + assert(*Position == StartChar); + Element = 0; + nextNonWhitespace(); + if (errorIfAtEndOfFile("value or end of container at start of container")) + return StringRef::iterator(); + + if (*Position == EndChar) + return StringRef::iterator(); + + Element = parseElement(ContainerKind); + if (Element == 0) + return StringRef::iterator(); + + return Position; +} + +/// \brief Parses the next element of a JSON array or object, or closes the +/// array. +/// +/// The method assumes that the current position is before the ',' which +/// separates the next element from the current element. When successful, it +/// returns the new position after parsing the element. Otherwise, if there is +/// no next value, it returns a default constructed StringRef::iterator. +StringRef::iterator JSONParser::parseNextElement(JSONAtom::Kind ContainerKind, + char EndChar, + const JSONAtom *&Element) { + Element = 0; + nextNonWhitespace(); + if (errorIfAtEndOfFile("',' or end of container for next element")) + return 0; + + if (*Position == ',') { + nextNonWhitespace(); + if (errorIfAtEndOfFile("element in container")) + return StringRef::iterator(); + + Element = parseElement(ContainerKind); + if (Element == 0) + return StringRef::iterator(); + + return Position; + } else if (*Position == EndChar) { + return StringRef::iterator(); + } else { + setExpectedError("',' or end of container for next element", *Position); + return StringRef::iterator(); + } } -template <> JSONKeyValuePair *JSONParser::parseElement() { - return parseKeyValuePair(); +const JSONAtom *JSONParser::parseElement(JSONAtom::Kind ContainerKind) { + switch (ContainerKind) { + case JSONAtom::JK_Array: + return parseValue(); + case JSONAtom::JK_Object: + return parseKeyValuePair(); + default: + llvm_unreachable("Impossible code path"); + } +} + +bool JSONParser::skipContainer(const JSONContainer &Container) { + for (JSONContainer::AtomIterator I = Container.atom_current(), + E = Container.atom_end(); + I != E; ++I) { + assert(*I != 0); + if (!skip(**I)) + return false; + } + return !failed(); } |