aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/lark/ast_utils.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/lark/ast_utils.py')
-rw-r--r--.venv/lib/python3.12/site-packages/lark/ast_utils.py55
1 files changed, 55 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/lark/ast_utils.py b/.venv/lib/python3.12/site-packages/lark/ast_utils.py
new file mode 100644
index 00000000..0c03d458
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/lark/ast_utils.py
@@ -0,0 +1,55 @@
+"""
+ Module of utilities for transforming a lark.Tree into a custom Abstract Syntax Tree
+"""
+
+import inspect, re
+
+from lark import Transformer, v_args
+
+class Ast(object):
+ """Abstract class
+
+ Subclasses will be collected by `create_transformer()`
+ """
+ pass
+
+class AsList(object):
+ """Abstract class
+
+ Subclasses will be instanciated with the parse results as a single list, instead of as arguments.
+ """
+
+class WithMeta(object):
+ """Abstract class
+
+ Subclasses will be instanciated with the Meta instance of the tree. (see ``v_args`` for more detail)
+ """
+ pass
+
+def camel_to_snake(name):
+ return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
+
+def create_transformer(ast_module, transformer=None, decorator_factory=v_args):
+ """Collects `Ast` subclasses from the given module, and creates a Lark transformer that builds the AST.
+
+ For each class, we create a corresponding rule in the transformer, with a matching name.
+ CamelCase names will be converted into snake_case. Example: "CodeBlock" -> "code_block".
+
+ Classes starting with an underscore (`_`) will be skipped.
+
+ Parameters:
+ ast_module: A Python module containing all the subclasses of ``ast_utils.Ast``
+ transformer (Optional[Transformer]): An initial transformer. Its attributes may be overwritten.
+ decorator_factory (Callable): An optional callable accepting two booleans, inline, and meta,
+ and returning a decorator for the methods of ``transformer``. (default: ``v_args``).
+ """
+ t = transformer or Transformer()
+
+ for name, obj in inspect.getmembers(ast_module):
+ if not name.startswith('_') and inspect.isclass(obj):
+ if issubclass(obj, Ast):
+ wrapper = decorator_factory(inline=not issubclass(obj, AsList), meta=issubclass(obj, WithMeta))
+ obj = wrapper(obj).__get__(t)
+ setattr(t, camel_to_snake(name), obj)
+
+ return t \ No newline at end of file