From 00430780459775a52e74736426f2f94f08fa2bb4 Mon Sep 17 00:00:00 2001 From: Chris Mounce Date: Thu, 8 May 2025 00:07:37 -0700 Subject: [PATCH] Add character ranges to PEG parser --- src/preprocess/peg.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/preprocess/peg.rs b/src/preprocess/peg.rs index 68b4226..e457808 100644 --- a/src/preprocess/peg.rs +++ b/src/preprocess/peg.rs @@ -1,3 +1,5 @@ +use std::ops::RangeInclusive; + use anyhow::{Result, anyhow, bail}; // TODO: Add offsets @@ -75,6 +77,18 @@ impl Rule for &str { } } +impl Rule for RangeInclusive { + fn parse(&self, p: &mut Parser) -> Result<()> { + if let Some(c) = p.input[p.offset..].chars().next() { + if self.contains(&c) { + p.offset += c.len_utf8(); + return Ok(()); + } + } + bail!("No match") + } +} + macro_rules! impl_rule_for_tuple { ($($x:ident)+) => { impl<$($x),+> Rule for ($($x),+,) where $($x: Rule),+, { @@ -133,7 +147,7 @@ where #[macro_export] macro_rules! star { - ($($item:tt),+ $(,)?) => { + ($($item:expr),+ $(,)?) => { Star(( $($item),+, )) @@ -171,6 +185,16 @@ mod test { rule.parse(&mut p) } + #[test] + fn test_char_range() -> Result<()> { + let num = '0'..='9'; + let rule = (Ref(&num), star!(Ref(&num))); + parse(&rule, "0")?; + parse(&rule, "123")?; + parse(&rule, "9")?; + Ok(()) + } + #[test] fn test_combinator_tuples() { let foo = ("f", "o", "o");