Some time ago i started to follow a Blog that weekly proposes some programming exercices and i solved one of their problems (an old one, from 2009) . So today i’m posting here my solution for the problem of this week. Basically they ask us to write a JSON parser in our favorite computer language, so i chose “Python” and tried to complete the task.
For those who don’t know what JSON is:
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.
My implementation is quite simple and it can contain some bugs (and is not optimized), so if you discover any error just leave a reply (we are always learning). Bellow is my code and a link to Github where you can also comment the code. In the following weeks i’ll try to solve more of their problems.
class json_parser:
def __init__(self, string):
self.json_data = self.__remove_blanks(string)
self.pointer = 0
def __remove_blanks(self, string):
new_list = []
inside_string = False
for i in list(string):
if inside_string or i != ' ':
new_list.append(i)
if i == '"':
inside_string = not inside_string
return "".join(n for n in new_list)
def __parse_obj(self):
new_dic = {}
self.pointer += 1
while self.json_data[self.pointer] != '}':
if self.json_data[self.pointer] == '"':
key = self.__parse_string()
else:
raise Exception # The only possible type of value for a key is String
if self.json_data[self.pointer] == ':':
self.pointer += 1
else:
raise Exception # invalid object
value = self.__parse_value()
if value == -1:
return -1
new_dic[key] = value
if self.json_data[self.pointer] == ',':
self.pointer += 1
self.pointer += 1
return new_dic
def __parse_array(self):
new_array = []
self.pointer += 1
while self.json_data[self.pointer] != ']':
value = self.__parse_value()
if value == -1:
return -1
else:
new_array.append(value)
if self.json_data[self.pointer] == ',':
self.pointer += 1
self.pointer += 1
return new_array
def __parse_string(self):
self.pointer += 1
start = self.pointer
while self.json_data[self.pointer] != '"':
self.pointer += 1
if self.pointer == len(self.json_data):
raise Exception # the string isn't closed
self.pointer += 1
return self.json_data[start:self.pointer - 1]
def __parse_other(self):
if self.json_data[self.pointer:self.pointer + 4] == 'true':
self.pointer += 4
return True
if self.json_data[self.pointer:self.pointer + 4] == 'null':
self.pointer += 4
return None
if self.json_data[self.pointer:self.pointer + 5] == 'false':
self.pointer += 5
return False
start = self.pointer
while (self.json_data[self.pointer].isdigit()) or (self.json_data[self.pointer] in (['-', '.', 'e', 'E'])):
self.pointer += 1
if '.' in self.json_data[start:self.pointer]:
return float(self.json_data[start:self.pointer])
else:
return int(self.json_data[start:self.pointer])
def __parse_value(self):
try:
if self.json_data[self.pointer] == '{':
new_value = self.__parse_obj()
elif self.json_data[self.pointer] == '[':
new_value = self.__parse_array()
elif self.json_data[self.pointer] == '"':
new_value = self.__parse_string()
else:
new_value = self.__parse_other()
except Exception:
print 'Error:: Invalid Data Format, unknown character at position', self.pointer
return -1
return new_value
def parse(self):
if self.json_data[self.pointer] == '{' or self.json_data[self.pointer] == '[':
final_object = self.__parse_value()
else:
print 'Error:: Invalid inicial Data Format'
final_object = None
return final_object
[EDIT: The previous code has several issues, so please do not use it. Python has many great packages to handle JSON documents the right way, like simplejson.]