Start parsing formulas
This commit is contained in:
		@@ -1,11 +1,12 @@
 | 
			
		||||
mod formulas;
 | 
			
		||||
mod helpers;
 | 
			
		||||
mod names;
 | 
			
		||||
mod terms;
 | 
			
		||||
 | 
			
		||||
pub(crate) use helpers::word_boundary;
 | 
			
		||||
pub use names::{function_or_predicate_name, variable_name};
 | 
			
		||||
pub use terms::{boolean, function, integer, predicate, special_integer, string, term, variable,
 | 
			
		||||
	variable_declaration};
 | 
			
		||||
pub use terms::term;
 | 
			
		||||
//pub use formulas::formula;
 | 
			
		||||
 | 
			
		||||
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};
 | 
			
		||||
 | 
			
		||||
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>
 | 
			
		||||
{
 | 
			
		||||
	map
 | 
			
		||||
@@ -83,6 +57,32 @@ fn absolute_value<'i>(i: &'i str, d: &Declarations) -> IResult<&'i str, crate::T
 | 
			
		||||
	)(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>
 | 
			
		||||
{
 | 
			
		||||
	alt
 | 
			
		||||
@@ -511,7 +511,7 @@ pub fn term<'a>(i: &'a str, d: &Declarations) -> IResult<&'a str, crate::Term>
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests
 | 
			
		||||
{
 | 
			
		||||
	use crate::parse::*;
 | 
			
		||||
	use crate::parse::terms::*;
 | 
			
		||||
	use crate::{Term, VariableDeclaration, VariableDeclarationStack};
 | 
			
		||||
 | 
			
		||||
	fn term(i: &str) -> Term
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user