Skip to content

Commit 27f0006

Browse files
committed
add .span() method
1 parent 61917b6 commit 27f0006

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

src/parsy/__init__.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ def __getitem__(self, i):
2929
else:
3030
return self.data[i]
3131

32+
@dataclass
33+
class SourceSpan:
34+
"""Identifies a span of material from the data to parse.
35+
36+
Attributes:
37+
source (str | None): the source of the data, e.g. a file path.
38+
start ([int, int]): the start row and column of the span.
39+
end ([int, int]): the end row and column of the span.
40+
"""
41+
42+
source: str | None
43+
start: [int, int]
44+
end: [int, int]
45+
3246
def line_info_at(stream: Stream, index):
3347
if index > len(stream):
3448
raise ValueError("invalid index")
@@ -365,6 +379,9 @@ def mark(self) -> Parser:
365379
((start_row, start_column),
366380
original_value,
367381
(end_row, end_column))
382+
383+
``.span()'' is a more powerful version of this combinator, returning a
384+
SourceSpan.
368385
"""
369386

370387
@generate
@@ -376,6 +393,24 @@ def marked():
376393

377394
return marked
378395

396+
def span(self) -> Parser:
397+
"""
398+
Returns a parser that augments the initial parser's result with a
399+
SourceSpan capturing where that parser started and stopped.
400+
The new value is a tuple:
401+
402+
(source_span, original_value)
403+
"""
404+
405+
@generate
406+
def marked():
407+
source, *start = yield line_info
408+
body = yield self
409+
_, *end = yield line_info
410+
return (SourceSpan(source, tuple(start), tuple(end)), body)
411+
412+
return marked
413+
379414
def tag(self, name: str) -> Parser:
380415
"""
381416
Returns a parser that wraps the produced value of the initial parser in a

0 commit comments

Comments
 (0)