From 6d33bd58381fcd4bf20bd832a6fe031535e619fd Mon Sep 17 00:00:00 2001 From: Chris Mounce Date: Sat, 10 May 2025 11:42:27 -0700 Subject: [PATCH] Add a very basic capture group iterator - Add a basic iterator over Event - Use single struct per capture group to store capture info --- src/preprocess/peg.rs | 77 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/src/preprocess/peg.rs b/src/preprocess/peg.rs index ec1babf..3d8b44f 100644 --- a/src/preprocess/peg.rs +++ b/src/preprocess/peg.rs @@ -1,14 +1,22 @@ -use std::ops::RangeInclusive; +use std::ops::{Range, RangeInclusive}; #[derive(Debug)] pub enum Event { Open { kind: &'static str, offset: usize }, Close { offset: usize }, } + +#[derive(Debug)] +pub struct CaptureInfo { + pub kind: &'static str, + pub span: Range, + sibling_index: usize, +} + pub struct Parser { input: String, offset: usize, - output: Vec, + output: Vec, } #[derive(Clone, Copy)] @@ -37,6 +45,34 @@ impl Parser { self.offset = sp.offset; self.output.truncate(sp.num_tags); } + + pub fn iter(&self) -> CaptureIterator { + CaptureIterator { + events: &self.output, + index: 0, + } + } +} + +pub struct CaptureIterator<'a> { + events: &'a [CaptureInfo], + index: usize, +} + +pub struct CaptureGroup<'a> { + pub event: &'a CaptureInfo, +} + +impl<'a> Iterator for CaptureIterator<'a> { + type Item = CaptureGroup<'a>; + + fn next(&mut self) -> Option { + while let Some(x) = self.events.get(self.index) { + self.index = x.sibling_index; + return Some(CaptureGroup { event: x }); + } + None + } } pub trait Rule { @@ -215,12 +251,16 @@ where { fn parse(&self, p: &mut Parser) -> bool { let save = p.save(); - p.output.push(Event::Open { + let index = p.output.len(); + let start_offset = p.offset; + p.output.push(CaptureInfo { kind: self.0, - offset: p.offset, + span: 0..0, + sibling_index: 0, }); if self.1.parse(p) { - p.output.push(Event::Close { offset: p.offset }); + p.output[index].span = start_offset..p.offset; + p.output[index].sibling_index = p.output.len(); true } else { p.restore(save); @@ -350,21 +390,28 @@ mod test { assert!(rule.parse(&mut p)); assert_debug_snapshot!(p.output, @r#" [ - Open { + CaptureInfo { kind: "num", - offset: 7, + span: 7..10, + sibling_index: 1, }, - Close { - offset: 10, - }, - Open { + CaptureInfo { kind: "num", - offset: 20, - }, - Close { - offset: 22, + span: 20..22, + sibling_index: 2, }, ] "#); + + let result: Vec<_> = p + .iter() + .map(|x| &p.input[x.event.span.start..x.event.span.end]) + .collect(); + assert_debug_snapshot!(result, @r#" + [ + "123", + "45", + ] + "#); } }