
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/advanced/prioritizer.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_prioritizer.py>`
        to download the full example code.

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

.. _sphx_glr_examples_advanced_prioritizer.py:


Custom SPPF Prioritizer
=======================

This example demonstrates how to subclass ``ForestVisitor`` to make a custom
SPPF node prioritizer to be used in conjunction with ``TreeForestTransformer``.

Our prioritizer will count the number of descendants of a node that are tokens.
By negating this count, our prioritizer will prefer nodes with fewer token
descendants. Thus, we choose the more specific parse.

.. GENERATED FROM PYTHON SOURCE LINES 12-73

.. code-block:: Python


    from lark import Lark
    from lark.parsers.earley_forest import ForestVisitor, TreeForestTransformer

    class TokenPrioritizer(ForestVisitor):

        def visit_symbol_node_in(self, node):
            # visit the entire forest by returning node.children
            return node.children

        def visit_packed_node_in(self, node):
            return node.children

        def visit_symbol_node_out(self, node):
            priority = 0
            for child in node.children:
                # Tokens do not have a priority attribute
                # count them as -1
                priority += getattr(child, 'priority', -1)
            node.priority = priority

        def visit_packed_node_out(self, node):
            priority = 0
            for child in node.children:
                priority += getattr(child, 'priority', -1)
            node.priority = priority

        def on_cycle(self, node, path):
            raise Exception("Oops, we encountered a cycle.")

    grammar = """
    start: hello " " world | hello_world
    hello: "Hello"
    world: "World"
    hello_world: "Hello World"
    """

    parser = Lark(grammar, parser='earley', ambiguity='forest')
    forest = parser.parse("Hello World")

    print("Default prioritizer:")
    tree = TreeForestTransformer(resolve_ambiguity=True).transform(forest)
    print(tree.pretty())

    forest = parser.parse("Hello World")

    print("Custom prioritizer:")
    tree = TreeForestTransformer(resolve_ambiguity=True, prioritizer=TokenPrioritizer()).transform(forest)
    print(tree.pretty())

    # Output:
    #
    # Default prioritizer:
    # start
    #   hello Hello
    #
    #   world World
    #
    # Custom prioritizer:
    # start
    #   hello_world   Hello World


.. _sphx_glr_download_examples_advanced_prioritizer.py:

.. only:: html

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

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

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

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

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


.. only:: html

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

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