From d5cd179a2dc3161ce6e9a7195b1b6d60c47d77cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 26 Feb 2020 13:56:19 +0100 Subject: [PATCH] Implement strings --- src/parse.rs | 2 +- src/parse/terms.rs | 100 ++++++++++++++++++++++++++++++++------------- 2 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/parse.rs b/src/parse.rs index f0f8ca1..4783197 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -4,7 +4,7 @@ mod terms; pub(crate) use helpers::word_boundary; pub use names::{function_name, predicate_name, variable_name}; -pub use terms::{integer, special_integer}; +pub use terms::{integer, special_integer, string}; /* use nom:: diff --git a/src/parse/terms.rs b/src/parse/terms.rs index 2fa2b36..a3003dd 100644 --- a/src/parse/terms.rs +++ b/src/parse/terms.rs @@ -2,10 +2,10 @@ use nom:: { IResult, branch::alt, - bytes::complete::tag, - character::complete::digit1, + bytes::complete::{escaped_transform, tag}, + character::complete::{digit1, none_of}, combinator::{map, map_res, opt, recognize}, - sequence::{pair, terminated}, + sequence::{delimited, pair, terminated}, }; use super::word_boundary; @@ -76,27 +76,44 @@ pub fn special_integer(i: &str) -> IResult<&str, crate::Term> ))(i) } -/* -fn string<'a>(i: &'a str, declarations: &Declarations) -> IResult<&'a str, crate::Term> +pub fn string(i: &str) -> IResult<&str, crate::Term> { map ( - delimited + terminated ( - multispace0, delimited ( tag("\""), - is_not("\""), + escaped_transform + ( + none_of("\"\\"), + '\\', + alt + (( + tag("\""), + tag("\\"), + map + ( + tag("n"), + |_| "\n", + ), + map + ( + tag("t"), + |_| "\t", + ), + )), + ), tag("\""), ), - multispace0 + word_boundary, ), - |s: &str| crate::Term::String(s.to_string()) + crate::Term::string, )(i) } - +/* fn function<'a>(i: &'a str, declarations: &Declarations) -> IResult<&'a str, crate::Formula> { alt @@ -156,21 +173,22 @@ fn function_n_ary<'a>(i: &'a str, declarations: &Declarations) -> IResult<&'a st mod tests { use crate::parse::*; + use crate::Term; #[test] fn parse_integer() { - 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("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_eq!(integer("0"), Ok(("", Term::integer(0)))); + assert_eq!(integer("10000"), Ok(("", Term::integer(10000)))); + assert_eq!(integer("+10000"), Ok(("", Term::integer(10000)))); + assert_eq!(integer("-10000"), Ok(("", Term::integer(-10000)))); + assert_eq!(integer("0 42"), Ok((" 42", Term::integer(0)))); + assert_eq!(integer("10000 42"), Ok((" 42", Term::integer(10000)))); + assert_eq!(integer("+10000 42"), Ok((" 42", Term::integer(10000)))); + assert_eq!(integer("-10000 42"), Ok((" 42", Term::integer(-10000)))); + assert_eq!(integer("10000,"), Ok((",", Term::integer(10000)))); + assert_eq!(integer("+10000,"), Ok((",", Term::integer(10000)))); + assert_eq!(integer("-10000,"), Ok((",", Term::integer(-10000)))); assert!(integer("10000a").is_err()); assert!(integer("+10000a").is_err()); assert!(integer("-10000a").is_err()); @@ -183,12 +201,12 @@ mod tests #[test] fn parse_special_integer() { - 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_eq!(special_integer("#inf"), Ok(("", Term::infimum()))); + assert_eq!(special_integer("#sup"), Ok(("", Term::supremum()))); + assert_eq!(special_integer("#inf #sup"), Ok((" #sup", Term::infimum()))); + assert_eq!(special_integer("#sup #inf"), Ok((" #inf", Term::supremum()))); + assert_eq!(special_integer("#inf,"), Ok((",", Term::infimum()))); + assert_eq!(special_integer("#sup,"), Ok((",", Term::supremum()))); assert!(special_integer("#inf0").is_err()); assert!(special_integer("#sup0").is_err()); assert!(special_integer("#infimum").is_err()); @@ -200,4 +218,30 @@ mod tests assert!(special_integer("-10000").is_err()); assert!(special_integer(" ").is_err()); } + + #[test] + fn parse_string() + { + assert_eq!(string("\"test 123\""), Ok(("", Term::string("test 123".to_string())))); + assert_eq!(string("\"123 test\""), Ok(("", Term::string("123 test".to_string())))); + assert_eq!(string("\" test 123 \""), Ok(("", Term::string(" test 123 ".to_string())))); + assert_eq!(string("\"test 123\" \"rest"), Ok((" \"rest", Term::string("test 123".to_string())))); + assert_eq!(string("\"test 123\", \"rest"), Ok((", \"rest", Term::string("test 123".to_string())))); + assert_eq!(string("\"test\n123\""), Ok(("", Term::string("test\n123".to_string())))); + assert_eq!(string("\"test\\\"123\""), Ok(("", Term::string("test\"123".to_string())))); + assert_eq!(string("\"test\\\"123\\\"\""), Ok(("", Term::string("test\"123\"".to_string())))); + assert_eq!(string("\"\\\"test 123\\\"\""), Ok(("", Term::string("\"test 123\"".to_string())))); + assert_eq!(string("\"test\\\\123\""), Ok(("", Term::string("test\\123".to_string())))); + assert_eq!(string("\"test\\\\123\\\\\""), Ok(("", Term::string("test\\123\\".to_string())))); + assert_eq!(string("\"\\\\test 123\\\\\""), Ok(("", Term::string("\\test 123\\".to_string())))); + assert_eq!(string("\"test\\n123\""), Ok(("", Term::string("test\n123".to_string())))); + assert_eq!(string("\"test\\n123\\n\""), Ok(("", Term::string("test\n123\n".to_string())))); + assert_eq!(string("\"\\ntest 123\\n\""), Ok(("", Term::string("\ntest 123\n".to_string())))); + assert_eq!(string("\"test\\t123\""), Ok(("", Term::string("test\t123".to_string())))); + assert_eq!(string("\"test\\t123\\t\""), Ok(("", Term::string("test\t123\t".to_string())))); + assert_eq!(string("\"\\ttest 123\\t\""), Ok(("", Term::string("\ttest 123\t".to_string())))); + assert_eq!(string("\"test 🙂 123\""), Ok(("", Term::string("test 🙂 123".to_string())))); + assert!(string("\"test 123\"a").is_err()); + assert!(string("\"test\\i123\"").is_err()); + } }