""" Reconstruct Python ================== Demonstrates how Lark's experimental text-reconstruction feature can recreate functional Python code from its parse-tree, using just the correct grammar and a small formatter. """ from lark import Token from lark.reconstruct import Reconstructor from python_parser import python_parser3 SPACE_AFTER = set(',+-*/~@<>="|:') SPACE_BEFORE = (SPACE_AFTER - set(',:')) | set('\'') def special(sym): return Token('SPECIAL', sym.name) def postproc(items): stack = ['\n'] actions = [] last_was_whitespace = True for item in items: if isinstance(item, Token) and item.type == 'SPECIAL': actions.append(item.value) else: if actions: assert actions[0] == '_NEWLINE' and '_NEWLINE' not in actions[1:], actions for a in actions[1:]: if a == '_INDENT': stack.append(stack[-1] + ' ' * 4) else: assert a == '_DEDENT' stack.pop() actions.clear() yield stack[-1] last_was_whitespace = True if not last_was_whitespace: if item[0] in SPACE_BEFORE: yield ' ' yield item last_was_whitespace = item[-1].isspace() if not last_was_whitespace: if item[-1] in SPACE_AFTER: yield ' ' last_was_whitespace = True yield "\n" python_reconstruct = Reconstructor(python_parser3, {'_NEWLINE': special, '_DEDENT': special, '_INDENT': special}) def test(): self_contents = open(__file__).read() tree = python_parser3.parse(self_contents+'\n') output = python_reconstruct.reconstruct(tree, postproc) tree_new = python_parser3.parse(output) assert tree == tree_new print(output) if __name__ == '__main__': test()