11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/torque/ls/json-parser.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include <cctype> 81cb0ef41Sopenharmony_ci#include "src/torque/earley-parser.h" 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_cinamespace v8 { 111cb0ef41Sopenharmony_cinamespace internal { 121cb0ef41Sopenharmony_cinamespace torque { 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_citemplate <> 151cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<ls::JsonValue>::id = 161cb0ef41Sopenharmony_ci ParseResultTypeId::kJsonValue; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_citemplate <> 191cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE const ParseResultTypeId 201cb0ef41Sopenharmony_ci ParseResultHolder<std::pair<std::string, ls::JsonValue>>::id = 211cb0ef41Sopenharmony_ci ParseResultTypeId::kJsonMember; 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_citemplate <> 241cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE const ParseResultTypeId 251cb0ef41Sopenharmony_ci ParseResultHolder<std::vector<ls::JsonValue>>::id = 261cb0ef41Sopenharmony_ci ParseResultTypeId::kStdVectorOfJsonValue; 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_citemplate <> 291cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE const ParseResultTypeId 301cb0ef41Sopenharmony_ci ParseResultHolder<std::vector<std::pair<std::string, ls::JsonValue>>>::id = 311cb0ef41Sopenharmony_ci ParseResultTypeId::kStdVectorOfJsonMember; 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_cinamespace ls { 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciusing JsonMember = std::pair<std::string, JsonValue>; 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_citemplate <bool value> 381cb0ef41Sopenharmony_cibase::Optional<ParseResult> MakeBoolLiteral( 391cb0ef41Sopenharmony_ci ParseResultIterator* child_results) { 401cb0ef41Sopenharmony_ci return ParseResult{JsonValue::From(value)}; 411cb0ef41Sopenharmony_ci} 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_cibase::Optional<ParseResult> MakeNullLiteral( 441cb0ef41Sopenharmony_ci ParseResultIterator* child_results) { 451cb0ef41Sopenharmony_ci JsonValue result; 461cb0ef41Sopenharmony_ci result.tag = JsonValue::IS_NULL; 471cb0ef41Sopenharmony_ci return ParseResult{std::move(result)}; 481cb0ef41Sopenharmony_ci} 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_cibase::Optional<ParseResult> MakeNumberLiteral( 511cb0ef41Sopenharmony_ci ParseResultIterator* child_results) { 521cb0ef41Sopenharmony_ci auto number = child_results->NextAs<std::string>(); 531cb0ef41Sopenharmony_ci double d = std::stod(number.c_str()); 541cb0ef41Sopenharmony_ci return ParseResult{JsonValue::From(d)}; 551cb0ef41Sopenharmony_ci} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_cibase::Optional<ParseResult> MakeStringLiteral( 581cb0ef41Sopenharmony_ci ParseResultIterator* child_results) { 591cb0ef41Sopenharmony_ci std::string literal = child_results->NextAs<std::string>(); 601cb0ef41Sopenharmony_ci return ParseResult{JsonValue::From(StringLiteralUnquote(literal))}; 611cb0ef41Sopenharmony_ci} 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_cibase::Optional<ParseResult> MakeArray(ParseResultIterator* child_results) { 641cb0ef41Sopenharmony_ci JsonArray array = child_results->NextAs<JsonArray>(); 651cb0ef41Sopenharmony_ci return ParseResult{JsonValue::From(std::move(array))}; 661cb0ef41Sopenharmony_ci} 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_cibase::Optional<ParseResult> MakeMember(ParseResultIterator* child_results) { 691cb0ef41Sopenharmony_ci JsonMember result; 701cb0ef41Sopenharmony_ci std::string key = child_results->NextAs<std::string>(); 711cb0ef41Sopenharmony_ci result.first = StringLiteralUnquote(key); 721cb0ef41Sopenharmony_ci result.second = child_results->NextAs<JsonValue>(); 731cb0ef41Sopenharmony_ci return ParseResult{std::move(result)}; 741cb0ef41Sopenharmony_ci} 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_cibase::Optional<ParseResult> MakeObject(ParseResultIterator* child_results) { 771cb0ef41Sopenharmony_ci using MemberList = std::vector<JsonMember>; 781cb0ef41Sopenharmony_ci MemberList members = child_results->NextAs<MemberList>(); 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci JsonObject object; 811cb0ef41Sopenharmony_ci for (auto& member : members) object.insert(std::move(member)); 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci return ParseResult{JsonValue::From(std::move(object))}; 841cb0ef41Sopenharmony_ci} 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ciclass JsonGrammar : public Grammar { 871cb0ef41Sopenharmony_ci static bool MatchWhitespace(InputPosition* pos) { 881cb0ef41Sopenharmony_ci while (MatchChar(std::isspace, pos)) { 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci return true; 911cb0ef41Sopenharmony_ci } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci static bool MatchStringLiteral(InputPosition* pos) { 941cb0ef41Sopenharmony_ci InputPosition current = *pos; 951cb0ef41Sopenharmony_ci if (MatchString("\"", ¤t)) { 961cb0ef41Sopenharmony_ci while ( 971cb0ef41Sopenharmony_ci (MatchString("\\", ¤t) && MatchAnyChar(¤t)) || 981cb0ef41Sopenharmony_ci MatchChar([](char c) { return c != '"' && c != '\n'; }, ¤t)) { 991cb0ef41Sopenharmony_ci } 1001cb0ef41Sopenharmony_ci if (MatchString("\"", ¤t)) { 1011cb0ef41Sopenharmony_ci *pos = current; 1021cb0ef41Sopenharmony_ci return true; 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci current = *pos; 1061cb0ef41Sopenharmony_ci if (MatchString("'", ¤t)) { 1071cb0ef41Sopenharmony_ci while ( 1081cb0ef41Sopenharmony_ci (MatchString("\\", ¤t) && MatchAnyChar(¤t)) || 1091cb0ef41Sopenharmony_ci MatchChar([](char c) { return c != '\'' && c != '\n'; }, ¤t)) { 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci if (MatchString("'", ¤t)) { 1121cb0ef41Sopenharmony_ci *pos = current; 1131cb0ef41Sopenharmony_ci return true; 1141cb0ef41Sopenharmony_ci } 1151cb0ef41Sopenharmony_ci } 1161cb0ef41Sopenharmony_ci return false; 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci static bool MatchHexLiteral(InputPosition* pos) { 1201cb0ef41Sopenharmony_ci InputPosition current = *pos; 1211cb0ef41Sopenharmony_ci MatchString("-", ¤t); 1221cb0ef41Sopenharmony_ci if (MatchString("0x", ¤t) && MatchChar(std::isxdigit, ¤t)) { 1231cb0ef41Sopenharmony_ci while (MatchChar(std::isxdigit, ¤t)) { 1241cb0ef41Sopenharmony_ci } 1251cb0ef41Sopenharmony_ci *pos = current; 1261cb0ef41Sopenharmony_ci return true; 1271cb0ef41Sopenharmony_ci } 1281cb0ef41Sopenharmony_ci return false; 1291cb0ef41Sopenharmony_ci } 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ci static bool MatchDecimalLiteral(InputPosition* pos) { 1321cb0ef41Sopenharmony_ci InputPosition current = *pos; 1331cb0ef41Sopenharmony_ci bool found_digit = false; 1341cb0ef41Sopenharmony_ci MatchString("-", ¤t); 1351cb0ef41Sopenharmony_ci while (MatchChar(std::isdigit, ¤t)) found_digit = true; 1361cb0ef41Sopenharmony_ci MatchString(".", ¤t); 1371cb0ef41Sopenharmony_ci while (MatchChar(std::isdigit, ¤t)) found_digit = true; 1381cb0ef41Sopenharmony_ci if (!found_digit) return false; 1391cb0ef41Sopenharmony_ci *pos = current; 1401cb0ef41Sopenharmony_ci if ((MatchString("e", ¤t) || MatchString("E", ¤t)) && 1411cb0ef41Sopenharmony_ci (MatchString("+", ¤t) || MatchString("-", ¤t) || true) && 1421cb0ef41Sopenharmony_ci MatchChar(std::isdigit, ¤t)) { 1431cb0ef41Sopenharmony_ci while (MatchChar(std::isdigit, ¤t)) { 1441cb0ef41Sopenharmony_ci } 1451cb0ef41Sopenharmony_ci *pos = current; 1461cb0ef41Sopenharmony_ci return true; 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci return true; 1491cb0ef41Sopenharmony_ci } 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci public: 1521cb0ef41Sopenharmony_ci JsonGrammar() : Grammar(&file) { SetWhitespace(MatchWhitespace); } 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci Symbol trueLiteral = {Rule({Token("true")})}; 1551cb0ef41Sopenharmony_ci Symbol falseLiteral = {Rule({Token("false")})}; 1561cb0ef41Sopenharmony_ci Symbol nullLiteral = {Rule({Token("null")})}; 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci Symbol decimalLiteral = { 1591cb0ef41Sopenharmony_ci Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput), 1601cb0ef41Sopenharmony_ci Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)}; 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci Symbol stringLiteral = { 1631cb0ef41Sopenharmony_ci Rule({Pattern(MatchStringLiteral)}, YieldMatchedInput)}; 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci Symbol* elementList = List<JsonValue>(&value, Token(",")); 1661cb0ef41Sopenharmony_ci Symbol array = {Rule({Token("["), elementList, Token("]")})}; 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci Symbol member = {Rule({&stringLiteral, Token(":"), &value}, MakeMember)}; 1691cb0ef41Sopenharmony_ci Symbol* memberList = List<JsonMember>(&member, Token(",")); 1701cb0ef41Sopenharmony_ci Symbol object = {Rule({Token("{"), memberList, Token("}")})}; 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci Symbol value = {Rule({&trueLiteral}, MakeBoolLiteral<true>), 1731cb0ef41Sopenharmony_ci Rule({&falseLiteral}, MakeBoolLiteral<false>), 1741cb0ef41Sopenharmony_ci Rule({&nullLiteral}, MakeNullLiteral), 1751cb0ef41Sopenharmony_ci Rule({&decimalLiteral}, MakeNumberLiteral), 1761cb0ef41Sopenharmony_ci Rule({&stringLiteral}, MakeStringLiteral), 1771cb0ef41Sopenharmony_ci Rule({&object}, MakeObject), 1781cb0ef41Sopenharmony_ci Rule({&array}, MakeArray)}; 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci Symbol file = {Rule({&value})}; 1811cb0ef41Sopenharmony_ci}; 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ciJsonParserResult ParseJson(const std::string& input) { 1841cb0ef41Sopenharmony_ci // Torque needs a CurrentSourceFile scope during parsing. 1851cb0ef41Sopenharmony_ci // As JSON lives in memory only, a unknown file scope is created. 1861cb0ef41Sopenharmony_ci SourceFileMap::Scope source_map_scope(""); 1871cb0ef41Sopenharmony_ci TorqueMessages::Scope messages_scope; 1881cb0ef41Sopenharmony_ci CurrentSourceFile::Scope unkown_file(SourceFileMap::AddSource("<json>")); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci JsonParserResult result; 1911cb0ef41Sopenharmony_ci try { 1921cb0ef41Sopenharmony_ci result.value = (*JsonGrammar().Parse(input)).Cast<JsonValue>(); 1931cb0ef41Sopenharmony_ci } catch (TorqueAbortCompilation&) { 1941cb0ef41Sopenharmony_ci CHECK(!TorqueMessages::Get().empty()); 1951cb0ef41Sopenharmony_ci result.error = TorqueMessages::Get().front(); 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci return result; 1981cb0ef41Sopenharmony_ci} 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci} // namespace ls 2011cb0ef41Sopenharmony_ci} // namespace torque 2021cb0ef41Sopenharmony_ci} // namespace internal 2031cb0ef41Sopenharmony_ci} // namespace v8 204