#include "Token.hpp" #include class JSONParser { std::fstream file; JSONNode *root; JSONNode *current; Tokenizer tokenizer; public: JSONParser(const string filename) : tokenizer(filename) {} void parse() { string key = ""; while (tokenizer.hasMoreTokens()) { Token *token; JSONNode *parsed; try { token = tokenizer.getToken(); switch (token->type) { case CURLY_OPEN: { parsed = parseObject(); if (!root) { root = parsed; } break; } case ARRAY_OPEN: { parsed = parseList(); if (!root) { root = parsed; } break; } case STRING: { tokenizer.rollBackToken(); parsed = parseString(); break; } case NUMBER: { tokenizer.rollBackToken(); parsed = parseNumber(); break; } case BOOLEAN: { tokenizer.rollBackToken(); parsed = parseBoolean(); break; } default: break; } parsed->stringify(0); } catch (std::logic_error &e) { break; } delete token; } // assert token not valid } JSONNode *parseObject() { //cout << "Parse Object\n"; JSONNode *node = new JSONNode(); JSONObject *keyObjectMap = new JSONObject(); bool hasCompleted = false; Token *token = tokenizer.getToken(); while (!hasCompleted) { if (tokenizer.hasMoreTokens()) { string key = token->value; tokenizer.getToken(); token = tokenizer.getToken(); switch (token->type) { case STRING: { tokenizer.rollBackToken(); (*keyObjectMap)[key] = parseString(); break; } case ARRAY_OPEN: { (*keyObjectMap)[key] = parseList(); break; } case NUMBER: { tokenizer.rollBackToken(); (*keyObjectMap)[key] = parseNumber(); break; } case CURLY_OPEN: { (*keyObjectMap)[key] = parseObject(); break; } case BOOLEAN: { tokenizer.rollBackToken(); (*keyObjectMap)[key] = parseBoolean(); break; } case NULL_TYPE: { (*keyObjectMap)[key] = parseNull(); break; } default: break; } delete token; token = tokenizer.getToken(); if (token->type == CURLY_CLOSE) { hasCompleted = true; delete token; break; } } else { throw std::logic_error("No more tokens"); } } node->setObject(keyObjectMap); return node; } JSONNode *parseList() { //cout << "Parse List\n"; JSONNode *node = new JSONNode(); JSONList *list = new JSONList(); bool hasCompleted = false; Token *token = tokenizer.getToken(); while (!hasCompleted) { if (!tokenizer.hasMoreTokens()) { throw std::logic_error("No more tokens"); } else { JSONNode *node; switch (token->type) { case ARRAY_OPEN: { node = parseList(); break; } case CURLY_OPEN: { node = parseObject(); break; } case STRING: { tokenizer.rollBackToken(); node = parseString(); break; } case NUMBER: { tokenizer.rollBackToken(); node = parseNumber(); break; } case BOOLEAN: { tokenizer.rollBackToken(); node = parseBoolean(); break; } case NULL_TYPE: { node = parseNull(); break; } default: break; } list->push_back(node); delete token; token = tokenizer.getToken(); if (token->type == ARRAY_CLOSE) { hasCompleted = true; } } } delete token; node->setList(list); return node; } JSONNode *parseString() { //cout << "Parse string\n"; JSONNode *node = new JSONNode(); Token *token = tokenizer.getToken(); string *sValue = new string(token->value); delete token; node->setString(sValue); return node; } JSONNode *parseNumber() { //cout << "Parse number\n"; JSONNode *node = new JSONNode(); Token *token = tokenizer.getToken(); string value = token->value; delete token; // cout << value << "\n"; int nbr = std::atoi(value.c_str()); node->setNumber(nbr); return node; } JSONNode *parseBoolean() { JSONNode *node = new JSONNode(); Token *token = tokenizer.getToken(); node->setBoolean(token->value == "True" ? true : false); delete token; return node; } JSONNode *parseNull() { JSONNode *node = new JSONNode(); node->setNull(); return node; } };