@@ -7,10 +7,29 @@ Lark | |||||
.. autoclass:: lark.Lark | .. autoclass:: lark.Lark | ||||
:members: open, parse, save, load | :members: open, parse, save, load | ||||
LarkOptions | |||||
----------- | |||||
**Using Unicode character classes with regex** | |||||
.. autoclass:: lark.lark.LarkOptions | |||||
Python's builtin `re` module has a few persistent known bugs and also won't parse | |||||
advanced regex features such as character classes. | |||||
With `pip install lark-parser[regex]`, the `regex` module will be installed alongside `lark` and can act as a drop-in replacement to `re`. | |||||
Any instance of `Lark` instantiated with `regex=True` will now use the `regex` module instead of `re`. | |||||
For example, we can now use character classes to match PEP-3131 compliant Python identifiers. | |||||
Example: | |||||
:: | |||||
from lark import Lark | |||||
>>> g = Lark(r""" | |||||
?start: NAME | |||||
NAME: ID_START ID_CONTINUE* | |||||
ID_START: /[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_]+/ | |||||
ID_CONTINUE: ID_START | /[\p{Mn}\p{Mc}\p{Nd}\p{Pc}·]+/ | |||||
""", regex=True) | |||||
>>> g.parse('வணக்கம்') | |||||
'வணக்கம்' | |||||
Tree | Tree | ||||
---- | ---- | ||||
@@ -24,7 +43,7 @@ Token | |||||
.. autoclass:: lark.Token | .. autoclass:: lark.Token | ||||
Transformer, Vistor & Interpretor | |||||
Transformer, Visitor & Interpreter | |||||
--------------------------------- | --------------------------------- | ||||
See :doc:`visitors`. | See :doc:`visitors`. | ||||
@@ -33,10 +33,10 @@ Welcome to Lark's documentation! | |||||
grammar | grammar | ||||
tree_construction | tree_construction | ||||
visitors | |||||
classes | classes | ||||
visitors | |||||
nearley | nearley | ||||
Lark is a modern parsing library for Python. Lark can parse any context-free grammar. | Lark is a modern parsing library for Python. Lark can parse any context-free grammar. | ||||
@@ -17,12 +17,33 @@ See: `visitors.py`_ | |||||
Visitor | Visitor | ||||
------- | ------- | ||||
.. autoclass:: lark.visitors.VisitorBase | |||||
Visitors visit each node of the tree, and run the appropriate method on it according to the node's data. | |||||
They work bottom-up, starting with the leaves and ending at the root of the tree. | |||||
There are two classes that implement the visitor interface: | |||||
- ``Visitor``: Visit every node (without recursion) | |||||
- ``Visitor_Recursive``: Visit every node using recursion. Slightly faster. | |||||
Example: | |||||
:: | |||||
class IncreaseAllNumbers(Visitor): | |||||
def number(self, tree): | |||||
assert tree.data == "number" | |||||
tree.children[0] += 1 | |||||
IncreaseAllNumbers().visit(parse_tree) | |||||
.. autoclass:: lark.visitors.Visitor | .. autoclass:: lark.visitors.Visitor | ||||
.. autoclass:: lark.visitors.Visitor_Recursive | .. autoclass:: lark.visitors.Visitor_Recursive | ||||
Interpreter | |||||
----------- | |||||
.. autoclass:: lark.visitors.Interpreter | |||||
Transformer | Transformer | ||||
----------- | ----------- | ||||
@@ -30,11 +51,6 @@ Transformer | |||||
.. autoclass:: lark.visitors.Transformer | .. autoclass:: lark.visitors.Transformer | ||||
:members: __default__, __default_token__ | :members: __default__, __default_token__ | ||||
Interpreter | |||||
----------- | |||||
.. autoclass:: lark.visitors.Interpreter | |||||
v_args | v_args | ||||
------ | ------ | ||||
@@ -43,4 +59,4 @@ v_args | |||||
Discard | Discard | ||||
------- | ------- | ||||
.. autoclass:: lark.visitors.Discard | |||||
.. autoclass:: lark.visitors.Discard |
@@ -26,11 +26,12 @@ class UnexpectedEOF(ParseError): | |||||
class UnexpectedInput(LarkError): | class UnexpectedInput(LarkError): | ||||
"""UnexpectedInput Error. | """UnexpectedInput Error. | ||||
Used as a base class for the following exceptions: | |||||
- ``UnexpectedToken``: The parser recieved an unexpected token | - ``UnexpectedToken``: The parser recieved an unexpected token | ||||
- ``UnexpectedCharacters``: The lexer encountered an unexpected string | - ``UnexpectedCharacters``: The lexer encountered an unexpected string | ||||
After catching one of these exceptions, you may call the following | |||||
helper methods to create a nicer error message. | |||||
After catching one of these exceptions, you may call the following helper methods to create a nicer error message. | |||||
""" | """ | ||||
pos_in_stream = None | pos_in_stream = None | ||||
@@ -57,7 +58,7 @@ class UnexpectedInput(LarkError): | |||||
def match_examples(self, parse_fn, examples, token_type_match_fallback=False, use_accepts=False): | def match_examples(self, parse_fn, examples, token_type_match_fallback=False, use_accepts=False): | ||||
"""Allows you to detect what's wrong in the input text by matching | """Allows you to detect what's wrong in the input text by matching | ||||
against example errors. | against example errors. | ||||
Given a parser instance and a dictionary mapping some label with | Given a parser instance and a dictionary mapping some label with | ||||
some malformed syntax examples, it'll return the label for the | some malformed syntax examples, it'll return the label for the | ||||
example that bests matches the current error. The function will | example that bests matches the current error. The function will | ||||
@@ -66,7 +67,7 @@ class UnexpectedInput(LarkError): | |||||
For an example usage, see examples/error_reporting_lalr.py | For an example usage, see examples/error_reporting_lalr.py | ||||
Args: | |||||
Parameters: | |||||
parse_fn: parse function (usually ``lark_instance.parse``) | parse_fn: parse function (usually ``lark_instance.parse``) | ||||
examples: dictionary of ``{'example_string': value}``. | examples: dictionary of ``{'example_string': value}``. | ||||
use_accepts: Recommended to call this with ``use_accepts=True``. | use_accepts: Recommended to call this with ``use_accepts=True``. | ||||
@@ -27,75 +27,67 @@ class LarkOptions(Serialize): | |||||
""" | """ | ||||
OPTIONS_DOC = """ | OPTIONS_DOC = """ | ||||
**General** | |||||
**=== General ===** | |||||
start | start | ||||
The start symbol. Either a string, or a list of strings for | |||||
multiple possible starts (Default: "start") | |||||
The start symbol. Either a string, or a list of strings for multiple possible starts (Default: "start") | |||||
debug | debug | ||||
Display debug information, such as warnings (default: False) | |||||
Display debug information, such as warnings (default: False) | |||||
transformer | transformer | ||||
Applies the transformer to every parse tree (equivlent | |||||
to applying it after the parse, but faster) | |||||
Applies the transformer to every parse tree (equivlent to applying it after the parse, but faster) | |||||
propagate_positions | propagate_positions | ||||
Propagates (line, column, end_line, end_column) attributes into all tree branches. | |||||
Propagates (line, column, end_line, end_column) attributes into all tree branches. | |||||
maybe_placeholders | maybe_placeholders | ||||
When True, the ``[]`` operator returns ``None`` | |||||
when not matched. When ``False``, ``[]`` behaves like the ``?`` | |||||
operator, and returns no value at all. (default= ``False``. Recommended | |||||
to set to ``True``) | |||||
When True, the ``[]`` operator returns ``None`` when not matched. | |||||
When ``False``, ``[]`` behaves like the ``?`` operator, and returns no value at all. | |||||
(default= ``False``. Recommended to set to ``True``) | |||||
regex | regex | ||||
When True, uses the ``regex`` module instead of the | |||||
stdlib ``re``. | |||||
When True, uses the ``regex`` module instead of the stdlib ``re``. | |||||
cache | cache | ||||
Cache the results of the Lark grammar analysis, for x2 to | |||||
x3 faster loading. LALR only for now. | |||||
Cache the results of the Lark grammar analysis, for x2 to x3 faster loading. LALR only for now. | |||||
- When ``False``, does nothing (default) | |||||
- When ``True``, caches to a temporary file in the local directory | |||||
- When given a string, caches to the path pointed by the string | |||||
- When ``False``, does nothing (default) | |||||
- When ``True``, caches to a temporary file in the local directory | |||||
- When given a string, caches to the path pointed by the string | |||||
g_regex_flags | g_regex_flags | ||||
Flags that are applied to all terminals (both regex and strings) | |||||
Flags that are applied to all terminals (both regex and strings) | |||||
keep_all_tokens | keep_all_tokens | ||||
Prevent the tree builder from automagically removing "punctuation" tokens (default: False) | |||||
Prevent the tree builder from automagically removing "punctuation" tokens (default: False) | |||||
**Algorithm** | |||||
**=== Algorithm ===** | |||||
parser | parser | ||||
Decides which parser engine to use. Accepts "earley" or "lalr". | |||||
(Default: "earley"). (there is also a "cyk" option for legacy) | |||||
Decides which parser engine to use. Accepts "earley" or "lalr". (Default: "earley"). | |||||
(there is also a "cyk" option for legacy) | |||||
lexer | lexer | ||||
Decides whether or not to use a lexer stage | |||||
- "auto" (default): Choose for me based on the parser | |||||
- "standard": Use a standard lexer | |||||
- "contextual": Stronger lexer (only works with parser="lalr") | |||||
- "dynamic": Flexible and powerful (only with parser="earley") | |||||
- "dynamic_complete": Same as dynamic, but tries *every* variation | |||||
of tokenizing possible. | |||||
Decides whether or not to use a lexer stage | |||||
- "auto" (default): Choose for me based on the parser | |||||
- "standard": Use a standard lexer | |||||
- "contextual": Stronger lexer (only works with parser="lalr") | |||||
- "dynamic": Flexible and powerful (only with parser="earley") | |||||
- "dynamic_complete": Same as dynamic, but tries *every* variation of tokenizing possible. | |||||
ambiguity | ambiguity | ||||
Decides how to handle ambiguity in the parse. Only relevant if parser="earley" | |||||
- "resolve" - The parser will automatically choose the simplest | |||||
derivation (it chooses consistently: greedy for tokens, | |||||
non-greedy for rules) | |||||
- "explicit": The parser will return all derivations wrapped in | |||||
"_ambig" tree nodes (i.e. a forest). | |||||
Decides how to handle ambiguity in the parse. Only relevant if parser="earley" | |||||
**Domain Specific** | |||||
- "resolve" - The parser will automatically choose the simplest derivation | |||||
(it chooses consistently: greedy for tokens, non-greedy for rules) | |||||
- "explicit": The parser will return all derivations wrapped in "_ambig" tree nodes (i.e. a forest). | |||||
**=== Misc. / Domain Specific ===** | |||||
postlex | postlex | ||||
Lexer post-processing (Default: None) Only works with the | |||||
standard and contextual lexers. | |||||
Lexer post-processing (Default: None) Only works with the standard and contextual lexers. | |||||
priority | priority | ||||
How priorities should be evaluated - auto, none, normal, invert (Default: auto) | |||||
How priorities should be evaluated - auto, none, normal, invert (Default: auto) | |||||
lexer_callbacks | lexer_callbacks | ||||
Dictionary of callbacks for the lexer. May alter tokens during lexing. Use with caution. | |||||
Dictionary of callbacks for the lexer. May alter tokens during lexing. Use with caution. | |||||
use_bytes | use_bytes | ||||
Accept an input of type ``bytes`` instead of ``str`` (Python 3 only). | |||||
Accept an input of type ``bytes`` instead of ``str`` (Python 3 only). | |||||
edit_terminals | edit_terminals | ||||
A callback | |||||
A callback for editing the terminals before parse. | |||||
""" | """ | ||||
if __doc__: | if __doc__: | ||||
__doc__ += OPTIONS_DOC | __doc__ += OPTIONS_DOC | ||||
@@ -170,13 +162,11 @@ class LarkOptions(Serialize): | |||||
class Lark(Serialize): | class Lark(Serialize): | ||||
"""Main interface for the library. | """Main interface for the library. | ||||
It's mostly a thin wrapper for the many different parsers, and for | |||||
the tree constructor. | |||||
It's mostly a thin wrapper for the many different parsers, and for the tree constructor. | |||||
Args: | |||||
grammar: a string or file-object containing the | |||||
grammar spec (using Lark's ebnf syntax) | |||||
options : a dictionary controlling various aspects of Lark. | |||||
Parameters: | |||||
grammar: a string or file-object containing the grammar spec (using Lark's ebnf syntax) | |||||
options: a dictionary controlling various aspects of Lark. | |||||
Example: | Example: | ||||
>>> Lark(r'''start: "foo" ''') | >>> Lark(r'''start: "foo" ''') | ||||
@@ -317,8 +307,7 @@ class Lark(Serialize): | |||||
self.save(f) | self.save(f) | ||||
# TODO: merge with above | # TODO: merge with above | ||||
if __init__.__doc__: | |||||
__init__.__doc__ += "\nOptions:\n" + LarkOptions.OPTIONS_DOC | |||||
__doc__ += "\nOptions:\n" + LarkOptions.OPTIONS_DOC | |||||
__serialize_fields__ = 'parser', 'rules', 'options' | __serialize_fields__ = 'parser', 'rules', 'options' | ||||
@@ -391,8 +380,7 @@ class Lark(Serialize): | |||||
def open(cls, grammar_filename, rel_to=None, **options): | def open(cls, grammar_filename, rel_to=None, **options): | ||||
"""Create an instance of Lark with the grammar given by its filename | """Create an instance of Lark with the grammar given by its filename | ||||
If ``rel_to`` is provided, the function will find the grammar | |||||
filename in relation to it. | |||||
If ``rel_to`` is provided, the function will find the grammar filename in relation to it. | |||||
Example: | Example: | ||||
@@ -426,17 +414,15 @@ class Lark(Serialize): | |||||
def parse(self, text, start=None, on_error=None): | def parse(self, text, start=None, on_error=None): | ||||
"""Parse the given text, according to the options provided. | """Parse the given text, according to the options provided. | ||||
If a transformer is supplied to ``__init__``, returns whatever is the | |||||
result of the transformation. | |||||
Args: | |||||
Parameters: | |||||
text (str): Text to be parsed. | text (str): Text to be parsed. | ||||
start (str, optional): Required if Lark was given multiple | |||||
possible start symbols (using the start option). | |||||
on_error (function, optional): if provided, will be called on | |||||
UnexpectedToken error. Return true to resume parsing. | |||||
LALR only. See examples/error_puppet.py for an example | |||||
of how to use on_error. | |||||
start (str, optional): Required if Lark was given multiple possible start symbols (using the start option). | |||||
on_error (function, optional): if provided, will be called on UnexpectedToken error. Return true to resume parsing. | |||||
LALR only. See examples/error_puppet.py for an example of how to use on_error. | |||||
Returns: | |||||
If a transformer is supplied to ``__init__``, returns whatever is the | |||||
result of the transformation. Otherwise, returns a Tree instance. | |||||
""" | """ | ||||
@@ -7,11 +7,9 @@ from .. import Token | |||||
class ParserPuppet(object): | class ParserPuppet(object): | ||||
"""ParserPuppet gives you advanced control over error handling when | |||||
parsing with LALR. | |||||
"""ParserPuppet gives you advanced control over error handling when parsing with LALR. | |||||
For a simpler, more streamlined interface, see the ``on_error`` | |||||
argument to ``Lark.parse()``. | |||||
For a simpler, more streamlined interface, see the ``on_error`` argument to ``Lark.parse()``. | |||||
""" | """ | ||||
def __init__(self, parser, state_stack, value_stack, start, stream, set_state): | def __init__(self, parser, state_stack, value_stack, start, stream, set_state): | ||||
self.parser = parser | self.parser = parser | ||||
@@ -24,8 +22,7 @@ class ParserPuppet(object): | |||||
self.result = None | self.result = None | ||||
def feed_token(self, token): | def feed_token(self, token): | ||||
"""Feed the parser with a token, and advance it to the next state, | |||||
as if it recieved it from the lexer. | |||||
"""Feed the parser with a token, and advance it to the next state, as if it recieved it from the lexer. | |||||
Note that ``token`` has to be an instance of ``Token``. | Note that ``token`` has to be an instance of ``Token``. | ||||
""" | """ | ||||
@@ -89,9 +86,9 @@ class ParserPuppet(object): | |||||
return '\n'.join(out) | return '\n'.join(out) | ||||
def choices(self): | def choices(self): | ||||
"""Returns a dictionary of token types, matched to their action in | |||||
the parser. Only returns token types that are accepted by the | |||||
current state. | |||||
"""Returns a dictionary of token types, matched to their action in the parser. | |||||
Only returns token types that are accepted by the current state. | |||||
Updated by ``feed_token()``. | Updated by ``feed_token()``. | ||||
""" | """ | ||||
@@ -18,15 +18,14 @@ class Meta: | |||||
class Tree(object): | class Tree(object): | ||||
"""The main tree class. | """The main tree class. | ||||
Creates a new tree, and stores "data" and "children" in attributes of | |||||
the same name. Trees can be hashed and compared. | |||||
Creates a new tree, and stores "data" and "children" in attributes of the same name. | |||||
Trees can be hashed and compared. | |||||
Args: | |||||
Parameters: | |||||
data: The name of the rule or alias | data: The name of the rule or alias | ||||
children: List of matched sub-rules and terminals | children: List of matched sub-rules and terminals | ||||
meta: Line & Column numbers (if ``propagate_positions`` is enabled). | meta: Line & Column numbers (if ``propagate_positions`` is enabled). | ||||
meta attributes: line, column, start_pos, end_line, | |||||
end_column, end_pos | |||||
meta attributes: line, column, start_pos, end_line, end_column, end_pos | |||||
""" | """ | ||||
def __init__(self, data, children, meta=None): | def __init__(self, data, children, meta=None): | ||||
self.data = data | self.data = data | ||||
@@ -79,9 +78,8 @@ class Tree(object): | |||||
def iter_subtrees(self): | def iter_subtrees(self): | ||||
"""Depth-first iteration. | """Depth-first iteration. | ||||
Iterates over all the subtrees, never returning to the | |||||
same node twice (Lark's parse-tree is actually a DAG). | |||||
Iterates over all the subtrees, never returning to the same node twice (Lark's parse-tree is actually a DAG). | |||||
""" | """ | ||||
queue = [self] | queue = [self] | ||||
subtrees = OrderedDict() | subtrees = OrderedDict() | ||||
@@ -121,8 +119,7 @@ class Tree(object): | |||||
def iter_subtrees_topdown(self): | def iter_subtrees_topdown(self): | ||||
"""Breadth-first iteration. | """Breadth-first iteration. | ||||
Iterates over all the subtrees, return nodes in order like | |||||
pretty() does. | |||||
Iterates over all the subtrees, return nodes in order like pretty() does. | |||||
""" | """ | ||||
stack = [self] | stack = [self] | ||||
while stack: | while stack: | ||||
@@ -45,28 +45,23 @@ class _Decoratable: | |||||
class Transformer(_Decoratable): | class Transformer(_Decoratable): | ||||
"""Transformer visit each node of the tree, and run the appropriate method | |||||
on it according to the node's data. | |||||
"""Transformers 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. | |||||
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. It can be used to implement map or reduce patterns. | |||||
All these classes implement the transformer interface: | 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 | |||||
- ``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: | Example: | ||||
:: | :: | ||||
@@ -82,7 +77,7 @@ class Transformer(_Decoratable): | |||||
# Prints: Tree(a, [3]) | # Prints: Tree(a, [3]) | ||||
Args: | |||||
Parameters: | |||||
visit_tokens: By default, transformers only visit rules. | visit_tokens: By default, transformers only visit rules. | ||||
visit_tokens=True will tell ``Transformer`` to visit tokens | visit_tokens=True will tell ``Transformer`` to visit tokens | ||||
as well. This is a slightly slower alternative to lexer_callbacks | as well. This is a slightly slower alternative to lexer_callbacks | ||||
@@ -164,16 +159,16 @@ class Transformer(_Decoratable): | |||||
def __default__(self, data, children, meta): | def __default__(self, data, children, meta): | ||||
"""Default operation on tree (for override) | """Default operation on tree (for override) | ||||
Function that is called on if a function with a corresponding name has | |||||
not been found. Defaults to reconstruct the Tree | |||||
Function that is called on if a function with a corresponding name has not been found. | |||||
Defaults to reconstruct the Tree. | |||||
""" | """ | ||||
return Tree(data, children, meta) | return Tree(data, children, meta) | ||||
def __default_token__(self, token): | def __default_token__(self, token): | ||||
"""Default operation on token (for override) | """Default operation on token (for override) | ||||
Function that is called on if a function with a corresponding name has | |||||
not been found. Defaults to just return the argument. | |||||
Function that is called on if a function with a corresponding name has not been found. | |||||
Defaults to just return the argument. | |||||
""" | """ | ||||
return token | return token | ||||
@@ -259,25 +254,6 @@ class Transformer_InPlaceRecursive(Transformer): | |||||
# Visitors | # Visitors | ||||
class VisitorBase: | class VisitorBase: | ||||
"""Visitors visit each node of the tree | |||||
Run the appropriate method on it according to the node's data. | |||||
They work bottom-up, starting with the leaves and ending at the root | |||||
of the tree. There are two classes that implement the visitor interface: | |||||
- ``Visitor``: Visit every node (without recursion) | |||||
- ``Visitor_Recursive``: Visit every node using recursion. Slightly faster. | |||||
Example: | |||||
:: | |||||
class IncreaseAllNumbers(Visitor): | |||||
def number(self, tree): | |||||
assert tree.data == "number" | |||||
tree.children[0] += 1 | |||||
IncreaseAllNumbers().visit(parse_tree) | |||||
""" | |||||
def _call_userfunc(self, tree): | def _call_userfunc(self, tree): | ||||
return getattr(self, tree.data, self.__default__)(tree) | return getattr(self, tree.data, self.__default__)(tree) | ||||
@@ -293,8 +269,7 @@ class Visitor(VisitorBase): | |||||
"""Bottom-up visitor, non-recursive. | """Bottom-up visitor, non-recursive. | ||||
Visits the tree, starting with the leaves and finally the root (bottom-up) | 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): | def visit(self, tree): | ||||
@@ -312,8 +287,7 @@ class Visitor_Recursive(VisitorBase): | |||||
"""Bottom-up visitor, recursive. | """Bottom-up visitor, recursive. | ||||
Visits the tree, starting with the leaves and finally the root (bottom-up) | 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): | def visit(self, tree): | ||||
@@ -348,13 +322,12 @@ class Interpreter(_Decoratable): | |||||
"""Interpreter walks the tree starting at the root. | """Interpreter walks the tree starting at the root. | ||||
Visits the tree, starting with the root and finally the leaves (top-down) | 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`` | |||||
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. | |||||
For each tree node, it 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: | Example: | ||||
:: | :: | ||||
@@ -452,21 +425,17 @@ def _vargs_tree(f, data, children, meta): | |||||
def v_args(inline=False, meta=False, tree=False, wrapper=None): | def v_args(inline=False, meta=False, tree=False, wrapper=None): | ||||
"""A convenience decorator factory for modifying the behavior of | |||||
user-supplied visitor methods. | |||||
By default, callback methods of transformers/visitors accept one argument - | |||||
a list of the node's children. ``v_args`` can modify this behavior. When | |||||
used on a transformer/visitor class definition, it applies to all the | |||||
callback methods inside it. Accepts one of three following flags. | |||||
Args: | |||||
inline: Children are provided as ``*args`` instead of a list | |||||
argument (not recommended for very long lists). | |||||
meta: Provides two arguments: ``children`` and ``meta`` (instead of | |||||
just the first) | |||||
tree: Provides the entire tree as the argument, instead of the | |||||
children. | |||||
"""A convenience decorator factory for modifying the behavior of user-supplied visitor methods. | |||||
By default, callback methods of transformers/visitors accept one argument - a list of the node's children. | |||||
``v_args`` can modify this behavior. When used on a transformer/visitor class definition, | |||||
it applies to all the callback methods inside it. | |||||
Parameters: | |||||
inline: Children are provided as ``*args`` instead of a list argument (not recommended for very long lists). | |||||
meta: Provides two arguments: ``children`` and ``meta`` (instead of just the first) | |||||
tree: Provides the entire tree as the argument, instead of the children. | |||||
Example: | Example: | ||||
:: | :: | ||||