Advertisement
Guest User

Untitled

a guest
May 19th, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.53 KB | None | 0 0
  1. // WIP -- not done yet :)
  2.  
  3. #include <optional>
  4. #include <string_view>
  5. #include <unordered_map>
  6. #include <variant>
  7. #include <vector>
  8.  
  9. namespace json {
  10.  
  11. struct Wrapper;
  12. using Null = std::nullptr_t;
  13. using Bool = bool;
  14. using Number = double;
  15. using String = std::string_view;
  16. using Array = std::vector<Value>;
  17. using Object = std::unordered_map<String, Value>;
  18. using Value = std::variant<Bool, Number, String, Array, Object, Null>;
  19.  
  20. struct Wrapper {
  21. operator Value& () { return v; }
  22. operator const Value& () const { return v; }
  23. };
  24.  
  25. namespace detail {
  26.  
  27. std::optional<Object> parseObject() {
  28. Object object;
  29. if(!accept('{'))
  30. return {};
  31. if (expect('}'))
  32. return object;
  33. while (true) {
  34. if (auto s = parseString(); s) {
  35. if (!expect(':'))
  36. return {};
  37. if (auto v = parseValue(); v)
  38. object.emplace(s, v);
  39. else
  40. return {};
  41. if (expect(','))
  42. continue;
  43. if (expect('}')
  44. return object;
  45. return {};
  46. }
  47. return {};
  48. }
  49. }
  50.  
  51. std::optional<Array> parseArray() {
  52. Array array;
  53. if (!accept('['))
  54. return {};
  55. if (expect(']'))
  56. return array;
  57. while (true) {
  58. if (auto v = parseValue(); v) {
  59. array.emplace_back(v);
  60. if (expect(','))
  61. continue;
  62. if (expect(']'))
  63. return array;
  64. return {};
  65. }
  66. return {};
  67. }
  68. }
  69.  
  70. std::optional<String> parseString() {
  71. if (!accept('"'))
  72. return {};
  73. auto ptr = std::next(ctx.ptr());
  74. unsigned length{0};
  75. while (true) {
  76. ctx.advance(1);
  77. if (ctx.prev() != '\\' && ctx.curr() == '"')
  78. return {ptr, length};
  79. ++length;
  80. }
  81. return {};
  82. }
  83.  
  84. std::optional<Number> parseNumber() {
  85. auto ptr = ctx.ptr();
  86. accept('-');
  87. if (!check(::isdigit))
  88. return {};
  89. while (check(::isdigit))
  90. ;
  91. if (accept('.')) {
  92. if (!check(::isdigit))
  93. return {};
  94. while (check(::isdigit))
  95. ;
  96. }
  97. if (accept('e') || accept('E')) {
  98. accept('+') || accept('-');
  99. if (!check(::isdigit))
  100. return {};
  101. while (check(::isdigit))
  102. ;
  103. }
  104. String asString{ptr, ctx.ptr() - ptr};
  105. return std::stod(asString);
  106. }
  107.  
  108. std::optional<Value> parseValue() {
  109. if (accept("true"))
  110. return bool{true};
  111. if (accept("false"))
  112. return bool{false};
  113. if (accept("null"))
  114. return nullptr;
  115. if (auto n = parseNumber(); n)
  116. return n;
  117. if (auto s = parseString(); s)
  118. return s;
  119. if (auto o = parseObject(); o)
  120. return o;
  121. if (auto a = parseArray(); a)
  122. return a;
  123. return {};
  124. }
  125.  
  126. } // end namespace detail
  127.  
  128. std::optional<Object> parse() {
  129. return detail::parseObject();
  130. }
  131.  
  132. } // end namespace json
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement