Revise trait Rule to return bool
This commit is contained in:
+40
-45
@@ -1,7 +1,5 @@
|
|||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
|
|
||||||
use anyhow::{Result, bail};
|
|
||||||
|
|
||||||
// TODO: Add offsets
|
// TODO: Add offsets
|
||||||
pub enum Tag {
|
pub enum Tag {
|
||||||
Open(&'static str),
|
Open(&'static str),
|
||||||
@@ -42,7 +40,7 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Rule {
|
pub trait Rule {
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()>;
|
fn parse(&self, p: &mut Parser) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Ref<T>(pub T);
|
pub struct Ref<T>(pub T);
|
||||||
@@ -51,7 +49,7 @@ impl<T> Rule for Ref<&T>
|
|||||||
where
|
where
|
||||||
T: Rule,
|
T: Rule,
|
||||||
{
|
{
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
self.0.parse(p)
|
self.0.parse(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,51 +59,50 @@ where
|
|||||||
R: Rule,
|
R: Rule,
|
||||||
F: Fn() -> R,
|
F: Fn() -> R,
|
||||||
{
|
{
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
self().parse(p)
|
self().parse(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rule for &str {
|
impl Rule for &str {
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
if p.input[p.offset..].starts_with(self) {
|
if p.input[p.offset..].starts_with(self) {
|
||||||
p.offset += self.len();
|
p.offset += self.len();
|
||||||
Ok(())
|
true
|
||||||
} else {
|
} else {
|
||||||
bail!("No match")
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rule for RangeInclusive<char> {
|
impl Rule for RangeInclusive<char> {
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
if let Some(c) = p.input[p.offset..].chars().next() {
|
if let Some(c) = p.input[p.offset..].chars().next() {
|
||||||
if self.contains(&c) {
|
if self.contains(&c) {
|
||||||
p.offset += c.len_utf8();
|
p.offset += c.len_utf8();
|
||||||
return Ok(());
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bail!("No match")
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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),+, {
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
let save = p.save();
|
let save = p.save();
|
||||||
let mut lambda = || {
|
let mut lambda = || {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let ($($x),+,) = self;
|
let ($($x),+,) = self;
|
||||||
$($x.parse(p)?;)+
|
$(if !$x.parse(p) {return false; })+
|
||||||
Ok(())
|
true
|
||||||
};
|
};
|
||||||
match lambda() {
|
if lambda() {
|
||||||
Ok(x) => Ok(x),
|
true
|
||||||
Err(e) => {
|
} else {
|
||||||
p.restore(save);
|
p.restore(save);
|
||||||
Err(e)
|
false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -117,17 +114,17 @@ pub struct Alt<T>(pub T);
|
|||||||
macro_rules! impl_rule_for_alt {
|
macro_rules! impl_rule_for_alt {
|
||||||
($($x:ident)+) => {
|
($($x:ident)+) => {
|
||||||
impl<$($x),+> Rule for Alt<($($x),+,)> where $($x: Rule),+ {
|
impl<$($x),+> Rule for Alt<($($x),+,)> where $($x: Rule),+ {
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
let save = p.save();
|
let save = p.save();
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let ($($x),+,) = &self.0;
|
let ($($x),+,) = &self.0;
|
||||||
$(
|
$(
|
||||||
if $x.parse(p).is_ok() {
|
if $x.parse(p) {
|
||||||
return Ok(())
|
return true
|
||||||
}
|
}
|
||||||
p.restore(save);
|
p.restore(save);
|
||||||
)+
|
)+
|
||||||
bail!("No match")
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -139,23 +136,23 @@ impl<T> Rule for And<T>
|
|||||||
where
|
where
|
||||||
T: Rule,
|
T: Rule,
|
||||||
{
|
{
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
let save = p.save();
|
let save = p.save();
|
||||||
self.0.parse(p)?;
|
let result = self.0.parse(p);
|
||||||
p.restore(save);
|
p.restore(save);
|
||||||
Ok(())
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Dot;
|
pub struct Dot;
|
||||||
|
|
||||||
impl Rule for Dot {
|
impl Rule for Dot {
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
if let Some(c) = p.input[p.offset..].chars().next() {
|
if let Some(c) = p.input[p.offset..].chars().next() {
|
||||||
p.offset += c.len_utf8();
|
p.offset += c.len_utf8();
|
||||||
Ok(())
|
true
|
||||||
} else {
|
} else {
|
||||||
bail!("No match")
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,13 +163,14 @@ impl<T> Rule for Not<T>
|
|||||||
where
|
where
|
||||||
T: Rule,
|
T: Rule,
|
||||||
{
|
{
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
let save = p.save();
|
let save = p.save();
|
||||||
if self.0.parse(p).is_ok() {
|
if self.0.parse(p) {
|
||||||
p.restore(save);
|
p.restore(save);
|
||||||
bail!("No match");
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,9 +180,9 @@ impl<T> Rule for Opt<T>
|
|||||||
where
|
where
|
||||||
T: Rule,
|
T: Rule,
|
||||||
{
|
{
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
let _ = self.0.parse(p);
|
let _ = self.0.parse(p);
|
||||||
Ok(())
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,9 +192,9 @@ impl<T> Rule for Star<T>
|
|||||||
where
|
where
|
||||||
T: Rule,
|
T: Rule,
|
||||||
{
|
{
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
while self.0.parse(p).is_ok() {}
|
while self.0.parse(p) {}
|
||||||
Ok(())
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,11 +210,8 @@ macro_rules! star {
|
|||||||
pub struct EOF;
|
pub struct EOF;
|
||||||
|
|
||||||
impl Rule for EOF {
|
impl Rule for EOF {
|
||||||
fn parse(&self, p: &mut Parser) -> Result<()> {
|
fn parse(&self, p: &mut Parser) -> bool {
|
||||||
if p.offset < p.input.len() {
|
p.offset >= p.input.len()
|
||||||
bail!("No match");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,13 +232,13 @@ mod test {
|
|||||||
fn parse<T: Rule>(rule: &T, input: &str) {
|
fn parse<T: Rule>(rule: &T, input: &str) {
|
||||||
let mut p = Parser::new(input);
|
let mut p = Parser::new(input);
|
||||||
let rule = (Ref(rule), EOF);
|
let rule = (Ref(rule), EOF);
|
||||||
assert!(rule.parse(&mut p).is_ok());
|
assert!(rule.parse(&mut p));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_err<T: Rule>(rule: &T, input: &str) {
|
fn parse_err<T: Rule>(rule: &T, input: &str) {
|
||||||
let mut p = Parser::new(input);
|
let mut p = Parser::new(input);
|
||||||
let rule = (Ref(rule), EOF);
|
let rule = (Ref(rule), EOF);
|
||||||
assert!(rule.parse(&mut p).is_err());
|
assert!(!rule.parse(&mut p));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user