Work in progress

This commit is contained in:
Patrick Lühne 2020-04-28 03:18:05 +02:00
parent 0fb2be4897
commit 66ac57c5b8
Signed by: patrick
GPG Key ID: 05F3611E97A70ABF
3 changed files with 56 additions and 39 deletions

View File

@ -26,7 +26,7 @@ pub enum Kind
MixedImplicationDirections(Location), MixedImplicationDirections(Location),
ExpectedVariableDeclaration, ExpectedVariableDeclaration,
UnexpectedToken, UnexpectedToken,
EmptyInput, EmptyExpression,
ExpectedLogicalConnectiveArgument(String), ExpectedLogicalConnectiveArgument(String),
MultipleComparisonOperators(crate::ComparisonOperator, crate::ComparisonOperator), MultipleComparisonOperators(crate::ComparisonOperator, crate::ComparisonOperator),
} }
@ -89,9 +89,9 @@ impl Error
Self::new(Kind::UnexpectedToken, location) Self::new(Kind::UnexpectedToken, location)
} }
pub(crate) fn new_empty_input(location: Location) -> Self pub(crate) fn new_empty_expression(location: Location) -> Self
{ {
Self::new(Kind::EmptyInput, location) Self::new(Kind::EmptyExpression, location)
} }
pub(crate) fn new_expected_logical_connective_argument(logical_connective_name: String, pub(crate) fn new_expected_logical_connective_argument(logical_connective_name: String,
@ -136,7 +136,7 @@ impl std::fmt::Debug for Error
Kind::ExpectedVariableDeclaration => Kind::ExpectedVariableDeclaration =>
write!(formatter, "expected variable declaration")?, write!(formatter, "expected variable declaration")?,
Kind::UnexpectedToken => write!(formatter, "unexpected token")?, Kind::UnexpectedToken => write!(formatter, "unexpected token")?,
Kind::EmptyInput => write!(formatter, "empty input")?, Kind::EmptyExpression => write!(formatter, "empty expression")?,
Kind::ExpectedLogicalConnectiveArgument(ref logical_connective_name) => Kind::ExpectedLogicalConnectiveArgument(ref logical_connective_name) =>
write!(formatter, "this “{}” logical connective is missing an argument", write!(formatter, "this “{}” logical connective is missing an argument",
logical_connective_name)?, logical_connective_name)?,

View File

@ -4,10 +4,7 @@ use super::tokens::*;
pub fn formula(input: &str) -> Result<crate::Formula, crate::parse::Error> pub fn formula(input: &str) -> Result<crate::Formula, crate::parse::Error>
{ {
let formula_str = FormulaStr::new(input); let formula_str = FormulaStr::new(input);
formula_str.parse(0)?; formula_str.parse(0)
// TODO: implement correctly
Ok(crate::Formula::true_())
} }
pub(crate) fn predicate_name(identifier: &str) -> Option<(&str, &str)> pub(crate) fn predicate_name(identifier: &str) -> Option<(&str, &str)>
@ -197,7 +194,7 @@ impl<'i> FormulaStr<'i>
{ {
Some(')') => return Err(crate::parse::Error::new_unmatched_parenthesis( Some(')') => return Err(crate::parse::Error::new_unmatched_parenthesis(
crate::parse::error::Location::new(0, Some(0)))), crate::parse::error::Location::new(0, Some(0)))),
None => return Err(crate::parse::Error::new_empty_input( None => return Err(crate::parse::Error::new_empty_expression(
crate::parse::error::Location::new(0, Some(0)))), crate::parse::error::Location::new(0, Some(0)))),
_ => (), _ => (),
} }
@ -250,6 +247,16 @@ impl<'i> FormulaStr<'i>
// Parse quantified formulas // Parse quantified formulas
if let Some((identifier, input)) = identifier(input) if let Some((identifier, input)) = identifier(input)
{ {
if identifier == "not"
{
let input = input.trim_start();
println!("{} parsing “not” formula body: {}", indentation, input);
let argument = FormulaStr::new(input).parse(level + 1)?;
return Ok(crate::Formula::not(Box::new(argument)));
}
let quantifier = match identifier let quantifier = match identifier
{ {
"exists" => Some(Quantifier::Existential), "exists" => Some(Quantifier::Existential),
@ -291,6 +298,7 @@ impl<'i> FormulaStr<'i>
// Hence, the split is guaranteed to generate exactly these two elements // Hence, the split is guaranteed to generate exactly these two elements
let input_left = comparison_operator_split.next().unwrap()?; let input_left = comparison_operator_split.next().unwrap()?;
let input_right = comparison_operator_split.next().unwrap()?; let input_right = comparison_operator_split.next().unwrap()?;
assert!(comparison_operator_split.next().is_none());
let argument_left = TermStr::new(input_left).parse(level + 1)?; let argument_left = TermStr::new(input_left).parse(level + 1)?;
let argument_right = TermStr::new(input_right).parse(level + 1)?; let argument_right = TermStr::new(input_right).parse(level + 1)?;
@ -302,47 +310,59 @@ impl<'i> FormulaStr<'i>
// Parse predicates // Parse predicates
if let Some((predicate_name, input)) = predicate_name(input) if let Some((predicate_name, input)) = predicate_name(input)
{ {
println!("{} TODO: parse predicate {}", indentation, predicate_name); println!("{} parsing predicate {}", indentation, predicate_name);
let input = input.trim_start(); let input = input.trim_start();
// Parse arguments if there are any // Parse arguments if there are any
/*let arguments = match parenthesized_expression(input)? let (arguments, input) = match parenthesized_expression(input)?
{ {
Some((parenthesized_expression, remaining_input)) => Some((parenthesized_expression, input)) =>
{ {
unimplemented!(); let functor = |token: &_| *token == Token::Symbol(Symbol::Comma);
} let arguments = Tokens::new_filter(parenthesized_expression, functor).split()
None => unimplemented!(), .map(|argument| TermStr::new(argument?).parse(level + 1))
};*/ .collect::<Result<_, _>>()?;
// TODO: implement correctly (arguments, input)
return Ok(crate::Formula::true_()); }
None => (vec![], input),
};
if !input.trim().is_empty()
{
return Err(crate::parse::Error::new_unexpected_token(
crate::parse::error::Location::new(0, Some(0))))
}
// TODO: implement look-up
let declaration =
crate::PredicateDeclaration::new(predicate_name.to_string(), arguments.len());
let declaration = std::rc::Rc::new(declaration);
// TODO: handle unexpected input after end of parenthesized expression
return Ok(crate::Formula::predicate(declaration, arguments));
} }
// Parse parenthesized formulas // Parse parenthesized formulas
if let Some('(') = input.chars().next() match parenthesized_expression(input)?
{ {
match parenthesized_expression(input)? Some((parenthesized_expression, input)) =>
{ {
Some((parenthesized_expression, remaining_input)) => if !input.trim().is_empty()
{ {
if !remaining_input.trim().is_empty() return Err(crate::parse::Error::new_unexpected_token(
{ crate::parse::error::Location::new(0, Some(0))));
return Err(crate::parse::Error::new_unexpected_token( }
crate::parse::error::Location::new(0, Some(0))));
}
return FormulaStr::new(parenthesized_expression).parse(level); return FormulaStr::new(parenthesized_expression).parse(level);
}, },
None => unreachable!(), None => (),
} }
};
println!("{} cant break down formula any further: {}", indentation, input); Err(crate::parse::Error::new_unexpected_token(
crate::parse::error::Location::new(0, Some(0))))
// TODO: implement correctly
Ok(crate::Formula::true_())
} }
} }

View File

@ -3,10 +3,7 @@ use super::tokens::*;
pub fn parse_term(input: &str) -> Result<crate::Term, crate::parse::Error> pub fn parse_term(input: &str) -> Result<crate::Term, crate::parse::Error>
{ {
let term_str = TermStr::new(input); let term_str = TermStr::new(input);
term_str.parse(0)?; term_str.parse(0)
// TODO: implement correctly
Ok(crate::Term::true_())
} }
pub(crate) fn function_name(input: &str) -> Option<(&str, &str)> pub(crate) fn function_name(input: &str) -> Option<(&str, &str)>