Browse Source

Merge pull request #935 from lark-parser/propagate_containers

Bugfix in propagate_positions
tags/gm/2021-09-23T00Z/github.com--lark-parser-lark/0.12.0
Erez Shinan 3 years ago
committed by GitHub
parent
commit
8b5d85605c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 9 deletions
  1. +22
    -9
      lark/parse_tree_builder.py
  2. +20
    -0
      tests/test_parser.py

+ 22
- 9
lark/parse_tree_builder.py View File

@@ -30,23 +30,36 @@ class PropagatePositions:
def __call__(self, children):
res = self.node_builder(children)

# local reference to Tree.meta reduces number of presence checks
if isinstance(res, Tree):
# Calculate positions while the tree is streaming, according to the rule:
# - nodes start at the start of their first child's container,
# and end at the end of their last child's container.
# Containers are nodes that take up space in text, but have been inlined in the tree.

res_meta = res.meta

first_meta = self._pp_get_meta(children)
if first_meta is not None:
res_meta.line = first_meta.line
res_meta.column = first_meta.column
res_meta.start_pos = first_meta.start_pos
res_meta.empty = False
if not hasattr(res_meta, 'line'):
# meta was already set, probably because the rule has been inlined (e.g. `?rule`)
res_meta.line = getattr(first_meta, 'container_line', first_meta.line)
res_meta.column = getattr(first_meta, 'container_column', first_meta.column)
res_meta.start_pos = getattr(first_meta, 'container_start_pos', first_meta.start_pos)
res_meta.empty = False

res_meta.container_line = getattr(first_meta, 'container_line', first_meta.line)
res_meta.container_column = getattr(first_meta, 'container_column', first_meta.column)

last_meta = self._pp_get_meta(reversed(children))
if last_meta is not None:
res_meta.end_line = last_meta.end_line
res_meta.end_column = last_meta.end_column
res_meta.end_pos = last_meta.end_pos
res_meta.empty = False
if not hasattr(res_meta, 'end_line'):
res_meta.end_line = getattr(last_meta, 'container_end_line', last_meta.end_line)
res_meta.end_column = getattr(last_meta, 'container_end_column', last_meta.end_column)
res_meta.end_pos = getattr(last_meta, 'container_end_pos', last_meta.end_pos)
res_meta.empty = False

res_meta.container_end_line = getattr(last_meta, 'container_end_line', last_meta.end_line)
res_meta.container_end_column = getattr(last_meta, 'container_end_column', last_meta.end_column)

return res



+ 20
- 0
tests/test_parser.py View File

@@ -94,6 +94,26 @@ class TestParsers(unittest.TestCase):
r = g.parse('a')
self.assertEqual( r.children[0].meta.line, 1 )

def test_propagate_positions2(self):
g = Lark("""start: a
a: b
?b: "(" t ")"
!t: "t"
""", propagate_positions=True)

start = g.parse("(t)")
a ,= start.children
t ,= a.children
assert t.children[0] == "t"

assert t.meta.column == 2
assert t.meta.end_column == 3

assert start.meta.column == a.meta.column == 1
assert start.meta.end_column == a.meta.end_column == 4



def test_expand1(self):

g = Lark("""start: a


Loading…
Cancel
Save