#[macro_use]
mod macros;
mod boolean;
mod check_step;
mod collect;
mod condition;
mod consume;
mod depth;
mod exception;
mod outcome;
mod paragraph;
mod parser;
mod result;
mod rule;
mod string;
mod token;
mod prelude {
pub use crate::parsing::{
ExtractedToken, ParseException, ParseResult, ParseSuccess, ParseWarning,
ParseWarningKind, Token,
};
pub use crate::text::FullText;
pub use crate::tree::{Element, Elements, ElementsIterator};
}
use self::boolean::parse_boolean;
use self::depth::{process_depths, DepthItem, DepthList};
use self::paragraph::{gather_paragraphs, NO_CLOSE_CONDITION};
use self::parser::Parser;
use self::rule::impls::RULE_PAGE;
use self::string::parse_string;
use crate::tokenizer::Tokenization;
use crate::tree::SyntaxTree;
use std::borrow::Cow;
pub use self::exception::{ParseException, ParseWarning, ParseWarningKind};
pub use self::outcome::ParseOutcome;
pub use self::result::{ParseResult, ParseSuccess};
pub use self::token::{ExtractedToken, Token};
pub fn parse<'r, 't>(
log: &slog::Logger,
tokenization: &'r Tokenization<'t>,
) -> ParseOutcome<SyntaxTree<'t>>
where
'r: 't,
{
let mut parser = Parser::new(log, tokenization);
let log = &log.new(slog_o!(
"filename" => slog_filename!(),
"lineno" => slog_lineno!(),
"function" => "parse",
"tokens-len" => tokenization.tokens().len(),
));
info!(log, "Running parser on tokens");
let result = gather_paragraphs(log, &mut parser, RULE_PAGE, NO_CLOSE_CONDITION);
debug!(log, "Finished paragraph gathering, matching on consumption");
match result {
Ok(ParseSuccess {
item: elements,
exceptions,
..
}) => {
let (warnings, styles) = extract_exceptions(exceptions);
info!(
log,
"Finished parsing, producing final syntax tree";
"warnings-len" => warnings.len(),
"styles-len" => styles.len(),
);
SyntaxTree::from_element_result(elements, warnings, styles)
}
Err(warning) => {
warn!(
log,
"Fatal error occurred at highest-level parsing: {:#?}", warning,
);
let elements = vec![text!(tokenization.full_text().inner())];
let warnings = vec![warning];
let styles = vec![];
SyntaxTree::from_element_result(elements, warnings, styles)
}
}
}
fn extract_exceptions(
exceptions: Vec<ParseException>,
) -> (Vec<ParseWarning>, Vec<Cow<str>>) {
let mut warnings = Vec::new();
let mut styles = Vec::new();
for exception in exceptions {
match exception {
ParseException::Warning(warning) => warnings.push(warning),
ParseException::Style(style) => styles.push(style),
}
}
(warnings, styles)
}