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

.. only:: html

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

        :ref:`Go to the end <sphx_glr_download_examples_advanced_py3to2.py>`
        to download the full example code.

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

.. _sphx_glr_examples_advanced_py3to2.py:


Python 3 to Python 2 converter (tree templates)
===============================================

This example demonstrates how to translate between two trees using tree templates.
It parses Python 3, translates it to a Python 2 AST, and then outputs the result as Python 2 code.

Uses reconstruct_python.py for generating the final Python 2 code.

.. GENERATED FROM PYTHON SOURCE LINES 10-95

.. code-block:: Python



    from lark import Lark
    from lark.tree_templates import TemplateConf, TemplateTranslator

    from lark.indenter import PythonIndenter
    from reconstruct_python import PythonReconstructor


    #
    # 1. Define a Python parser that also accepts template vars in the code (in the form of $var)
    #
    TEMPLATED_PYTHON = r"""
    %import python (single_input, file_input, eval_input, atom, var, stmt, expr, testlist_star_expr, _NEWLINE, _INDENT, _DEDENT, COMMENT, NAME)

    %extend atom: TEMPLATE_NAME -> var

    TEMPLATE_NAME: "$" NAME

    ?template_start: (stmt | testlist_star_expr _NEWLINE)

    %ignore /[\t \f]+/          // WS
    %ignore /\\[\t \f]*\r?\n/   // LINE_CONT
    %ignore COMMENT
    """

    parser = Lark(TEMPLATED_PYTHON, parser='lalr', start=['single_input', 'file_input', 'eval_input', 'template_start'], postlex=PythonIndenter(), maybe_placeholders=False)


    def parse_template(s):
        return parser.parse(s + '\n', start='template_start')

    def parse_code(s):
        return parser.parse(s + '\n', start='file_input')


    #
    # 2. Define translations using templates (each template code is parsed to a template tree)
    #

    pytemplate = TemplateConf(parse=parse_template)

    translations_3to2 = {
        'yield from $a':
    	    'for _tmp in $a: yield _tmp',

        'raise $e from $x':
        	'raise $e',

        '$a / $b':
    	    'float($a) / $b',
    }
    translations_3to2 = {pytemplate(k): pytemplate(v) for k, v in translations_3to2.items()}

    #
    # 3. Translate and reconstruct Python 3 code into valid Python 2 code
    #

    python_reconstruct = PythonReconstructor(parser)

    def translate_py3to2(code):
    	tree = parse_code(code)
    	tree = TemplateTranslator(translations_3to2).translate(tree)
    	return python_reconstruct.reconstruct(tree)


    #
    # Test Code
    #

    _TEST_CODE = '''
    if a / 2 > 1:
        yield from [1,2,3]
    else:
        raise ValueError(a) from e

    '''

    def test():
    	print(_TEST_CODE)
    	print('   ----->    ')
    	print(translate_py3to2(_TEST_CODE))

    if __name__ == '__main__':
    	test()


.. _sphx_glr_download_examples_advanced_py3to2.py:

.. only:: html

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

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

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

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

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


.. only:: html

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

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