From 1b5ffc06600bbc2b1c7dadacffb47d3f13cc69cb Mon Sep 17 00:00:00 2001 From: MegaIng1 Date: Sun, 29 Mar 2020 17:14:24 +0200 Subject: [PATCH] Added the ability to use templates as template arguments. Error reporting should still be horrible. --- lark/load_grammar.py | 18 ++++++++++++------ tests/test_parser.py | 7 +++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/lark/load_grammar.py b/lark/load_grammar.py index 3fe10a3..cba2d8f 100644 --- a/lark/load_grammar.py +++ b/lark/load_grammar.py @@ -358,9 +358,14 @@ class _ReplaceSymbols(Transformer_InPlace): self.names = {} def value(self, c): - if len(c) == 1 and isinstance(c[0], Token) and c[0].type == 'RULE' and c[0].value in self.names: + if len(c) == 1 and isinstance(c[0], Token) and c[0].value in self.names: return self.names[c[0].value] return self.__default__('value', c, None) + + def template_usage(self, c): + if c[0] in self.names: + return self.__default__('template_usage', [self.names[c[0]].name] + c[1:], None) + return self.__default__('template_usage', c, None) class ApplyTemplates(Transformer_InPlace): " Apply the templates, creating new rules that represent the used templates " @@ -912,11 +917,12 @@ class GrammarLoader: for temp in expansions.find_data('template_usage'): sym = temp.children[0] args = temp.children[1:] - if sym not in rule_names: - raise GrammarError("Template '%s' used but not defined (in rule %s)" % (sym, name)) - if len(args) != rule_names[sym]: - raise GrammarError("Wrong number of template arguments used for %s " - "(expected %s, got %s) (in rule %s)"%(sym, rule_names[sym], len(args), name)) + if sym not in params: + if sym not in rule_names: + raise GrammarError("Template '%s' used but not defined (in rule %s)" % (sym, name)) + if len(args) != rule_names[sym]: + raise GrammarError("Wrong number of template arguments used for %s " + "(expected %s, got %s) (in rule %s)"%(sym, rule_names[sym], len(args), name)) for sym in _find_used_symbols(expansions): if sym.type == 'TERMINAL': if sym not in terminal_names: diff --git a/tests/test_parser.py b/tests/test_parser.py index 6b9df3f..0102c62 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -895,6 +895,13 @@ def _make_parser_test(LEXER, PARSER): x = g.parse("AB") self.assertSequenceEqual(x.children, [Tree('b',[])]) + def test_templates_templates(self): + g = _Lark('''start: a{b} + a{t}: t{"a"} + b{x}: x''') + x = g.parse('a') + self.assertSequenceEqual(x.children, [Tree('a', [Tree('b',[])])]) + def test_g_regex_flags(self): g = _Lark(""" start: "a" /b+/ C