ask-dracula-rs/src/parse.rs

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))
}