Skip to main content

perl_parser_core/
lib.rs

1//! Core parser engine for Perl source code.
2//!
3//! `perl-parser-core` is the foundational crate that wires together the lexer,
4//! AST, error recovery, and position mapping into a single [`Parser`] entry
5//! point. Higher-level crates -- semantic analysis, workspace indexing, and the
6//! LSP server -- all build on top of this crate.
7//!
8//! # Key types
9//!
10//! | Type | Role |
11//! |------|------|
12//! | [`Parser`] | Recursive-descent parser; call [`Parser::parse`] to get an AST |
13//! | [`Node`] / [`NodeKind`] | AST node and its discriminant (re-exported from `perl-ast`) |
14//! | [`ParseError`] | Syntax error collected during parsing |
15//! | [`ParseOutput`] | AST + diagnostics bundle for IDE workflows |
16//! | [`Token`] / [`TokenKind`] | Lexer tokens consumed by the parser |
17//! | [`SourceLocation`] | Byte-offset span for every node |
18//!
19//! # Quick start
20//!
21//! ```rust
22//! use perl_parser_core::{Parser, Node, NodeKind};
23//!
24//! let mut parser = Parser::new("my $x = 42;");
25//! let ast = parser.parse().expect("should parse");
26//!
27//! // The root is always a Program node
28//! assert!(matches!(ast.kind, NodeKind::Program { .. }));
29//!
30//! // Non-fatal errors are collected, not returned as Err
31//! assert!(parser.errors().is_empty());
32//! ```
33//!
34//! For IDE workflows that need error-tolerant parsing, use
35//! [`Parser::parse_with_recovery`]:
36//!
37//! ```rust
38//! use perl_parser_core::Parser;
39//!
40//! let mut parser = Parser::new("if (");
41//! let output = parser.parse_with_recovery();
42//!
43//! // Always returns an AST (possibly with ERROR nodes)
44//! assert!(!output.diagnostics.is_empty());
45//! ```
46
47#![deny(unsafe_code)]
48#![deny(unreachable_pub)]
49#![warn(rust_2018_idioms)]
50#![warn(missing_docs)]
51#![cfg_attr(test, allow(clippy::panic, clippy::unwrap_used, clippy::expect_used))]
52#![warn(clippy::all)]
53#![allow(
54    clippy::too_many_lines,
55    clippy::module_name_repetitions,
56    clippy::cast_possible_truncation,
57    clippy::cast_sign_loss,
58    clippy::cast_precision_loss,
59    clippy::cast_possible_wrap,
60    clippy::must_use_candidate,
61    clippy::missing_errors_doc,
62    clippy::missing_panics_doc,
63    clippy::wildcard_imports,
64    clippy::enum_glob_use,
65    clippy::match_same_arms,
66    clippy::if_not_else,
67    clippy::struct_excessive_bools,
68    clippy::items_after_statements,
69    clippy::return_self_not_must_use,
70    clippy::unused_self,
71    clippy::collapsible_match,
72    clippy::collapsible_if,
73    clippy::only_used_in_recursion,
74    clippy::items_after_test_module,
75    clippy::while_let_loop,
76    clippy::single_range_in_vec_init,
77    clippy::arc_with_non_send_sync,
78    clippy::needless_range_loop,
79    clippy::result_large_err,
80    clippy::if_same_then_else,
81    clippy::should_implement_trait,
82    clippy::manual_flatten,
83    clippy::needless_raw_string_hashes,
84    clippy::single_char_pattern,
85    clippy::uninlined_format_args
86)]
87
88/// Builtin function signatures and metadata.
89pub use perl_builtins as builtins;
90/// Parser engine components and supporting utilities.
91pub mod engine;
92/// Token stream and trivia utilities for the parser.
93pub mod tokens;
94
95/// Index into the diagnostics array in [`ParseOutput`] (from `ast_v2`).
96pub use ast_v2::{DiagnosticId, MissingKind};
97/// Abstract Syntax Tree (AST) definitions for Perl parsing.
98pub use engine::ast;
99/// Experimental second-generation AST (work in progress).
100pub use engine::ast_v2;
101/// Parser context with error recovery support.
102pub use engine::parser_context;
103/// Pragma tracking for `use` and related directives.
104pub use engine::pragma_tracker;
105/// Parser for Perl quote and quote-like operators.
106pub use engine::quote_parser;
107/// Legacy module aliases for moved engine components.
108pub use engine::{error, parser, position};
109/// Edit tracking for incremental parsing.
110pub use perl_edit as edit;
111/// Heredoc content collector with FIFO ordering and indent stripping.
112pub use perl_heredoc as heredoc_collector;
113/// Parser utilities and helpers.
114pub use perl_tokenizer::util;
115
116/// Recursive-descent parser -- the main entry point for parsing Perl source.
117pub use engine::parser::Parser;
118
119/// Error classification and recovery strategies for parse failures.
120pub use error::classifier as error_classifier;
121/// Error recovery helpers and strategies.
122pub use error::recovery as error_recovery;
123/// Result of an error recovery attempt.
124pub use error_recovery::RecoveryResult;
125
126/// Line indexing and position mapping utilities.
127pub mod line_index {
128    /// Fast lookup from byte offset to line number.
129    pub use perl_position_tracking::LineIndex;
130}
131/// Line ending detection for mixed-EOL source files.
132pub use position::{LineEnding, PositionMapper};
133
134/// Core AST types re-exported for convenience.
135pub use ast::{Node, NodeKind, SourceLocation};
136/// Parse error, budget, and output types.
137pub use error::{BudgetTracker, ParseBudget, ParseError, ParseOutput, ParseResult};
138
139/// Builtin function signature lookup tables.
140pub use builtins::builtin_signatures;
141/// Perfect hash function (PHF) based builtin signature lookup.
142pub use builtins::builtin_signatures_phf;
143
144/// Token stream module for lexer-to-parser bridge.
145pub use tokens::token_stream;
146/// Lightweight token wrapper for AST integration.
147pub use tokens::token_wrapper;
148/// Trivia (whitespace and comments) representation.
149pub use tokens::trivia;
150/// Trivia-preserving parser and formatting utilities.
151pub use tokens::trivia_parser;
152
153/// Individual token, its classification, and the streaming iterator.
154pub use token_stream::{Token, TokenKind, TokenStream};
155/// Trivia types attached to AST nodes for formatting preservation.
156pub use trivia::{NodeWithTrivia, Trivia, TriviaToken};
157/// Trivia-preserving parser and source formatting helper.
158pub use trivia_parser::{TriviaPreservingParser, format_with_trivia};