Start parsing formulas
This commit is contained in:
		@@ -1,11 +1,12 @@
 | 
				
			|||||||
 | 
					mod formulas;
 | 
				
			||||||
mod helpers;
 | 
					mod helpers;
 | 
				
			||||||
mod names;
 | 
					mod names;
 | 
				
			||||||
mod terms;
 | 
					mod terms;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) use helpers::word_boundary;
 | 
					pub(crate) use helpers::word_boundary;
 | 
				
			||||||
pub use names::{function_or_predicate_name, variable_name};
 | 
					pub use names::{function_or_predicate_name, variable_name};
 | 
				
			||||||
pub use terms::{boolean, function, integer, predicate, special_integer, string, term, variable,
 | 
					pub use terms::term;
 | 
				
			||||||
	variable_declaration};
 | 
					//pub use formulas::formula;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Declarations
 | 
					pub struct Declarations
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										260
									
								
								src/parse/formulas.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								src/parse/formulas.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
				
			|||||||
 | 
					use nom::
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						IResult,
 | 
				
			||||||
 | 
						branch::alt,
 | 
				
			||||||
 | 
						bytes::complete::{escaped_transform, tag},
 | 
				
			||||||
 | 
						character::complete::{digit1, multispace0, none_of},
 | 
				
			||||||
 | 
						combinator::{map, map_res, opt, recognize},
 | 
				
			||||||
 | 
						multi::{many1, separated_list},
 | 
				
			||||||
 | 
						sequence::{delimited, pair, preceded, terminated},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::{Declarations, function_or_predicate_name, word_boundary, variable_name};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: avoid code duplication
 | 
				
			||||||
 | 
					fn true_(i: &str) -> IResult<&str, crate::Formula>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						map
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							terminated
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								tag("true"),
 | 
				
			||||||
 | 
								word_boundary,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|_| crate::Formula::true_(),
 | 
				
			||||||
 | 
						)(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn false_(i: &str) -> IResult<&str, crate::Formula>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						map
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							terminated
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								tag("false"),
 | 
				
			||||||
 | 
								word_boundary,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|_| crate::Formula::false_(),
 | 
				
			||||||
 | 
						)(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn boolean(i: &str) -> IResult<&str, crate::Formula>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						alt
 | 
				
			||||||
 | 
						((
 | 
				
			||||||
 | 
							true_,
 | 
				
			||||||
 | 
							false_,
 | 
				
			||||||
 | 
						))(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*fn formula_parenthesized<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Formula>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						delimited
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							terminated
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								tag("("),
 | 
				
			||||||
 | 
								multispace0,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|i| formula(i, d),
 | 
				
			||||||
 | 
							preceded
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								multispace0,
 | 
				
			||||||
 | 
								tag(")"),
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
						)(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn term_precedence_0<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Term>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						alt
 | 
				
			||||||
 | 
						((
 | 
				
			||||||
 | 
							boolean,
 | 
				
			||||||
 | 
							special_integer,
 | 
				
			||||||
 | 
							integer,
 | 
				
			||||||
 | 
							map
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								|i| function(i, d),
 | 
				
			||||||
 | 
								crate::Term::Function,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							string,
 | 
				
			||||||
 | 
							map
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								|i| variable(i, d),
 | 
				
			||||||
 | 
								crate::Term::Variable,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|i| absolute_value(i, d),
 | 
				
			||||||
 | 
							|i| term_parenthesized(i, d),
 | 
				
			||||||
 | 
						))(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn term_precedence_1<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Term>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						alt
 | 
				
			||||||
 | 
						((
 | 
				
			||||||
 | 
							|i| negative(i, d),
 | 
				
			||||||
 | 
							|i| term_precedence_0(i, d),
 | 
				
			||||||
 | 
						))(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn term_precedence_2<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Term>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						alt
 | 
				
			||||||
 | 
						((
 | 
				
			||||||
 | 
							map
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								pair
 | 
				
			||||||
 | 
								(
 | 
				
			||||||
 | 
									many1
 | 
				
			||||||
 | 
									(
 | 
				
			||||||
 | 
										terminated
 | 
				
			||||||
 | 
										(
 | 
				
			||||||
 | 
											|i| term_precedence_1(i, d),
 | 
				
			||||||
 | 
											delimited
 | 
				
			||||||
 | 
											(
 | 
				
			||||||
 | 
												multispace0,
 | 
				
			||||||
 | 
												tag("**"),
 | 
				
			||||||
 | 
												multispace0,
 | 
				
			||||||
 | 
											),
 | 
				
			||||||
 | 
										)
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
 | 
									|i| term_precedence_1(i, d),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								|(arguments, last_argument)| arguments.into_iter().rev().fold(last_argument,
 | 
				
			||||||
 | 
									|accumulator, argument|
 | 
				
			||||||
 | 
										crate::Term::exponentiate(Box::new(argument), Box::new(accumulator))),
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|i| term_precedence_1(i, d),
 | 
				
			||||||
 | 
						))(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn term_precedence_3<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Term>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						alt
 | 
				
			||||||
 | 
						((
 | 
				
			||||||
 | 
							map
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								pair
 | 
				
			||||||
 | 
								(
 | 
				
			||||||
 | 
									|i| term_precedence_2(i, d),
 | 
				
			||||||
 | 
									many1
 | 
				
			||||||
 | 
									(
 | 
				
			||||||
 | 
										pair
 | 
				
			||||||
 | 
										(
 | 
				
			||||||
 | 
											delimited
 | 
				
			||||||
 | 
											(
 | 
				
			||||||
 | 
												multispace0,
 | 
				
			||||||
 | 
												alt
 | 
				
			||||||
 | 
												((
 | 
				
			||||||
 | 
													tag("*"),
 | 
				
			||||||
 | 
													tag("/"),
 | 
				
			||||||
 | 
													tag("%"),
 | 
				
			||||||
 | 
												)),
 | 
				
			||||||
 | 
												multispace0,
 | 
				
			||||||
 | 
											),
 | 
				
			||||||
 | 
											|i| term_precedence_2(i, d),
 | 
				
			||||||
 | 
										)
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								|(first_argument, arguments)| arguments.into_iter().fold(first_argument,
 | 
				
			||||||
 | 
									|accumulator, (operator, argument)|
 | 
				
			||||||
 | 
									match operator
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"*" => crate::Term::multiply(Box::new(accumulator), Box::new(argument)),
 | 
				
			||||||
 | 
										"/" => crate::Term::divide(Box::new(accumulator), Box::new(argument)),
 | 
				
			||||||
 | 
										"%" => crate::Term::modulo(Box::new(accumulator), Box::new(argument)),
 | 
				
			||||||
 | 
										// TODO: handle appropriately
 | 
				
			||||||
 | 
										_ => panic!("test"),
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|i| term_precedence_2(i, d),
 | 
				
			||||||
 | 
						))(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn term_precedence_4<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Term>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						alt
 | 
				
			||||||
 | 
						((
 | 
				
			||||||
 | 
							map
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								pair
 | 
				
			||||||
 | 
								(
 | 
				
			||||||
 | 
									|i| term_precedence_3(i, d),
 | 
				
			||||||
 | 
									many1
 | 
				
			||||||
 | 
									(
 | 
				
			||||||
 | 
										pair
 | 
				
			||||||
 | 
										(
 | 
				
			||||||
 | 
											delimited
 | 
				
			||||||
 | 
											(
 | 
				
			||||||
 | 
												multispace0,
 | 
				
			||||||
 | 
												alt
 | 
				
			||||||
 | 
												((
 | 
				
			||||||
 | 
													tag("+"),
 | 
				
			||||||
 | 
													tag("-"),
 | 
				
			||||||
 | 
												)),
 | 
				
			||||||
 | 
												multispace0,
 | 
				
			||||||
 | 
											),
 | 
				
			||||||
 | 
											|i| term_precedence_3(i, d),
 | 
				
			||||||
 | 
										)
 | 
				
			||||||
 | 
									),
 | 
				
			||||||
 | 
								),
 | 
				
			||||||
 | 
								|(first_argument, arguments)| arguments.into_iter().fold(first_argument,
 | 
				
			||||||
 | 
									|accumulator, (operator, argument)|
 | 
				
			||||||
 | 
									match operator
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"+" => crate::Term::add(Box::new(accumulator), Box::new(argument)),
 | 
				
			||||||
 | 
										"-" => crate::Term::subtract(Box::new(accumulator), Box::new(argument)),
 | 
				
			||||||
 | 
										// TODO: handle appropriately
 | 
				
			||||||
 | 
										_ => panic!("test"),
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|i| term_precedence_3(i, d),
 | 
				
			||||||
 | 
						))(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn formula<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Formula>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						formula_precedence_4(i, d)
 | 
				
			||||||
 | 
					}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod tests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						use crate::parse::formulas::*;
 | 
				
			||||||
 | 
						use crate::{Formula, VariableDeclaration, VariableDeclarationStack};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*fn formula(i: &str) -> Formula
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							crate::parse::formula(i, &Declarations::new()).unwrap().1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn format_formula(i: &str) -> String
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							format!("{}", formula(i))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#[test]
 | 
				
			||||||
 | 
						fn parse_formula_boolean()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							assert_eq!(formula("true"), Formula::true_());
 | 
				
			||||||
 | 
							assert_eq!(formula("false"), Formula::false_());
 | 
				
			||||||
 | 
						}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#[test]
 | 
				
			||||||
 | 
						fn parse_boolean()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							assert_eq!(boolean("true"), Ok(("", Formula::true_())));
 | 
				
			||||||
 | 
							assert_eq!(boolean("false"), Ok(("", Formula::false_())));
 | 
				
			||||||
 | 
							assert_eq!(boolean("true false"), Ok((" false", Formula::true_())));
 | 
				
			||||||
 | 
							assert_eq!(boolean("false true"), Ok((" true", Formula::false_())));
 | 
				
			||||||
 | 
							assert_eq!(boolean("true,"), Ok((",", Formula::true_())));
 | 
				
			||||||
 | 
							assert_eq!(boolean("false,"), Ok((",", Formula::false_())));
 | 
				
			||||||
 | 
							assert!(boolean("truefalse").is_err());
 | 
				
			||||||
 | 
							assert!(boolean("falsetrue").is_err());
 | 
				
			||||||
 | 
							assert!(boolean("truea").is_err());
 | 
				
			||||||
 | 
							assert!(boolean("falsea").is_err());
 | 
				
			||||||
 | 
							assert!(boolean("a").is_err());
 | 
				
			||||||
 | 
							assert!(boolean("-").is_err());
 | 
				
			||||||
 | 
							assert!(boolean(" ").is_err());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -11,32 +11,6 @@ use nom::
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use super::{Declarations, function_or_predicate_name, word_boundary, variable_name};
 | 
					use super::{Declarations, function_or_predicate_name, word_boundary, variable_name};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn true_(i: &str) -> IResult<&str, crate::Term>
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	map
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
		terminated
 | 
					 | 
				
			||||||
		(
 | 
					 | 
				
			||||||
			tag("true"),
 | 
					 | 
				
			||||||
			word_boundary,
 | 
					 | 
				
			||||||
		),
 | 
					 | 
				
			||||||
		|_| crate::Term::true_(),
 | 
					 | 
				
			||||||
	)(i)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn false_(i: &str) -> IResult<&str, crate::Term>
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	map
 | 
					 | 
				
			||||||
	(
 | 
					 | 
				
			||||||
		terminated
 | 
					 | 
				
			||||||
		(
 | 
					 | 
				
			||||||
			tag("false"),
 | 
					 | 
				
			||||||
			word_boundary,
 | 
					 | 
				
			||||||
		),
 | 
					 | 
				
			||||||
		|_| crate::Term::false_(),
 | 
					 | 
				
			||||||
	)(i)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn negative<'i>(i: &'i str, d: &Declarations) -> IResult<&'i str, crate::Term>
 | 
					fn negative<'i>(i: &'i str, d: &Declarations) -> IResult<&'i str, crate::Term>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	map
 | 
						map
 | 
				
			||||||
@@ -83,6 +57,32 @@ fn absolute_value<'i>(i: &'i str, d: &Declarations) -> IResult<&'i str, crate::T
 | 
				
			|||||||
	)(i)
 | 
						)(i)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn true_(i: &str) -> IResult<&str, crate::Term>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						map
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							terminated
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								tag("true"),
 | 
				
			||||||
 | 
								word_boundary,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|_| crate::Term::true_(),
 | 
				
			||||||
 | 
						)(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn false_(i: &str) -> IResult<&str, crate::Term>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						map
 | 
				
			||||||
 | 
						(
 | 
				
			||||||
 | 
							terminated
 | 
				
			||||||
 | 
							(
 | 
				
			||||||
 | 
								tag("false"),
 | 
				
			||||||
 | 
								word_boundary,
 | 
				
			||||||
 | 
							),
 | 
				
			||||||
 | 
							|_| crate::Term::false_(),
 | 
				
			||||||
 | 
						)(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn boolean(i: &str) -> IResult<&str, crate::Term>
 | 
					pub fn boolean(i: &str) -> IResult<&str, crate::Term>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	alt
 | 
						alt
 | 
				
			||||||
@@ -511,7 +511,7 @@ pub fn term<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Term>
 | 
				
			|||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
mod tests
 | 
					mod tests
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	use crate::parse::*;
 | 
						use crate::parse::terms::*;
 | 
				
			||||||
	use crate::{Term, VariableDeclaration, VariableDeclarationStack};
 | 
						use crate::{Term, VariableDeclaration, VariableDeclarationStack};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn term(i: &str) -> Term
 | 
						fn term(i: &str) -> Term
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user