Start parsing formulas

This commit is contained in:
Patrick Lühne 2020-03-13 22:58:53 +01:00
parent af1ec8a606
commit 1b89d8900e
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
3 changed files with 290 additions and 29 deletions

View File

@ -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
View 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());
}
}

View File

@ -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