Skip to content

Commit

Permalink
Refactored line comment scanning methods
Browse files Browse the repository at this point in the history
  • Loading branch information
vallentin committed Jul 10, 2023
1 parent 425c714 commit c48da03
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 6 deletions.
4 changes: 4 additions & 0 deletions text-scanner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ harness = false
[[bench]]
name = "accept_vs_test"
harness = false

[[bench]]
name = "scan_line_comment"
harness = false
76 changes: 76 additions & 0 deletions text-scanner/benches/scan_line_comment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use std::hint::black_box;

use criterion::{criterion_group, criterion_main, Criterion};
use text_scanner::{Scanner, ScannerResult};

#[inline]
fn scan_line_comment_old<'text>(scanner: &mut Scanner<'text>) -> ScannerResult<'text, &'text str> {
scanner.scan_with(|scanner| {
scanner.accept_str("//")?;
// Note: This does not handle the case where `\r` is not
// immediately followed by `\n`. However, the test data
// does not include that case
scanner.skip_until_char_any(&['\n', '\r']);
Ok(())
})
}

#[inline]
fn scan_line_comment_new<'text>(scanner: &mut Scanner<'text>) -> ScannerResult<'text, &'text str> {
scanner.scan_with(|scanner| {
scanner.test_str("//")?;
_ = scanner.next_line();
Ok(())
})
}

#[inline]
fn scan<'text, F>(scanner: &mut Scanner<'text>, mut f: F)
where
F: FnMut(&mut Scanner<'text>) -> ScannerResult<'text, &'text str>,
{
while scanner.has_remaining_text() {
let (r, _s) = scanner.skip_whitespace();
if !r.is_empty() {
continue;
}

if let Ok(_) = f(scanner) {
continue;
}

if let Ok(_) = scanner.next_line_terminator() {
continue;
}

unreachable!();
}
}

fn bench_accept_vs_test(c: &mut Criterion) {
let text = r#"
// Hello World
// Hello World
// Hello World
// Hello World
// Hello World
// Hello World
// Hello World
// Hello World
// Hello World
// Hello World
"#;
let scanner = Scanner::new(black_box(text));

let mut group = c.benchmark_group("comment");
group.bench_function("old", |b| {
b.iter(|| scan(&mut scanner.clone(), scan_line_comment_old));
});
group.bench_function("new", |b| {
b.iter(|| scan(&mut scanner.clone(), scan_line_comment_new));
});
group.finish();
}

criterion_group!(benches, bench_accept_vs_test);
criterion_main!(benches);
9 changes: 6 additions & 3 deletions text-scanner/src/ext/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ pub trait CScannerExt<'text>: crate::private::Sealed {

impl<'text> CScannerExt<'text> for Scanner<'text> {
// Reference: https://learn.microsoft.com/en-us/cpp/c-language/c-comments?view=msvc-170
#[inline]
fn scan_c_line_comment(&mut self) -> ScannerResult<'text, &'text str> {
self.scan_with(|scanner| {
scanner.accept_str("//")?;
scanner.skip_until_char_any(&['\n', '\r']);
scanner.test_str("//")?;
_ = scanner.next_line();
Ok(())
})
}
Expand Down Expand Up @@ -180,8 +181,10 @@ mod tests {
("// Line Comment\n", Ok((0..15, "// Line Comment")), "\n"),
("// Line Comment\r\n", Ok((0..15, "// Line Comment")), "\r\n"),
//
("// Foo\rBar\r\n", Ok((0..10, "// Foo\rBar")), "\r\n"),
//
("", Err((0..0, "")), ""),
("/", Err((0..1, "/")), "/"),
// ("/", Err((0..1, "/")), "/"),
(" //", Err((0..0, "")), " //"),
];

Expand Down
2 changes: 1 addition & 1 deletion text-scanner/src/ext/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl<'text> PythonScannerExt<'text> for Scanner<'text> {
fn scan_python_line_comment(&mut self) -> ScannerResult<'text, &'text str> {
self.scan_with(|scanner| {
scanner.accept_char('#')?;
scanner.skip_until_char_any(&['\n', '\r']);
_ = scanner.next_line();
Ok(())
})
}
Expand Down
5 changes: 3 additions & 2 deletions text-scanner/src/ext/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,10 +535,11 @@ pub trait RustScannerExt<'text>: crate::private::Sealed {

impl<'text> RustScannerExt<'text> for Scanner<'text> {
// Reference: https://doc.rust-lang.org/reference/comments.html
#[inline]
fn scan_rust_line_comment(&mut self) -> ScannerResult<'text, &'text str> {
self.scan_with(|scanner| {
scanner.accept_str("//")?;
scanner.skip_until_char_any(&['\n', '\r']);
scanner.test_str("//")?;
_ = scanner.next_line();
Ok(())
})
}
Expand Down

0 comments on commit c48da03

Please sign in to comment.