Skip to content

Instantly share code, notes, and snippets.

@bao-qian
Last active May 23, 2017 10:26
Show Gist options
  • Save bao-qian/c7cd1d418c2f655f86e5b6c142e34d8c to your computer and use it in GitHub Desktop.
Save bao-qian/c7cd1d418c2f655f86e5b6c142e34d8c to your computer and use it in GitHub Desktop.
json
from collections import deque
def encoded(json):
t = type(json)
if t is dict:
text = ""
for k, v in json.items():
text += "'{}': {},".format(k, encoded(v))
text = "{{ {} }}".format(text)
return text
elif t is list:
text = ""
for e in json:
text += "{},".format(encoded(e))
text = "[{}]".format(text)
return text
else:
return str(json)
def tokens_from_text(text):
ts = []
text = "".join(text.split()) # remove whitespace
text = text.replace("'", "")
for c in text:
if c.isdigit():
d = int(c)
ts.append(d)
else:
ts.append(c)
return ts
def parsed_from_matching_bracket(t, tokens):
right_from_left = {
"[": "]",
"{": "}",
}
left = t
right = right_from_left[left]
ts = deque([t])
match = 1
while match > 0:
t = tokens.popleft()
ts.append(t)
if t == left:
match += 1
elif t == right:
match -= 1
else:
continue
p = parsed_from_tokens(ts, None)
return p
def parsed_from_tokens(tokens, bracket):
print("tokens: <{}>\nbrackets: <{}>".format(tokens, bracket))
l = len(tokens)
if l > 0:
t = tokens.popleft()
if t in ["}", "]"] and l > 1:
return parsed_from_tokens(tokens, None)
elif t == "}":
return {}
elif t == "]":
return []
elif bracket == "{":
k = t
tokens.popleft() # eat :
v = tokens.popleft()
if v in ["[", "{"]:
v = parsed_from_matching_bracket(v, tokens)
tokens.popleft() # eat ,
rest = parsed_from_tokens(tokens, bracket)
return {**{k: v}, **rest}
elif bracket == "[":
e = t
if e in ["[", "{"]:
e = parsed_from_matching_bracket(e, tokens)
tokens.popleft() # eat ,
rest = parsed_from_tokens(tokens, bracket)
return [e] + rest
elif t in ["[", "{"]:
return parsed_from_tokens(tokens, t)
else:
message = "unknown\n t:<{}>\n tokens:<{}>\n bracket:<{}>\n"
raise TypeError(message.format(t, tokens, bracket))
def decoded(text):
ts = tokens_from_text(text)
ts = deque(ts) # convert list to linked list
p = parsed_from_tokens(ts, None)
return p
def test():
sample0 = [1, 'f', 3]
sample1 = [1, [4, 5, 6], 3]
sample2 = [1, [2, [3, [4], 5], 6], 7]
sample3 = [[1, 2, ], [3, 4, ], 5]
sample4 = {'a': 1, 'b': 2, 'c': 3}
sample5 = {'a': 1, 'b': {'c': 3, 'd': 4}, 'e': 5}
sample6 = {
'a': 1,
'b': [2, 3],
}
sample7 = {
'a': 1,
'b': [2, 3],
'c': {
'd': 1,
},
'e': [
'f',
{
'g': 1,
}
]
}
for i in range(8):
s = locals()["sample" + str(i)]
e = encoded(s)
print("encoded: {}".format(e))
d = decoded(e)
print("decoded: {}".format(d))
assert s == d
if __name__ == '__main__':
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment