This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

55 linhas
1.9 KiB

  1. """
  2. Module of utilities for transforming a lark.Tree into a custom Abstract Syntax Tree
  3. """
  4. import inspect, re
  5. from lark import Transformer, v_args
  6. class Ast(object):
  7. """Abstract class
  8. Subclasses will be collected by `create_transformer()`
  9. """
  10. pass
  11. class AsList(object):
  12. """Abstract class
  13. Subclasses will be instanciated with the parse results as a single list, instead of as arguments.
  14. """
  15. class WithMeta(object):
  16. """Abstract class
  17. Subclasses will be instanciated with the Meta instance of the tree. (see ``v_args`` for more detail)
  18. """
  19. pass
  20. def camel_to_snake(name):
  21. return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
  22. def create_transformer(ast_module, transformer=None, decorator_factory=v_args):
  23. """Collects `Ast` subclasses from the given module, and creates a Lark transformer that builds the AST.
  24. For each class, we create a corresponding rule in the transformer, with a matching name.
  25. CamelCase names will be converted into snake_case. Example: "CodeBlock" -> "code_block".
  26. Classes starting with an underscore (`_`) will be skipped.
  27. Parameters:
  28. ast_module: A Python module containing all the subclasses of ``ast_utils.Ast``
  29. transformer (Optional[Transformer]): An initial transformer. Its attributes may be overwritten.
  30. decorator_factory (Callable): An optional callable accepting two booleans, inline, and meta,
  31. and returning a decorator for the methods of ``transformer``. (default: ``v_args``).
  32. """
  33. t = transformer or Transformer()
  34. for name, obj in inspect.getmembers(ast_module):
  35. if not name.startswith('_') and inspect.isclass(obj):
  36. if issubclass(obj, Ast):
  37. wrapper = decorator_factory(inline=not issubclass(obj, AsList), meta=issubclass(obj, WithMeta))
  38. obj = wrapper(obj).__get__(t)
  39. setattr(t, camel_to_snake(name), obj)
  40. return t