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;