rott/rottlib/src/parser/mod.rs
dkanus 588790b9b4 Refactor everything
Huge dump of refactored code. Still in the middle of the changes that
are to be squashed later in a one huge monster commit, because there is
no value in anything atomic here.
2026-04-05 20:32:11 +07:00

64 lines
2.3 KiB
Rust

//! Parser for Fermented `UnrealScript` (`FerUS`).
//!
//! Consumes tokens from [`crate::lexer::TokenizedFile`] and allocates AST
//! nodes in [`crate::arena::Arena`]. Basic expressions use a Pratt parser;
//! the rest rely on recursive descent in [`crate::parser::grammar`].\
//! Non-fatal errors accumulate in `Parser::diagnostics` as
//! [`crate::diagnostics::Diagnostic`]; recovery skips to sync points defined by
//! [`crate::parser::recovery::SyncLevel`] and synthesizes error nodes while
//! keeping the parse going.
//!
//! Components:
//! - `cursor`: token I/O, `peek`/`advance`, and lazy trivia capture;
//! - `trivia`: trailing comments and newline counts keyed to
//! the previous significant token and BOF;
//! - `recovery`: panic-mode skipping and recovery adapters for results;
//! - `pretty`: printable trees (`ExprTree`, `StmtTree`) for messages and dumps;
//! - `errors`: [`ParseError`] and [`ParseErrorKind`].
//!
//! Lifetimes: `'src` ties to lexer slices; `'arena` ties to AST allocation.
//!
//! Guarantees:
//!
//! - Parser does not abort on user input. It emits diagnostics and error nodes.
//! - Trivia is recorded as you scan and can be queried by formatters/linters.
//! - Public surface keeps [`Parser`] small;
//! low-level plumbing lives in submodules.
use super::lexer;
pub use lexer::{TokenData, Tokens};
mod cursor;
mod errors;
mod grammar;
mod recovery;
mod trivia;
pub use errors::ParseError;
pub(crate) use errors::{ParseErrorKind, ParseResult};
pub(crate) use recovery::{ResultRecoveryExt, SyncLevel};
pub(crate) use trivia::{TriviaKind, TriviaToken};
pub type ParseExpressionResult<'src, 'arena> =
ParseResult<'src, 'arena, crate::ast::ExpressionRef<'src, 'arena>>;
/// A recursive-descent parser over token from [`crate::lexer::TokenizedFile`].
pub struct Parser<'src, 'arena> {
arena: &'arena crate::arena::Arena,
pub diagnostics: Vec<crate::diagnostics::Diagnostic>,
cursor: cursor::Cursor<'src, 'src>,
trivia: trivia::TriviaIndexBuilder<'src>,
}
impl<'src, 'arena> Parser<'src, 'arena> {
pub fn new(file: &'src lexer::TokenizedFile<'src>, arena: &'arena crate::arena::Arena) -> Self {
Self {
arena,
diagnostics: Vec::new(),
cursor: cursor::Cursor::new(file),
trivia: trivia::TriviaIndexBuilder::default(),
}
}
}