2019-11-02 02:13:45 +01:00
|
|
|
use nom::
|
|
|
|
{
|
|
|
|
IResult,
|
2019-11-05 19:44:28 +01:00
|
|
|
sequence::{delimited, pair, preceded, terminated, tuple},
|
|
|
|
combinator::{map, recognize},
|
2019-11-07 04:20:06 +01:00
|
|
|
character::complete::digit1,
|
2019-11-02 02:13:45 +01:00
|
|
|
branch::alt,
|
|
|
|
bytes::complete::tag,
|
|
|
|
};
|
|
|
|
|
2019-11-05 19:44:28 +01:00
|
|
|
use foliage::parse::whitespace0;
|
|
|
|
|
|
|
|
pub fn recognize_and_keep<I: Clone + nom::Offset + nom::Slice<std::ops::RangeTo<usize>>, O, E: nom::error::ParseError<I>, F>(parser: F) -> impl Fn(I) -> IResult<I, (I, O), E>
|
|
|
|
where
|
|
|
|
F: Fn(I) -> IResult<I, O, E>,
|
|
|
|
{
|
|
|
|
move |input: I|
|
|
|
|
{
|
|
|
|
let i = input.clone();
|
|
|
|
match parser(i)
|
|
|
|
{
|
|
|
|
Ok((i, result)) =>
|
|
|
|
{
|
|
|
|
let index = input.offset(&i);
|
|
|
|
Ok((i, (input.slice(..index), result)))
|
|
|
|
},
|
|
|
|
Err(e) => Err(e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
fn formula_statement_kind(i: &str) -> IResult<&str, crate::project::FormulaStatementKind>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
|
|
|
let foo = delimited
|
|
|
|
(
|
2019-11-05 19:44:28 +01:00
|
|
|
whitespace0,
|
2019-11-02 02:13:45 +01:00
|
|
|
alt
|
|
|
|
((
|
|
|
|
map
|
|
|
|
(
|
|
|
|
tag("axiom:"),
|
2019-11-07 08:12:26 +01:00
|
|
|
|_| crate::project::FormulaStatementKind::Axiom,
|
2019-11-02 02:13:45 +01:00
|
|
|
),
|
|
|
|
map
|
2019-11-07 05:42:42 +01:00
|
|
|
(
|
|
|
|
tag("completion(constraint):"),
|
2019-11-07 08:12:26 +01:00
|
|
|
|_| crate::project::FormulaStatementKind::Completion(crate::project::CompletionTarget::Constraint),
|
2019-11-07 05:42:42 +01:00
|
|
|
),
|
|
|
|
map
|
2019-11-02 02:13:45 +01:00
|
|
|
(
|
2019-11-07 04:20:06 +01:00
|
|
|
preceded
|
|
|
|
(
|
|
|
|
tag("completion"),
|
|
|
|
delimited
|
|
|
|
(
|
|
|
|
tag("("),
|
|
|
|
pair
|
|
|
|
(
|
|
|
|
terminated
|
|
|
|
(
|
|
|
|
foliage::parse::symbolic_identifier,
|
|
|
|
tag("/"),
|
|
|
|
),
|
|
|
|
digit1,
|
|
|
|
),
|
|
|
|
tag("):"),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
|(name, arity)|
|
|
|
|
match arity.parse::<usize>()
|
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
Ok(arity) => crate::project::FormulaStatementKind::Completion(
|
2019-11-07 04:20:06 +01:00
|
|
|
crate::project::CompletionTarget::Predicate(foliage::PredicateDeclaration{name, arity})),
|
|
|
|
Err(error) => panic!("invalid arity “{}”: {}", arity, error),
|
|
|
|
}
|
|
|
|
),
|
|
|
|
map
|
|
|
|
(
|
2019-11-07 05:42:42 +01:00
|
|
|
tag("assumption:"),
|
2019-11-07 08:12:26 +01:00
|
|
|
|_| crate::project::FormulaStatementKind::Assumption,
|
2019-11-02 02:13:45 +01:00
|
|
|
),
|
|
|
|
map
|
|
|
|
(
|
2019-11-07 05:42:42 +01:00
|
|
|
tag("lemma(forward):"),
|
2019-11-07 08:12:26 +01:00
|
|
|
|_| crate::project::FormulaStatementKind::Lemma(Some(crate::project::ProofDirection::Forward)),
|
2019-11-07 05:42:42 +01:00
|
|
|
),
|
|
|
|
map
|
|
|
|
(
|
|
|
|
tag("lemma(backward):"),
|
2019-11-07 08:12:26 +01:00
|
|
|
|_| crate::project::FormulaStatementKind::Lemma(Some(crate::project::ProofDirection::Backward)),
|
2019-11-07 05:42:42 +01:00
|
|
|
),
|
|
|
|
map
|
|
|
|
(
|
|
|
|
tag("lemma:"),
|
2019-11-07 08:12:26 +01:00
|
|
|
|_| crate::project::FormulaStatementKind::Lemma(None),
|
2019-11-06 07:18:30 +01:00
|
|
|
),
|
|
|
|
map
|
|
|
|
(
|
|
|
|
tag("assertion:"),
|
2019-11-07 08:12:26 +01:00
|
|
|
|_| crate::project::FormulaStatementKind::Assertion,
|
2019-11-02 02:13:45 +01:00
|
|
|
),
|
|
|
|
)),
|
2019-11-05 19:44:28 +01:00
|
|
|
whitespace0,
|
2019-11-02 02:13:45 +01:00
|
|
|
)(i);
|
|
|
|
|
|
|
|
foo
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
fn formula_statement(i: &str) -> IResult<&str, (crate::project::FormulaStatementKind, foliage::Formula)>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
|
|
|
terminated
|
|
|
|
(
|
|
|
|
pair
|
|
|
|
(
|
2019-11-07 08:12:26 +01:00
|
|
|
formula_statement_kind,
|
2019-11-02 02:13:45 +01:00
|
|
|
foliage::formula,
|
|
|
|
),
|
2019-11-05 19:44:28 +01:00
|
|
|
preceded
|
2019-11-02 02:13:45 +01:00
|
|
|
(
|
2019-11-05 19:44:28 +01:00
|
|
|
whitespace0,
|
2019-11-02 02:13:45 +01:00
|
|
|
tag("."),
|
|
|
|
),
|
|
|
|
)(i)
|
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
fn formula_statement_enclosed_by_whitespace(i: &str)
|
|
|
|
-> IResult<&str, (&str, (&str, (crate::project::FormulaStatementKind, foliage::Formula)), &str)>
|
2019-11-05 19:44:28 +01:00
|
|
|
{
|
|
|
|
tuple
|
|
|
|
((
|
|
|
|
recognize(whitespace0),
|
2019-11-07 08:12:26 +01:00
|
|
|
recognize_and_keep(formula_statement),
|
2019-11-05 19:44:28 +01:00
|
|
|
recognize(whitespace0),
|
|
|
|
))(i)
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:13:45 +01:00
|
|
|
pub fn project(i: &str) -> IResult<&str, crate::Project>
|
|
|
|
{
|
|
|
|
let mut statement_input = i.clone();
|
2019-11-05 19:44:28 +01:00
|
|
|
let mut blocks = Vec::new();
|
2019-11-02 02:13:45 +01:00
|
|
|
|
|
|
|
loop
|
|
|
|
{
|
|
|
|
let i_ = statement_input.clone();
|
2019-11-07 08:12:26 +01:00
|
|
|
match formula_statement_enclosed_by_whitespace(i_)
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
Ok((i, (whitespace_before, (formula_statement_original_text, (formula_statement_kind, formula)), whitespace_after))) =>
|
2019-11-02 02:13:45 +01:00
|
|
|
{
|
|
|
|
// Iteration must always consume input (to prevent infinite loops)
|
|
|
|
if i == statement_input
|
|
|
|
{
|
|
|
|
return Err(nom::Err::Error(nom::error::ParseError::from_error_kind(statement_input, nom::error::ErrorKind::Many0)));
|
|
|
|
}
|
|
|
|
|
2019-11-05 19:44:28 +01:00
|
|
|
if !whitespace_before.is_empty()
|
|
|
|
{
|
2019-11-06 11:36:51 +01:00
|
|
|
blocks.push(crate::project::Block::Whitespace(whitespace_before.to_string()));
|
2019-11-05 19:44:28 +01:00
|
|
|
}
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
let formula_statement = crate::project::FormulaStatement
|
2019-11-05 19:44:28 +01:00
|
|
|
{
|
2019-11-07 08:12:26 +01:00
|
|
|
kind: formula_statement_kind,
|
|
|
|
original_text: formula_statement_original_text.to_string(),
|
2019-11-05 19:44:28 +01:00
|
|
|
formula,
|
2019-11-07 07:53:50 +01:00
|
|
|
proven: false,
|
2019-11-05 19:44:28 +01:00
|
|
|
};
|
|
|
|
|
2019-11-07 08:12:26 +01:00
|
|
|
blocks.push(crate::project::Block::FormulaStatement(formula_statement));
|
2019-11-05 19:44:28 +01:00
|
|
|
|
|
|
|
if !whitespace_after.is_empty()
|
|
|
|
{
|
2019-11-06 11:36:51 +01:00
|
|
|
blocks.push(crate::project::Block::Whitespace(whitespace_after.to_string()));
|
2019-11-05 19:44:28 +01:00
|
|
|
}
|
2019-11-02 02:13:45 +01:00
|
|
|
|
|
|
|
statement_input = i;
|
|
|
|
},
|
|
|
|
Err(nom::Err::Error(_)) => break,
|
|
|
|
Err(e) => return Err(e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let i = statement_input;
|
|
|
|
|
|
|
|
// Verify that the whole file has been parsed
|
|
|
|
if i != ""
|
|
|
|
{
|
2019-11-07 07:53:50 +01:00
|
|
|
eprintln!("parsing error at:\n{}", i);
|
2019-11-02 02:13:45 +01:00
|
|
|
return Err(nom::Err::Error(nom::error::ParseError::from_error_kind(statement_input, nom::error::ErrorKind::Many0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
let project = crate::Project
|
|
|
|
{
|
2019-11-05 19:44:28 +01:00
|
|
|
blocks,
|
2019-11-02 02:13:45 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok((i, project))
|
|
|
|
}
|