use crate::parser::bracket_balancer::rebalance_brackets;
use crate::parser::events::Event;
use crate::parser::expr::parse_expr;
use crate::parser::lexer::{TokKind, lex};
use crate::parser::tree_builder::build_tree;
use crate::syntax::SyntaxNode;
pub use crate::parser::diagnostics::ParseDiagnostic;
#[derive(Debug, Clone)]
pub struct ParseOutput {
pub cst: SyntaxNode,
pub diagnostics: Vec<ParseDiagnostic>,
}
pub fn parse(text: &str) -> ParseOutput {
let tokens = rebalance_brackets(lex(text));
let mut diagnostics = Vec::new();
let mut root_events = Vec::new();
let mut i = 0usize;
while i < tokens.len() {
if matches!(
tokens[i].kind,
TokKind::Whitespace | TokKind::Newline | TokKind::Semicolon
) {
root_events.push(Event::Tok(i));
i += 1;
continue;
}
if let Some(expr) = parse_expr(&tokens, i, 0, &mut diagnostics) {
root_events.extend(expr.events);
i = expr.end;
} else {
root_events.push(Event::Tok(i));
i += 1;
}
}
let cst = build_tree(&tokens, &root_events);
ParseOutput { cst, diagnostics }
}
pub fn reconstruct(text: &str) -> String {
parse(text)
.cst
.descendants_with_tokens()
.filter_map(|el| el.into_token())
.map(|tok| tok.text().to_string())
.collect::<String>()
}