
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/advanced/reconstruct_python.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        Click :ref:`here <sphx_glr_download_examples_advanced_reconstruct_python.py>`
        to download the full example code

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_advanced_reconstruct_python.py:


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.

.. GENERATED FROM PYTHON SOURCE LINES 10-86

.. code-block:: default


    from lark import Token, Lark
    from lark.reconstruct import Reconstructor
    from lark.indenter import PythonIndenter

    # Official Python grammar by Lark
    python_parser3 = Lark.open_from_package('lark', 'python.lark', ['grammars'],
                                            parser='lalr', postlex=PythonIndenter(), start='file_input',
                                            maybe_placeholders=False    # Necessary for reconstructor
                                            )

    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"


    class PythonReconstructor:
        def __init__(self, parser):
            self._recons = Reconstructor(parser, {'_NEWLINE': special, '_DEDENT': special, '_INDENT': special})

        def reconstruct(self, tree):
            return self._recons.reconstruct(tree, postproc)


    def test():
        python_reconstructor = PythonReconstructor(python_parser3)

        self_contents = open(__file__).read()

        tree = python_parser3.parse(self_contents+'\n')
        output = python_reconstructor.reconstruct(tree)

        tree_new = python_parser3.parse(output)
        print(tree.pretty())
        print(tree_new.pretty())
        # assert tree.pretty() == tree_new.pretty()
        assert tree == tree_new

        print(output)


    if __name__ == '__main__':
        test()

.. rst-class:: sphx-glr-timing

   **Total running time of the script:** ( 0 minutes  0.000 seconds)


.. _sphx_glr_download_examples_advanced_reconstruct_python.py:


.. only :: html

 .. container:: sphx-glr-footer
    :class: sphx-glr-footer-example



  .. container:: sphx-glr-download sphx-glr-download-python

     :download:`Download Python source code: reconstruct_python.py <reconstruct_python.py>`



  .. container:: sphx-glr-download sphx-glr-download-jupyter

     :download:`Download Jupyter notebook: reconstruct_python.ipynb <reconstruct_python.ipynb>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
