瀏覽代碼

document lark.Interpreter, lark.Transformer

tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.10.0
Sasank Chilamkurthy 4 年之前
父節點
當前提交
cad22acf0f
共有 2 個檔案被更改,包括 90 行新增12 行删除
  1. +13
    -2
      docs/classes.rst
  2. +77
    -10
      lark/visitors.py

+ 13
- 2
docs/classes.rst 查看文件

@@ -29,6 +29,17 @@ Visitor

.. autoclass:: lark.visitors.VisitorBase

.. autoclass:: lark.Visitor
.. autoclass:: lark.visitors.Visitor

.. autoclass:: lark.visitors.Visitor_Recursive
.. autoclass:: lark.visitors.Visitor_Recursive

Interpreter
-----------

.. autoclass:: lark.visitors.Interpreter


Transformer
-----------

.. autoclass:: lark.visitors.Transformer

+ 77
- 10
lark/visitors.py 查看文件

@@ -42,12 +42,61 @@ class _Decoratable:


class Transformer(_Decoratable):
"""Visits the tree recursively, starting with the leaves and finally the root (bottom-up)
"""Transformer visit each node of the tree, and run the appropriate method
on it according to the node's data.

Calls its methods (provided by user via inheritance) according to tree.data
The returned value replaces the old one in the structure.
Calls its methods (provided by user via inheritance) according to
``tree.data``. The returned value replaces the old one in the structure.

They work bottom-up (or depth-first), starting with the leaves and
ending at the root of the tree. Transformers can be used to
implement map & reduce patterns. Because nodes are reduced from leaf to
root, at any point the callbacks may assume the children have already been
transformed (if applicable). ``Transformer`` can do anything ``Visitor``
can do, but because it reconstructs the tree, it is slightly less
efficient.

All these classes implement the transformer interface:

- ``Transformer`` - Recursively transforms the tree. This is the one you
probably want.
- ``Transformer_InPlace`` - Non-recursive. Changes the tree in-place
instead of returning new instances
- ``Transformer_InPlaceRecursive`` - Recursive. Changes the tree in-place
instead of returning new instances

Example:
::

from lark import Tree, Transformer

class EvalExpressions(Transformer):
def expr(self, args):
return eval(args[0])

t = Tree('a', [Tree('expr', ['1+2'])])
print(EvalExpressions().transform( t ))

# Prints: Tree(a, [3])

Args:
visit_tokens: By default, transformers only visit rules.
visit_tokens=True will tell ``Transformer`` to visit tokens
as well. This is a slightly slower alternative to lexer_callbacks
but it's easier to maintain and works for all algorithms
(even when there isn't a lexer).

Example:
::

class T(Transformer):
INT = int
NUMBER = float
def NAME(self, name):
return lookup_dict.get(name, name)

T(visit_tokens=True).transform(tree)

Can be used to implement map or reduce.
"""
__visit_tokens__ = True # For backwards compatibility

@@ -235,7 +284,8 @@ class Visitor(VisitorBase):
"""Bottom-up visitor, non-recursive.

Visits the tree, starting with the leaves and finally the root (bottom-up)
Calls its methods (provided by user via inheritance) according to tree.data
Calls its methods (provided by user via inheritance) according to
``tree.data``
"""

def visit(self, tree):
@@ -253,7 +303,8 @@ class Visitor_Recursive(VisitorBase):
"""Bottom-up visitor, recursive.

Visits the tree, starting with the leaves and finally the root (bottom-up)
Calls its methods (provided by user via inheritance) according to tree.data
Calls its methods (provided by user via inheritance) according to
``tree.data``
"""

def visit(self, tree):
@@ -285,13 +336,29 @@ def visit_children_decor(func):


class Interpreter(_Decoratable):
"""Top-down visitor, recursive
"""Interpreter walks the tree starting at the root.

Visits the tree, starting with the root and finally the leaves (top-down)
Calls its methods (provided by user via inheritance) according to tree.data
Calls its methods (provided by user via inheritance) according to
``tree.data``

Unlike ``Transformer`` and ``Visitor``, the Interpreter doesn't
automatically visit its sub-branches. The user has to explicitly call ``visit``,
``visit_children``, or use the ``@visit_children_decor``. This allows the
user to implement branching and loops.

Example:
::

class IncreaseSomeOfTheNumbers(Interpreter):
def number(self, tree):
tree.children[0] += 1

def skip(self, tree):
# skip this subtree. don't change any number node inside it.
pass

Unlike Transformer and Visitor, the Interpreter doesn't automatically visit its sub-branches.
The user has to explicitly call visit, visit_children, or use the @visit_children_decor
IncreaseSomeOfTheNumbers().visit(parse_tree)
"""

def visit(self, tree):


Loading…
取消
儲存