101 lines
1.8 KiB
Rust
101 lines
1.8 KiB
Rust
|
use nom::
|
||
|
{
|
||
|
IResult,
|
||
|
character::complete::multispace0,
|
||
|
sequence::{delimited, pair, terminated},
|
||
|
combinator::map,
|
||
|
branch::alt,
|
||
|
bytes::complete::tag,
|
||
|
};
|
||
|
|
||
|
fn statement_kind(i: &str) -> IResult<&str, crate::project::StatementKind>
|
||
|
{
|
||
|
let foo = delimited
|
||
|
(
|
||
|
multispace0,
|
||
|
alt
|
||
|
((
|
||
|
map
|
||
|
(
|
||
|
tag("axiom:"),
|
||
|
|_| crate::project::StatementKind::Axiom,
|
||
|
),
|
||
|
map
|
||
|
(
|
||
|
tag("lemma:"),
|
||
|
|_| crate::project::StatementKind::Lemma,
|
||
|
),
|
||
|
map
|
||
|
(
|
||
|
tag("conjecture:"),
|
||
|
|_| crate::project::StatementKind::Conjecture,
|
||
|
),
|
||
|
)),
|
||
|
multispace0,
|
||
|
)(i);
|
||
|
|
||
|
foo
|
||
|
}
|
||
|
|
||
|
fn statement(i: &str) -> IResult<&str, (crate::project::StatementKind, foliage::Formula)>
|
||
|
{
|
||
|
terminated
|
||
|
(
|
||
|
pair
|
||
|
(
|
||
|
statement_kind,
|
||
|
foliage::formula,
|
||
|
),
|
||
|
delimited
|
||
|
(
|
||
|
multispace0,
|
||
|
tag("."),
|
||
|
multispace0,
|
||
|
),
|
||
|
)(i)
|
||
|
}
|
||
|
|
||
|
pub fn project(i: &str) -> IResult<&str, crate::Project>
|
||
|
{
|
||
|
let mut statement_input = i.clone();
|
||
|
let mut statements = std::collections::HashMap::new();
|
||
|
|
||
|
loop
|
||
|
{
|
||
|
let i_ = statement_input.clone();
|
||
|
match statement(i_)
|
||
|
{
|
||
|
Ok((i, (statement_kind, formula))) =>
|
||
|
{
|
||
|
// 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)));
|
||
|
}
|
||
|
|
||
|
let statements = statements.entry(statement_kind).or_insert_with(Vec::new);
|
||
|
statements.push(formula);
|
||
|
|
||
|
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 != ""
|
||
|
{
|
||
|
return Err(nom::Err::Error(nom::error::ParseError::from_error_kind(statement_input, nom::error::ErrorKind::Many0)));
|
||
|
}
|
||
|
|
||
|
let project = crate::Project
|
||
|
{
|
||
|
statements,
|
||
|
};
|
||
|
|
||
|
Ok((i, project))
|
||
|
}
|