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.
64 lines
2.3 KiB
Rust
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(),
|
|
}
|
|
}
|
|
}
|