use crate::grammar::parse_tree as pt;
use crate::grammar::repr as r;
use crate::session::Session;
pub type NormResult<T> = Result<T, NormError>;
#[derive(Clone, Debug)]
pub struct NormError {
pub message: String,
pub span: pt::Span,
}
macro_rules! return_err {
($span: expr, $($args:expr),+) => {
return Err(NormError {
message: format!($($args),+),
span: $span
})
}
}
pub fn normalize(session: &Session, grammar: pt::Grammar) -> NormResult<r::Grammar> {
normalize_helper(session, grammar, true)
}
#[cfg(test)]
pub fn normalize_without_validating(grammar: pt::Grammar) -> NormResult<r::Grammar> {
normalize_helper(&Session::new(), grammar, false)
}
fn normalize_helper(
session: &Session,
grammar: pt::Grammar,
validate: bool,
) -> NormResult<r::Grammar> {
let grammar = lower_helper(session, grammar, validate)?;
let grammar = profile!(session, "Inlining", inline::inline(grammar)?);
Ok(grammar)
}
fn lower_helper(session: &Session, grammar: pt::Grammar, validate: bool) -> NormResult<r::Grammar> {
profile!(
session,
"Grammar validation",
if validate {
prevalidate::validate(&grammar)?;
}
);
let grammar = profile!(
session,
"Conditional compilation",
cond_comp::remove_disabled_decls(session, grammar)?
);
let grammar = profile!(session, "Grammar resolution", resolve::resolve(grammar)?);
let grammar = profile!(
session,
"Precedence expansion",
precedence::expand_precedence(grammar)?
);
let grammar = profile!(
session,
"Macro expansion",
macro_expand::expand_macros(grammar, session.macro_recursion_limit)?
);
let grammar = profile!(session, "Token check", token_check::validate(grammar)?);
let types = profile!(session, "Infer types", tyinfer::infer_types(&grammar)?);
let grammar = profile!(session, "Lowering", lower::lower(session, grammar, types)?);
Ok(grammar)
}
mod prevalidate;
mod cond_comp;
mod resolve;
mod precedence;
mod macro_expand;
mod token_check;
mod tyinfer;
mod lower;
mod inline;
mod norm_util;