diff --git a/projects/lilith/src/python/lilith/parser.py b/projects/lilith/src/python/lilith/parser.py index a351cf8..844564d 100644 --- a/projects/lilith/src/python/lilith/parser.py +++ b/projects/lilith/src/python/lilith/parser.py @@ -16,13 +16,17 @@ GRAMMAR = read_text('lilith', 'grammar.lark') # !frag[lang: yaml] # !end # all this following tex +class Symbol(t.NamedTuple): + name: str + + class Args(t.NamedTuple): positionals: object = [] kwargs: object = {} class Apply(t.NamedTuple): - name: str + name: Symbol args: Args @@ -43,8 +47,8 @@ class Block(t.NamedTuple): return "\n".join(self.body_lines) -class TreeToTuples(lark.Transformer): - @lark.v_args(inline=True) +class TreeToTuples(Transformer): + @v_args(inline=True) def string(self, s): return s[1:-1].replace('\\"', '"') @@ -59,7 +63,7 @@ class TreeToTuples(lark.Transformer): def word(self, args): """args: ['a'] ['a' ['b', 'c', 'd']]""" - return ".".join(a.value for a in args) + return Symbol(".".join(a.value for a in args)) def atom(self, args): return args[0] diff --git a/projects/lilith/test/python/test_parser.py b/projects/lilith/test/python/test_parser.py index f6d28ee..cc4514d 100644 --- a/projects/lilith/test/python/test_parser.py +++ b/projects/lilith/test/python/test_parser.py @@ -1,6 +1,7 @@ """tests covering the Lilith parser.""" -from lilith.parser import Apply, Args, Block, GRAMMAR, parse_buffer, parser_with_transformer +from lilith.parser import Apply, Args, Block, GRAMMAR, parse_buffer, parser_with_transformer, Symbol + import pytest @@ -14,8 +15,8 @@ def test_parse_args(args_grammar, example, expected): @pytest.mark.parametrize('example, expected', [ - ("foo: bar", {"foo": "bar"}), - ("foo: bar, baz: qux", {"foo": "bar", "baz": "qux"}), + ("foo: bar", {Symbol("foo"): Symbol("bar")}), + ("foo: bar, baz: qux", {Symbol("foo"): Symbol("bar"), Symbol("baz"): Symbol("qux")}), ]) def test_parse_kwargs(kwargs_grammar, example, expected): assert kwargs_grammar.parse(example) == expected @@ -25,9 +26,14 @@ def test_parse_kwargs(kwargs_grammar, example, expected): ("1", ([1], {})), ("1, 2", ([1, 2], {})), ("1, 2, 3", ([1, 2, 3], {})), - ("foo: bar", ([], {"foo": "bar"})), - ("foo: bar, baz: qux", ([], {"foo": "bar", "baz": "qux"})), - ("1; foo: bar, baz: qux", ([1], {"foo": "bar", "baz": "qux"})), + ("foo: bar", + ([], {Symbol("foo"): Symbol("bar")})), + ("foo: bar, baz: qux", + ([], {Symbol("foo"): Symbol("bar"), + Symbol("baz"): Symbol("qux")})), + ("1; foo: bar, baz: qux", + ([1], {Symbol("foo"): Symbol("bar"), + Symbol("baz"): Symbol("qux")})), ]) def test_parse_arguments(arguments_grammar, example, expected): assert arguments_grammar.parse(example) == expected @@ -35,13 +41,13 @@ def test_parse_arguments(arguments_grammar, example, expected): @pytest.mark.parametrize('example, expected', [ ('!def[syntax]', - Block(Apply('def', Args(['syntax'], {})), [])), + Block(Apply(Symbol('def'), Args(['syntax'], {})), [])), ('!frag[lang: md]', - Block(Apply('frag', Args([], {'lang': 'md'})), [])), + Block(Apply(Symbol('frag'), Args([], {'lang': 'md'})), [])), ('!frag[foo; lang: md]', - Block(Apply('frag', Args(['foo'], {'lang': 'md'})), [])), + Block(Apply(Symbol('frag'), Args(['foo'], {'lang': 'md'})), [])), ("!int.add[1, 2]", - Block(Apply('int.add', Args([1, 2], {})), [])), + Block(Apply(Symbol('int.add'), Args([1, 2], {})), [])), ]) def test_parse_header(header_grammar, example, expected): assert header_grammar.parse(example) == expected @@ -49,12 +55,12 @@ def test_parse_header(header_grammar, example, expected): @pytest.mark.parametrize('example, expected', [ ("!frag[lang: md]", - [Block(Apply('frag', Args([], {"lang": "md"})), [])]), + [Block(Apply(Symbol('frag'), Args([], {Symbol("lang"): Symbol("md")})), [])]), ("""!frag[lang: md]\nHello, world!\n\n""", - [Block(Apply('frag', Args([], {"lang": "md"})), ["Hello, world!", ""])]), + [Block(Apply(Symbol('frag'), Args([], {Symbol("lang"): Symbol("md")})), ["Hello, world!", ""])]), ("""!frag[lang: md]\nHello, world!\n\n!def[bar]""", - [Block(Apply('frag', Args([], {"lang": "md"})), ["Hello, world!", ""]), - Block(Apply('def', Args(["bar"], {})), [])]), + [Block(Apply(Symbol('frag'), Args([], {Symbol("lang"): Symbol("md")})), ["Hello, world!", ""]), + Block(Apply(Symbol('def'), Args([Symbol("bar")], {})), [])]), ]) def test_block_parser(example, expected): assert parse_buffer(example) == expected