rlib.parsing
で、py ディレクトリと pypy ディレクトリをざくっと cp -R でコピー
rlib parsing でサクったら id:mopemope:20080314:p2 が見つかったので参考にしつつがさごそ
#!/usr/local/bin/python # vi:set ts=3 sw=3: # vim:set sts=0 noet: import pypy.rlib.parsing.ebnfparse grammar = """ STRING: "\\"[^\\\\"]*\\""; NUMBER: "\-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][\+\-]?[0-9]+)?"; IGNORE: " |\n"; value: <STRING> | <NUMBER> | <object> | <array> | <"null"> | <"true"> | <"false">; object: ["{"] (entry [","])* entry ["}"]; array: ["["] (value [","])* value ["]"]; entry: STRING [":"] value; """ regexs, rules, ToAST = pypy.rlib.parsing.ebnfparse.parse_ebnf(grammar) parse = pypy.rlib.parsing.ebnfparse.make_parse_function(regexs, rules) t = parse('{"a": "5", "b": [1, null, 3, true, {"f": "g", "h": 6}]}').visit(ToAST()) print(t)
そのままでは芸がないので rlib のドキュメントの例をやってみた
実行結果はこんな感じ
[Nonterminal('object', [Nonterminal('entry', [Symbol('STRING', '"a"'), Symbol('STRING', '"5"')]), Nonterminal('entry', [Symbol('STRING', '"b"'), Nonterminal('array', [Symbol('NUMBER', '1'), Symbol('__0_null', 'null'), Symbol('NUMBER', '3'), Symbol('__1_true', 'true'), Nonterminal('object', [Nonterminal('entry', [Symbol('STRING', '"f"'), Symbol('STRING', '"g"')]), Nonterminal('entry', [Symbol('STRING', '"h"'), Symbol('NUMBER', '6')])])])])])]