開発環境
- OS: macOS High Sierra - Apple
- Text Editor: Emacs
- プログラミング言語: Python3
- モジュール: sion (GitHub)
load関数の引数がファイル名だと、手元のファイルの読み込みは簡単だけど、データのやり取りでバイナリモードのファイルの読み込みが出来なくて、urllib.responeモジュールのurlopenとかで使えないから変更。
コード(Emacs)
sion.py
# Created by kamimura on 2018/07/21.
# Copyright © 2018 kamimura. All rights reserved.
import sys
import datetime
from antlr4 import *
from SIONLexer import SIONLexer
from SIONParser import SIONParser
from SIONVisitor import SIONVisitor
def load(file, encoding: str='utf-8', errors: str='strict') -> object:
data = file.read()
if type(data) == bytes:
data = data.decode(encoding, errors)
stream = InputStream(data)
lexer = SIONLexer(stream)
tokens = CommonTokenStream(lexer)
parser = SIONParser(tokens)
tree = parser.si_self()
visitor = SIONVisitor()
return visitor.visit(tree)
def str_esc(s):
for o, n in [('"', '\\"'), ('\n', '\\n'), ('\r', '\\r'), ('\\', '\\\\')]:
s = s.replace(o, n)
return s
def dump(obj, file):
t = type(obj)
if obj is None:
print('nil', file=file, end='')
elif t == bool:
if obj:
print('ture', file=file, end='')
else:
print('false', file=file, end='')
elif t in {int, float}:
print(obj, file=file, end='')
elif t == str:
print(f'"{str_esc(obj)}"', file=file, end='')
elif t == bytes:
print(f'.Data("{str(obj)[2:-1]}")', file=file, end='')
elif t == datetime.datetime:
print(f'.Date({t.timestamp(obj)})', file=file, end='')
elif t in {list, tuple}:
print(f'[', file=file, end='')
if len(obj) > 0:
for o in obj[:-1]:
dump(o, file)
print(',', file=file, end='')
dump(obj[-1], file)
print(']', file=file, end='')
elif t == dict:
print('[', file=file, end='')
ks = list(obj.keys())
if len(ks) == 0:
print(':', file=file, end='')
elif len(ks) == 1:
dump(ks[0], file)
print(':', file=file, end='')
dump(obj[ks[0]], file)
else:
for k in ks[:-1]:
dump(k, file)
print(':', file=file, end='')
dump(obj[k], file)
print(',', file=file, end='')
dump(ks[-1], file)
print(':', file=file, end='')
dump(obj[ks[-1]], file)
print(']', file=file, end='')
else:
raise TypeError(
f"Object of type '{obj.__class__.__name__}' is not SION serializable")
if __name__ == '__main__':
if len(sys.argv) > 1:
filename = sys.argv[1]
else:
filename = '../test/t.sion'
with open(filename) as f:
obj = load(f)
print(obj)
with open('../test/output.sion', 'w') as f:
dump(obj, f)
バイナリファイルの読み込みが出来る事を確認。
Python 3
#!/usr/bin/env python3
import pprint
from urllib.request import urlopen
import sion
url = 'https://raw.githubusercontent.com/kamimura/py-sion/master/test/t.sion'
with urlopen(url) as res:
pprint.pprint(sion.load(res))
with open('sample.sion') as f:
pprint.pprint(sion.load(f))
入出力結果(Terminal, Jupyter(IPython))
$ cat sample.sion
[
"array" : [
nil,
true,
1, // Int in decimal
1.0, // Double in decimal
"one",
[1],
["one" : 1.0]
],
"bool" : true,
"data" : .Data("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"),
"date" : .Date(0x0p+0),
"dictionary" : [
"array" : [],
"bool" : false,
"double" : 0x0p+0,
"int" : 0,
"nil" : nil,
"object" : [:],
"string" : ""
],
"double" : 0x1.518f5c28f5c29p+5, // Double in hexadecimal
"int" : -0x2a, // Int in hexadecimal
"nil" : nil,
"string" : "漢字、カタカナ、ひらがなの入ったstring😇",
"url" : "https://github.com/dankogai/",
nil : "Unlike JSON and Property Lists,",
true : "Yes, SION",
1 : "does accept",
1.0 : "non-String keys.",
[] : "like",
[:] : "Map of ECMAScript."
]$ ./sample3.py
{None: 'Unlike JSON and Property Lists,',
True: 'non-String keys.',
'[]': 'like',
'array': [None, True, 1, 1.0, 'one', [1], {'one': 1.0}],
'bool': True,
'data': b'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
'date': datetime.datetime(1970, 1, 1, 9, 0),
'dictionary': {'array': [],
'bool': False,
'double': 0.0,
'int': 0,
'nil': None,
'object': {},
'string': ''},
'double': 42.195,
'int': -42,
'nil': None,
'string': '漢字、カタカナ、ひらがなの入ったstring😇',
'url': 'https://github.com/dankogai/',
'{}': 'Map of ECMAScript.'}
{None: 'Unlike JSON and Property Lists,',
True: 'non-String keys.',
'[]': 'like',
'array': [None, True, 1, 1.0, 'one', [1], {'one': 1.0}],
'bool': True,
'data': b'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
'date': datetime.datetime(1970, 1, 1, 9, 0),
'dictionary': {'array': [],
'bool': False,
'double': 0.0,
'int': 0,
'nil': None,
'object': {},
'string': ''},
'double': 42.195,
'int': -42,
'nil': None,
'string': '漢字、カタカナ、ひらがなの入ったstring😇',
'url': 'https://github.com/dankogai/',
'{}': 'Map of ECMAScript.'}
$
0 コメント:
コメントを投稿