summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/input.rs26
-rw-r--r--src/lib.rs76
-rw-r--r--tests/sexpr.rs14
3 files changed, 109 insertions, 7 deletions
diff --git a/src/input.rs b/src/input.rs
index 0857c8c..0b38556 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -48,22 +48,44 @@ impl<'a> Input for &'a [u8] {
}
pub trait Character {
+ fn is_ascii(&self) -> bool;
+
fn is_alphabetic(&self) -> bool;
+ fn is_ascii_alphabetic(&self) -> bool;
+
fn is_numeric(&self) -> bool;
+ fn is_ascii_numeric(&self) -> bool {
+ self.is_ascii() && self.is_numeric()
+ }
+
fn is_whitespace(&self) -> bool;
+ fn is_ascii_whitespace(&self) -> bool;
+
fn is_alphanumeric(&self) -> bool {
self.is_alphabetic() || self.is_numeric()
}
+
+ fn is_ascii_alphanumeric(&self) -> bool {
+ self.is_ascii_alphabetic() || self.is_ascii_numeric()
+ }
}
impl Character for char {
+ fn is_ascii(&self) -> bool {
+ (*self).is_ascii()
+ }
+
fn is_alphabetic(&self) -> bool {
(*self).is_ascii_alphabetic()
}
+ fn is_ascii_alphabetic(&self) -> bool {
+ (*self).is_ascii_alphabetic()
+ }
+
fn is_numeric(&self) -> bool {
(*self).is_numeric()
}
@@ -71,6 +93,10 @@ impl Character for char {
fn is_whitespace(&self) -> bool {
(*self).is_whitespace()
}
+
+ fn is_ascii_whitespace(&self) -> bool {
+ (*self).is_ascii_whitespace()
+ }
}
#[derive(Clone)]
diff --git a/src/lib.rs b/src/lib.rs
index fe9a720..5d6c3d3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -965,6 +965,14 @@ where
r#if(|c: &I::Item| c.is_alphabetic())
}
+pub fn ascii_alpha<I>() -> impl Parser<I, Output = I::Item>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii_alphabetic())
+}
+
pub fn alpha1<I>() -> impl Parser<I, Output = I>
where
I: Input,
@@ -976,6 +984,17 @@ where
.recognize()
}
+pub fn ascii_alpha1<I>() -> impl Parser<I, Output = I>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii_alphabetic())
+ .repeated()
+ .at_least(1)
+ .recognize()
+}
+
pub fn numeric<I>() -> impl Parser<I, Output = I::Item>
where
I: Input,
@@ -984,6 +1003,14 @@ where
r#if(|c: &I::Item| c.is_numeric())
}
+pub fn ascii_numeric<I>() -> impl Parser<I, Output = I::Item>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii() && c.is_numeric())
+}
+
pub fn numeric1<I>() -> impl Parser<I, Output = I>
where
I: Input,
@@ -995,6 +1022,17 @@ where
.recognize()
}
+pub fn ascii_numeric1<I>() -> impl Parser<I, Output = I>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii() && c.is_numeric())
+ .repeated()
+ .at_least(1)
+ .recognize()
+}
+
pub fn alphanumeric<I>() -> impl Parser<I, Output = I::Item>
where
I: Input,
@@ -1003,6 +1041,14 @@ where
r#if(|c: &I::Item| c.is_alphanumeric())
}
+pub fn ascii_alphanumeric<I>() -> impl Parser<I, Output = I::Item>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii_alphanumeric())
+}
+
pub fn alphanumeric1<I>() -> impl Parser<I, Output = I>
where
I: Input,
@@ -1014,6 +1060,17 @@ where
.recognize()
}
+pub fn ascii_alphanumeric1<I>() -> impl Parser<I, Output = I>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii_alphanumeric())
+ .repeated()
+ .at_least(1)
+ .recognize()
+}
+
pub fn whitespace<I>() -> impl Parser<I, Output = I::Item>
where
I: Input,
@@ -1022,6 +1079,14 @@ where
r#if(|c: &I::Item| c.is_whitespace())
}
+pub fn ascii_whitespace<I>() -> impl Parser<I, Output = I::Item>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii_whitespace())
+}
+
pub fn whitespace1<I>() -> impl Parser<I, Output = I>
where
I: Input,
@@ -1033,6 +1098,17 @@ where
.recognize()
}
+pub fn ascii_whitespace1<I>() -> impl Parser<I, Output = I>
+where
+ I: Input,
+ I::Item: Character,
+{
+ r#if(|c: &I::Item| c.is_ascii_whitespace())
+ .repeated()
+ .at_least(1)
+ .recognize()
+}
+
pub fn any<I>() -> impl Parser<I, Output = I::Item>
where
I: Input,
diff --git a/tests/sexpr.rs b/tests/sexpr.rs
index 77ef3a0..a3783f0 100644
--- a/tests/sexpr.rs
+++ b/tests/sexpr.rs
@@ -1,8 +1,8 @@
#![allow(dead_code)]
use mon::{
- Parser, ParserIter, alpha1, alphanumeric, alphanumeric1, input::InputIter, numeric1, tag,
- whitespace, whitespace1,
+ Parser, ParserIter, ascii_alpha1, ascii_alphanumeric, ascii_alphanumeric1, ascii_numeric1,
+ ascii_whitespace1, input::InputIter, tag,
};
#[derive(Debug)]
@@ -14,20 +14,20 @@ enum Sexpr {
}
fn atom<'a>() -> impl Parser<&'a str, Output = Sexpr> {
- alpha1()
- .and(alphanumeric().repeated().many())
+ ascii_alpha1()
+ .and(ascii_alphanumeric().repeated().many())
.recognize()
.map(|output: &str| Sexpr::Atom(output.to_string()))
}
fn string<'a>() -> impl Parser<&'a str, Output = Sexpr> {
- alphanumeric1()
+ ascii_alphanumeric1()
.delimited_by(tag("\""), tag("\""))
.map(|output: &str| Sexpr::String(output.to_string()))
}
fn int<'a>() -> impl Parser<&'a str, Output = Sexpr> {
- numeric1().map(|output: &str| Sexpr::Int(output.parse().unwrap()))
+ ascii_numeric1().map(|output: &str| Sexpr::Int(output.parse().unwrap()))
}
// Recursive parsers must avoid an infinite loop, you can do this
@@ -35,7 +35,7 @@ fn int<'a>() -> impl Parser<&'a str, Output = Sexpr> {
fn sexpr<'a>() -> impl Parser<&'a str, Output = Sexpr> {
|it| {
sexpr()
- .separated_by(whitespace1())
+ .separated_by(ascii_whitespace1())
.many()
.delimited_by(tag("("), tag(")"))
.map(|output| Sexpr::List(output))