Add character ranges to PEG parser

This commit is contained in:
2025-05-08 00:07:37 -07:00
parent e2eebc62ba
commit 0043078045
+25 -1
View File
@@ -1,3 +1,5 @@
use std::ops::RangeInclusive;
use anyhow::{Result, anyhow, bail}; use anyhow::{Result, anyhow, bail};
// TODO: Add offsets // TODO: Add offsets
@@ -75,6 +77,18 @@ impl Rule for &str {
} }
} }
impl Rule for RangeInclusive<char> {
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 { macro_rules! impl_rule_for_tuple {
($($x:ident)+) => { ($($x:ident)+) => {
impl<$($x),+> Rule for ($($x),+,) where $($x: Rule),+, { impl<$($x),+> Rule for ($($x),+,) where $($x: Rule),+, {
@@ -133,7 +147,7 @@ where
#[macro_export] #[macro_export]
macro_rules! star { macro_rules! star {
($($item:tt),+ $(,)?) => { ($($item:expr),+ $(,)?) => {
Star(( Star((
$($item),+, $($item),+,
)) ))
@@ -171,6 +185,16 @@ mod test {
rule.parse(&mut p) 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] #[test]
fn test_combinator_tuples() { fn test_combinator_tuples() {
let foo = ("f", "o", "o"); let foo = ("f", "o", "o");