This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 lines
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