| @@ -19,13 +19,22 @@ class AsList(object): | |||||
| Subclasses will be instanciated with the parse results as a single list, instead of as arguments. | Subclasses will be instanciated with the parse results as a single list, instead of as arguments. | ||||
| """ | """ | ||||
| class WithMeta(object): | |||||
| pass | |||||
| def camel_to_snake(name): | def camel_to_snake(name): | ||||
| return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower() | return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower() | ||||
| def _call(func, _data, children, _meta): | def _call(func, _data, children, _meta): | ||||
| return func(*children) | return func(*children) | ||||
| def _call_with_meta(func, _data, children, meta): | |||||
| return func(meta, children) | |||||
| def _call_with_meta_inline(func, _data, children, meta): | |||||
| return func(meta, *children) | |||||
| inline = v_args(wrapper=_call) | inline = v_args(wrapper=_call) | ||||
| with_meta = v_args(wrapper=_call_with_meta) | |||||
| with_meta_inline = v_args(wrapper=_call_with_meta_inline) | |||||
| def create_transformer(ast_module, transformer=None): | def create_transformer(ast_module, transformer=None): | ||||
| """Collects `Ast` subclasses from the given module, and creates a Lark transformer that builds the AST. | """Collects `Ast` subclasses from the given module, and creates a Lark transformer that builds the AST. | ||||
| @@ -45,7 +54,11 @@ def create_transformer(ast_module, transformer=None): | |||||
| if not name.startswith('_') and inspect.isclass(obj): | if not name.startswith('_') and inspect.isclass(obj): | ||||
| if issubclass(obj, Ast): | if issubclass(obj, Ast): | ||||
| if not issubclass(obj, AsList): | if not issubclass(obj, AsList): | ||||
| obj = inline(obj).__get__(t) | |||||
| obj = with_meta_inline(obj).__get__(t) | |||||
| else: | |||||
| obj = inline(obj).__get__(t) | |||||
| elif issubclass(obj, WithMeta): | |||||
| obj = with_meta(obj).__get__(t) | |||||
| setattr(t, camel_to_snake(name), obj) | setattr(t, camel_to_snake(name), obj) | ||||