Implement word boundaries

This commit is contained in:
Patrick Lühne 2020-02-26 12:42:02 +01:00
parent 896af02120
commit 5ec9331b4c
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
3 changed files with 124 additions and 12 deletions

View File

@ -1,6 +1,8 @@
mod helpers;
mod names;
mod terms;
pub(crate) use helpers::word_boundary;
pub use names::{function_name, predicate_name, variable_name};
pub use terms::{integer, special_integer};

77
src/parse/helpers.rs Normal file
View File

@ -0,0 +1,77 @@
use nom::
{
IResult,
branch::alt,
bytes::complete::take_while_m_n,
combinator::{map, peek, rest_len, verify},
};
fn is_character_word_boundary(c: char) -> bool
{
if c.is_whitespace()
{
return true;
}
match c
{
'('
| ')'
| ','
| '+'
| '-'
| '*'
| '/'
| '%'
=> true,
_ => false,
}
}
pub(crate) fn word_boundary(i: &str) -> IResult<&str, ()>
{
peek
(
alt
((
// Accept word boundary characters
map
(
take_while_m_n(1, 1, is_character_word_boundary),
|_| (),
),
// Accept end of file
map
(
verify
(
rest_len,
|rest_length| *rest_length == 0usize,
),
|_| (),
),
))
)(i)
}
#[cfg(test)]
mod tests
{
use crate::parse::*;
#[test]
fn detect_word_boundaries()
{
assert_eq!(word_boundary(" rest"), Ok((" rest", ())));
assert_eq!(word_boundary("(rest"), Ok(("(rest", ())));
assert_eq!(word_boundary(")rest"), Ok((")rest", ())));
assert_eq!(word_boundary(",rest"), Ok((",rest", ())));
assert_eq!(word_boundary("+rest"), Ok(("+rest", ())));
assert_eq!(word_boundary("-rest"), Ok(("-rest", ())));
assert_eq!(word_boundary("*rest"), Ok(("*rest", ())));
assert_eq!(word_boundary("/rest"), Ok(("/rest", ())));
assert_eq!(word_boundary("%rest"), Ok(("%rest", ())));
assert!(word_boundary("0").is_err());
assert!(word_boundary("rest").is_err());
}
}

View File

@ -5,9 +5,11 @@ use nom::
bytes::complete::tag,
character::complete::digit1,
combinator::{map, map_res, opt, recognize},
sequence::pair,
sequence::{pair, terminated},
};
use super::word_boundary;
pub fn integer(i: &str) -> IResult<&str, crate::Term>
{
map
@ -16,17 +18,21 @@ pub fn integer(i: &str) -> IResult<&str, crate::Term>
(
recognize
(
pair
terminated
(
opt
pair
(
alt
((
tag("-"),
tag("+"),
))
opt
(
alt
((
tag("-"),
tag("+"),
))
),
digit1,
),
digit1,
word_boundary,
)
),
std::str::FromStr::from_str,
@ -39,7 +45,11 @@ fn infimum(i: &str) -> IResult<&str, crate::Term>
{
map
(
tag("#inf"),
terminated
(
tag("#inf"),
word_boundary,
),
|_| crate::Term::infimum(),
)(i)
}
@ -48,7 +58,11 @@ fn supremum(i: &str) -> IResult<&str, crate::Term>
{
map
(
tag("#sup"),
terminated
(
tag("#sup"),
word_boundary,
),
|_| crate::Term::supremum(),
)(i)
}
@ -148,8 +162,19 @@ mod tests
{
assert_eq!(integer("0"), Ok(("", crate::Term::integer(0))));
assert_eq!(integer("10000"), Ok(("", crate::Term::integer(10000))));
assert_eq!(integer("+10000"), Ok(("", crate::Term::integer(10000))));
assert_eq!(integer("-10000"), Ok(("", crate::Term::integer(-10000))));
assert_eq!(integer("1.5"), Ok((".5", crate::Term::integer(1))));
assert_eq!(integer("0 42"), Ok((" 42", crate::Term::integer(0))));
assert_eq!(integer("10000 42"), Ok((" 42", crate::Term::integer(10000))));
assert_eq!(integer("+10000 42"), Ok((" 42", crate::Term::integer(10000))));
assert_eq!(integer("-10000 42"), Ok((" 42", crate::Term::integer(-10000))));
assert_eq!(integer("10000("), Ok(("(", crate::Term::integer(10000))));
assert_eq!(integer("+10000("), Ok(("(", crate::Term::integer(10000))));
assert_eq!(integer("-10000("), Ok(("(", crate::Term::integer(-10000))));
assert!(integer("10000a").is_err());
assert!(integer("+10000a").is_err());
assert!(integer("-10000a").is_err());
assert!(integer("1.5").is_err());
assert!(integer("a").is_err());
assert!(integer("-").is_err());
assert!(integer(" ").is_err());
@ -160,6 +185,14 @@ mod tests
{
assert_eq!(special_integer("#inf"), Ok(("", crate::Term::infimum())));
assert_eq!(special_integer("#sup"), Ok(("", crate::Term::supremum())));
assert_eq!(special_integer("#inf #sup"), Ok((" #sup", crate::Term::infimum())));
assert_eq!(special_integer("#sup #inf"), Ok((" #inf", crate::Term::supremum())));
assert_eq!(special_integer("#inf("), Ok(("(", crate::Term::infimum())));
assert_eq!(special_integer("#sup("), Ok(("(", crate::Term::supremum())));
assert!(special_integer("#inf0").is_err());
assert!(special_integer("#sup0").is_err());
assert!(special_integer("#infimum").is_err());
assert!(special_integer("#supremum").is_err());
assert!(special_integer("inf").is_err());
assert!(special_integer("sup").is_err());
assert!(special_integer("0").is_err());