use grammar::parse_tree as pt;
use grammar::repr as r;
use 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 = try!(lower_helper(session, grammar, validate));
let grammar = profile!(session, "Inlining", try!(inline::inline(grammar)));
Ok(grammar)
}
fn lower_helper(session: &Session, grammar: pt::Grammar, validate: bool) -> NormResult<r::Grammar> {
profile!(
session,
"Grammar validation",
if validate {
try!(prevalidate::validate(&grammar));
}
);
let grammar = profile!(
session,
"Grammar resolution",
try!(resolve::resolve(grammar))
);
let grammar = profile!(
session,
"Macro expansion",
try!(macro_expand::expand_macros(grammar))
);
let grammar = profile!(session, "Token check", try!(token_check::validate(grammar)));
let types = profile!(session, "Infer types", try!(tyinfer::infer_types(&grammar)));
let grammar = profile!(
session,
"Lowering",
try!(lower::lower(session, grammar, types))
);
Ok(grammar)
}
mod prevalidate;
mod resolve;
mod macro_expand;
mod token_check;
mod tyinfer;
mod lower;
mod inline;
mod norm_util;