Skip to content

Commit 7dd0a91

Browse files
committed
add .span() method
1 parent a475321 commit 7dd0a91

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

src/parsy/__init__.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,21 @@ def __getitem__(self, i):
3232
return self.data[i]
3333

3434

35+
@dataclass
36+
class SourceSpan:
37+
"""Identifies a span of material from the data to parse.
38+
39+
Attributes:
40+
source (str | None): the source of the data, e.g. a file path.
41+
start ([int, int]): the start row and column of the span.
42+
end ([int, int]): the end row and column of the span.
43+
"""
44+
45+
source: str | None
46+
start: [int, int]
47+
end: [int, int]
48+
49+
3550
def line_info_at(stream: Stream, index):
3651
if index > len(stream):
3752
raise ValueError("invalid index")
@@ -368,6 +383,9 @@ def mark(self) -> Parser:
368383
((start_row, start_column),
369384
original_value,
370385
(end_row, end_column))
386+
387+
``.span()'' is a more powerful version of this combinator, returning a
388+
SourceSpan.
371389
"""
372390

373391
@generate
@@ -379,6 +397,24 @@ def marked():
379397

380398
return marked
381399

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

0 commit comments

Comments
 (0)