result_t ParseJsonValue(v8::Local<v8::Value> &retVal) { if (c0_ == '"') return ParseJsonString(retVal); if ((c0_ >= '0' && c0_ <= '9') || c0_ == '-') return ParseJsonNumber(retVal); if (c0_ == '{') return ParseJsonObject(retVal); if (c0_ == '[') return ParseJsonArray(retVal); if (c0_ == 'f') { if (AdvanceGetChar() == 'a' && AdvanceGetChar() == 'l' && AdvanceGetChar() == 's' && AdvanceGetChar() == 'e') { AdvanceSkipWhitespace(); retVal = v8::False(isolate->m_isolate); return 0; } return ReportUnexpectedCharacter(); } if (c0_ == 't') { if (AdvanceGetChar() == 'r' && AdvanceGetChar() == 'u' && AdvanceGetChar() == 'e') { AdvanceSkipWhitespace(); retVal = v8::True(isolate->m_isolate); return 0; } return ReportUnexpectedCharacter(); } if (c0_ == 'n') { if (AdvanceGetChar() == 'u' && AdvanceGetChar() == 'l' && AdvanceGetChar() == 'l') { AdvanceSkipWhitespace(); retVal = v8::Null(isolate->m_isolate); return 0; } return ReportUnexpectedCharacter(); } return ReportUnexpectedCharacter(); }
Array* ParseJsonArray(TokenArray& token_array, long long& ptr) { std::vector<JSON::Object> the_array; Token thing = token_array[ptr++]; //NullToken(); do { //thing = token_array[ptr++]; switch (thing.first) { case TokenType::Null: break; case TokenType::LBrace: the_array.emplace_back(ParseJsonTable(token_array, ptr)); break; case TokenType::LBracket: the_array.emplace_back(ParseJsonArray(token_array, ptr)); break; case TokenType::Int: case TokenType::Num: the_array.emplace_back(new JSON::Number(thing.second->ToDouble())); break; case TokenType::Quote: // Assign thing to the correct data, increment the ptr past the second quote then move on thing = token_array[ptr + 1]; ptr += 2; case TokenType::Str: the_array.emplace_back(new JSON::String(thing.second->ToString())); break; } auto comma = token_array[ptr++]; if (comma.first == TokenType::Comma) thing = token_array[ptr++]; else if (comma.first == TokenType::RBracket) thing.first = TokenType::RBracket; else throw std::invalid_argument("Expected , or ] but found neither"); } while (thing.first != TokenType::RBracket); return new JSON::Array(the_array); }
Table* ParseJsonTable(TokenArray& token_array, long long& ptr) { auto identifier = token_array[ptr++]; std::map<std::string, JSON::Object> table_results; do { //std::string the_key = ""; Token the_key; // .first is the token type // the first thing to do is get an identifier // following that we require a colon, and then some data switch (identifier.first) { // in the case of a quote, seperate the string and then drop through case TokenType::Quote: { the_key = token_array[ptr++]; auto the_end_quote = token_array[ptr++]; if (the_key.first != TokenType::Str) //if (the_string.first != TokenType::Str) throw std::invalid_argument("Expected string"); //table_results[the_string.second->ToString()] = ParseJson(token_array, ptr++); }//break; case TokenType::Num: case TokenType::Int: case TokenType::Str: case TokenType::Identifier: { std::string key = identifier.second->ToString(); if(the_key.second != nullptr) key = the_key.second->ToString(); // Verify there is a colon following the name auto& colon = token_array[ptr++]; if (colon.first != TokenType::Colon) throw std::invalid_argument( std::string("Expected colon, got: ")+ colon.second->ToString()); // Now we can accept data auto& data = token_array[ptr++]; switch (data.first) { case TokenType::LBrace: table_results[key] = ParseJsonTable(token_array, ptr); break; case TokenType::LBracket: table_results[key] = ParseJsonArray(token_array, ptr); break; case TokenType::Int: case TokenType::Num: table_results[key] = new JSON::Number(data.second->ToDouble()); break; case TokenType::Str: table_results[key] = new JSON::String(data.second->ToString()); break; case TokenType::Quote: table_results[key] = new JSON::String(token_array[ptr++].second->ToString()); // This should move overtop of the expected quotation ptr++; break; default: puts("Parser ran into some invalid data."); throw std::invalid_argument("Unexpected token found."); } }break; default: throw std::invalid_argument( std::string("Expect string or identifier but found") + identifier.second->ToString()); break; } auto comma = token_array[ptr++]; if (comma.first == TokenType::Comma) identifier = token_array[ptr++]; else if (comma.first == TokenType::RBrace) identifier.first = TokenType::RBrace; else throw std::invalid_argument("Expected , or } but found neither"); } while (identifier.first != TokenType::RBrace); return new JSON::Table(table_results); }