#include "parser.h" #include #include #include #include #include #include #include namespace { double readNumber(std::string in) { std::istringstream iss(in); double d; iss >> d; return d; } std::string readString(std::string in) { std::string result; for (std::size_t i = 1; i < in.length() - 1; i++) { if (in[i] == '\\' && in[i + 1] != 'u') { char c = 0; switch (in[i + 1]) { case '"': case '\\': case '/': c = in[i + 1]; break; case 'b': c = '\b'; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; default: break; } result.push_back(c); i++; } else if (in[i] == '\\'){ char16_t unicode_value; std::wstring_convert, char16_t > utf8converter; unicode_value = 0; for (int j = 0; j < 4; j++, i++) { char hex = in[i + 2]; unicode_value *= 16; if (hex >= '0' && hex <= '9') unicode_value += hex - '0'; else if (hex >= 'A' && hex <= '9') unicode_value += hex - 'A' + 10; else unicode_value += hex - 'a' + 10; } result.append(utf8converter.to_bytes(unicode_value)); i++; } else { if (iscntrl(in[i])) { throw SyntaxError("Control character inside string"); } result.push_back(in[i]); } } return result; } } namespace json { Parser::Parser(JSONLexer lex) : JSONParser(), m_lex(lex) {} Parser::Token Parser::lex() { try { JSONLexer::Token orig = m_lex.nextToken(); JSONParser_Symbol s; switch (orig.type) { case JSONLexer::COLON: s = JSONParser_Symbol::T_COLON; break; case JSONLexer::COMMA: s = JSONParser_Symbol::T_COMMA; break; case JSONLexer::LBRACE: s = JSONParser_Symbol::T_LBRACE; break; case JSONLexer::RBRACE: s = JSONParser_Symbol::T_RBRACE; break; case JSONLexer::LBRACKET: s = JSONParser_Symbol::T_LBRACKET; break; case JSONLexer::RBRACKET: s = JSONParser_Symbol::T_RBRACKET; break; case JSONLexer::STRING: return Token{JSONParser_Symbol::T_STRING, JSON::string(readString(orig.content))}; case JSONLexer::NUMBER: return Token{JSONParser_Symbol::T_NUMBER, JSON::num(readNumber(orig.content))}; case JSONLexer::TTRUE: return Token{JSONParser_Symbol::T_TTRUE, JSON::boolean(true)}; case JSONLexer::TFALSE: return Token{JSONParser_Symbol::T_TFALSE, JSON::boolean(false)}; case JSONLexer::TNULL: return Token{JSONParser_Symbol::T_TNULL, JSON::null()}; default: //impossible break; } return Token{s, JSON()}; } catch (JSONLexer::NoMoreTokens) { return Token{JSONParser_Symbol::T_EOF, JSON()}; } } JSON Parser::reduce_0(std::deque subparts) { return std::move(subparts[0].value); } JSON Parser::reduce_1(std::deque subparts) { return std::move(subparts[0].value); } JSON Parser::reduce_2(std::deque subparts) { return std::move(subparts[0].value); } JSON Parser::reduce_3(std::deque subparts) { return std::move(subparts[0].value); } JSON Parser::reduce_4(std::deque subparts) { return std::move(subparts[0].value); } JSON Parser::reduce_5(std::deque subparts) { return std::move(subparts[0].value); } JSON Parser::reduce_6(std::deque subparts) { return std::move(subparts[0].value); } JSON Parser::reduce_7(std::deque subparts) { return std::move(subparts[1].value); } JSON Parser::reduce_8(std::deque) { return JSON::object(); } JSON Parser::reduce_9(std::deque subparts) { JSON obj = JSON::object(); obj[std::move(subparts[0].value)] = std::move(subparts[2].value); return obj; } JSON Parser::reduce_10(std::deque subparts) { JSON obj = std::move(subparts[4].value); obj[std::move(subparts[0].value)] = std::move(subparts[2].value); return obj; } JSON Parser::reduce_11(std::deque subparts) { return std::move(subparts[1].value); } JSON Parser::reduce_12(std::deque) { return JSON::array(); } JSON Parser::reduce_13(std::deque subparts) { JSON arr = JSON::array(); arr.push_front(std::move(subparts[0].value)); return arr; } JSON Parser::reduce_14(std::deque subparts) { JSON arr = std::move(subparts[2].value); arr.push_front(std::move(subparts[0].value)); return arr; } }