use crate::core::{ParseError, ParseResult, get_extension, load_file, validate_extension};
use crate::syntax::kerml::ast::KerMLFile;
use crate::syntax::kerml::ast::parsers::parse_file;
use pest::Parser;
use std::path::{Path, PathBuf};
pub fn load_and_parse(path: &PathBuf) -> Result<KerMLFile, String> {
validate_extension(path)?;
let content = load_file(path)?;
parse_content(&content, path)
}
pub fn parse_content(content: &str, path: &Path) -> Result<KerMLFile, String> {
let mut pairs = crate::parser::KerMLParser::parse(crate::parser::kerml::Rule::file, content)
.map_err(|e| format!("Parse error in {}: {}", path.display(), e))?;
parse_file(&mut pairs).map_err(|e| format!("AST error in {}: {:?}", path.display(), e))
}
pub fn parse_with_result(content: &str, path: &Path) -> ParseResult<KerMLFile> {
if let Err(e) = get_extension(path) {
return ParseResult::with_errors(vec![e]);
}
match crate::parser::KerMLParser::parse(crate::parser::kerml::Rule::file, content) {
Ok(mut pairs) => match parse_file(&mut pairs) {
Ok(file) => ParseResult::success(file),
Err(e) => {
let error = ParseError::ast_error(format!("{e:?}"), 0, 0);
ParseResult::with_errors(vec![error])
}
},
Err(parse_error) => {
let (line, col) = match parse_error.line_col {
pest::error::LineColLocation::Pos((l, c)) => (l - 1, c - 1), pest::error::LineColLocation::Span((l, c), _) => (l - 1, c - 1),
};
let error = ParseError::syntax_error(format!("{}", parse_error.variant), line, col);
ParseResult::with_errors(vec![error])
}
}
}
#[cfg(test)]
mod tests;