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')])])])])])]