use pest::Parser;
use pest_derive::Parser;
use super::{ast::treebuilder::ASTTreeBuilder, datastructure::TableDesc};
use crate::public::{
calc::{safe_calc, Operator},
failures::ErrorCases,
structs::ChemicalEquation,
traits::CheckedType,
};
#[derive(Parser)]
#[grammar = "ast.pest"]
struct EquParser;
pub fn parser<T: CheckedType>(equ: &str) -> Result<(ChemicalEquation, Vec<Vec<T>>), ErrorCases> {
let builder = ASTTreeBuilder::new();
let exps = EquParser::parse(Rule::equ, equ)
.map_err(|e| ErrorCases::ParserError(e.to_string()))?
.collect::<Vec<_>>();
let mut ce_desc = ChemicalEquation {
left: exps[0].clone().into_inner().count(),
right: exps[1].clone().into_inner().count(),
sum: 0,
};
ce_desc.sum = safe_calc(&ce_desc.left, &ce_desc.right, &Operator::Add)?;
let mut table = TableDesc::new(ce_desc.sum);
for (location, formula) in exps[0].clone().into_inner().enumerate() {
let atomdict = builder.parse(formula.as_str())?.to_atomdict()?;
table.store_in_table(&atomdict, location, false);
}
for (location, formula) in exps[1].clone().into_inner().enumerate() {
let atomdict = builder.parse(formula.as_str())?.to_atomdict()?;
table.store_in_table(&atomdict, location + ce_desc.left, true);
}
Ok((ce_desc, table.get_list()))
}