Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,18 @@ Using the same package release for `antlr4-rust-gen` and
`antlr-rust-runtime` remains the recommended workflow, but matching the
generated-code API is the compile-time requirement.

The bundled generator currently emits revision 10, which stops re-declaring
The bundled generator currently emits revision 11, which stops re-declaring
the parse-driver core and entry-point scaffolding in every generated parser:
the driver methods (`parse_rule*`, `parse_interpreted_rule*`) expand from the
runtime's `__antlr4_rust_parser_driver!` macro with the module's interpreted
fallback supplied as a binder block, the `parse*` / `parse_stream*` functions
and the `<Grammar>ParserParseOutput` alias of the runtime's
`GeneratedParseOutput` expand from `__antlr4_rust_parser_entry_points!`,
`GeneratedRuleError` is the runtime's grammar-agnostic type (its
`AdaptiveRetry` variant always exists), the adaptive-ATN retry state is the
runtime's `AdaptiveAtnRetryState<N>` sized by a const knob (0 for grammars
without residual adaptive routing), and the lexer `lex` / `lex_stream`
functions are re-exports of runtime generics. Revision 10 stops re-declaring
the validated-parse surface in every generated parser: `<Grammar>ValidatedTree`
is a type alias of the runtime's `ValidatedTree` branded with the module-local
`ValidatedTreeContext` marker (likewise the module's `ValidatedRuleNode`
Expand All @@ -182,7 +193,7 @@ error name must collapse into one; see `docs/migration.md`). Revision 9
similarly imports the grammar-independent generated support surface (the typed
terminal/error-node wrappers, context child-iteration helpers, and
embedded-action input facade) from the runtime's `generated` module. The
runtime also accepts revisions 1 through 9 because their older generated
runtime also accepts revisions 1 through 10 because their older generated
recognizers use API surfaces that remain available.

Generated modules created before this check was introduced cannot be detected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ expression: rendered_generated_rule_methods(&rendered)
fn parse_generated_rule_0_precedence(&mut self, __precedence: i32, allow_fallback: bool) -> Result<antlr4_runtime::ParseTree, GeneratedRuleError> {
antlr4_runtime::__antlr4_rust_generated_rule! {
recursive self, 0isize, 0, __precedence, allow_fallback, atn(), GeneratedRuleError::Fatal;
retry [none];
retry [adaptive];
bind (__ctx, __rule_start, __consumed_eof, __sync_error);
setup {}
body {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ expression: rendered_generated_rule_methods(&rendered)
let _ = __precedence;
antlr4_runtime::__antlr4_rust_generated_rule! {
ordinary self, 0isize, 0, allow_fallback, atn(), GeneratedRuleError::Fatal;
retry [none];
retry [adaptive];
bind (__ctx, __rule_start, __consumed_eof, __sync_error);
setup {}
body {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expression: "generated_module_header.replace(env!(\"CARGO_PKG_VERSION\"),\n\"<ge
---
// @generated by antlr-rust-codegen v<generator-version> - do not edit
// project: https://github.com/ophi-dev/antlr-rust-runtime
antlr4_runtime::__antlr4_rust_require_codegen_api!(10, "<generator-version>");
antlr4_runtime::__antlr4_rust_require_codegen_api!(11, "<generator-version>");
#[allow(warnings, missing_docs, clippy::all, clippy::pedantic, clippy::nursery)]
#[rustfmt::skip]
mod __antlr4_rust_generated {
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ antlr4_runtime::__antlr4_rust_parser_facade! {
metadata: metadata,
parser_atn: parser_atn,
reset(parser) {
parser.adaptive_atn_preferred_rules.fill(false);
parser.adaptive_atn_preference_depths.fill(0);
parser.adaptive_atn_preference_starts.fill((0, 0));
parser.adaptive_atn_syntax_error_starts.fill(0);
parser.adaptive_atn_retry_slot = None;
parser.adaptive_atn.reset();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ antlr4_runtime::__antlr4_rust_parser_facade! {
metadata: metadata,
parser_atn: parser_atn,
reset(parser) {
parser.adaptive_atn.reset();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ Parser::with_hooks
base,
simulator: None,
generated_only: std::env::var_os("ANTLR4_RUST_GENERATED_ONLY").is_some(),
adaptive_atn: antlr4_runtime::generated::AdaptiveAtnRetryState::new(),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,4 @@
source: crates/antlr-rust-codegen/src/generator/tests.rs
expression: "&convenience"
---
/// Lexes UTF-8 text into an eagerly filled token stream without constructing
/// a parser.
///
/// The stream retains every emitted token, including EOF and tokens on hidden
/// or custom channels. Lexer rules using `skip` do not emit tokens.
///
/// With `use antlr4_runtime::Token as _;`, print each token's vocabulary name,
/// numeric channel, and text:
/// `let vocabulary = metadata().vocabulary(); for token in lex(src, TLexer::new).tokens() { println!("type={} channel={} text={:?}", vocabulary.display_name(token.token_type()), token.channel(), token.text()); }`
///
/// `number_of_source_errors()` reports buffered lexer diagnostics. After
/// iterating `tokens()`, `drain_source_errors()` retrieves those diagnostics.
///
/// # Panics
///
/// Panics if buffering returns an [`antlr4_runtime::TokenStoreError`]. Construct
/// the lexer and call [`antlr4_runtime::CommonTokenStream::try_new`] to handle
/// that error instead.
pub fn lex<L: antlr4_runtime::TokenSource>(
input: impl AsRef<str>,
lexer: impl FnOnce(antlr4_runtime::InputStream) -> L,
) -> antlr4_runtime::CommonTokenStream<L> {
lex_stream(antlr4_runtime::InputStream::new(input.as_ref()), lexer)
}

/// Lexes a caller-provided character stream without constructing a parser.
///
/// Unlike [`lex`], this accepts any [`antlr4_runtime::CharStream`], including a
/// named [`antlr4_runtime::InputStream`] or a byte-oriented
/// [`antlr4_runtime::ByteStream`].
///
/// `number_of_source_errors()` reports buffered lexer diagnostics. After
/// iterating `tokens()`, `drain_source_errors()` retrieves those diagnostics.
///
/// # Panics
///
/// Panics if buffering returns an [`antlr4_runtime::TokenStoreError`]. Call
/// [`antlr4_runtime::CommonTokenStream::try_new`] with the constructed lexer to
/// handle that error instead.
pub fn lex_stream<I: antlr4_runtime::CharStream, L: antlr4_runtime::TokenSource>(
input: I,
lexer: impl FnOnce(I) -> L,
) -> antlr4_runtime::CommonTokenStream<L> {
antlr4_runtime::CommonTokenStream::new(lexer(input))
}
pub use antlr4_runtime::generated::{lex, lex_stream};
Original file line number Diff line number Diff line change
@@ -1,131 +1,11 @@
---
source: crates/antlr-rust-codegen/src/generator.rs
assertion_line: 20143
source: crates/antlr-rust-codegen/src/generator/tests.rs
expression: "render_parser_parse_convenience(\"TParser\", \"T\")"
---
/// Result from [`parse_with_parser`] or [`parse_stream_with_parser`].
///
/// Keeps the generated parser available after the entry rule runs so callers
/// can inspect diagnostics or recover the parser-owned token stream.
#[derive(Debug)]
pub struct TParserParseOutput<R, L>
where
L: TokenSource,
{
pub result: R,
pub parser: TParser<L>,
}

impl<L: TokenSource> TParserParseOutput<antlr4_runtime::NodeId, L> {
/// Validates a completed parse and changes its generated context surface.
///
/// Validation rejects lexer diagnostics, parser recovery, recovered error
/// nodes, and missing generated required children before constructing the
/// validated-tree type boundary.
pub fn validate(self) -> Result<TValidatedTree, TValidationError> {
let lexer = self.parser.token_stream().number_of_source_errors();
let parser = self.parser.number_of_syntax_errors();
if lexer != 0 || parser != 0 {
return Err(TValidationError::SyntaxErrors { lexer, parser });
}
let parsed = self.parser.into_parsed_file(self.result);
validate_tree_structure(&parsed)?;
Ok(TValidatedTree::__new(parsed))
}
}

/// Parses UTF-8 text by constructing the lexer, token stream, parser, and
/// caller-selected entry rule in one call.
///
/// Pass the generated lexer constructor and a parser entry rule, for example
/// `parse(src, MyGrammarLexer::new, TParser::file)`.
///
/// The returned [`antlr4_runtime::ParsedFile`] owns the canonical token store,
/// flat CST storage, and entry-rule root.
/// Use [`parse_with_parser`] instead when the caller also needs parser
/// diagnostics after the entry rule runs.
pub fn parse<L: TokenSource>(
input: impl AsRef<str>,
lexer: impl FnOnce(antlr4_runtime::InputStream) -> L,
entry: impl FnOnce(&mut TParser<L>) -> Result<antlr4_runtime::NodeId, antlr4_runtime::AntlrError>,
) -> Result<antlr4_runtime::ParsedFile, antlr4_runtime::AntlrError>
{
parse_stream(antlr4_runtime::InputStream::new(input.as_ref()), lexer, entry)
}

/// Parses UTF-8 text and returns a typed tree whose required generated child
/// accessors are infallible.
pub fn parse_validated<L: TokenSource>(
input: impl AsRef<str>,
lexer: impl FnOnce(antlr4_runtime::InputStream) -> L,
entry: impl FnOnce(&mut TParser<L>) -> Result<antlr4_runtime::NodeId, antlr4_runtime::AntlrError>,
) -> Result<TValidatedTree, TValidationError>
{
parse_stream_validated(
antlr4_runtime::InputStream::new(input.as_ref()),
lexer,
entry,
)
}

/// Parses UTF-8 text like [`parse`] while returning the parser after the entry
/// rule has run.
///
/// This keeps the compact generated setup path available for callers that also
/// need `Parser::number_of_syntax_errors()` or `TParser::into_token_stream()`.
pub fn parse_with_parser<L: TokenSource, R>(
input: impl AsRef<str>,
lexer: impl FnOnce(antlr4_runtime::InputStream) -> L,
entry: impl FnOnce(&mut TParser<L>) -> Result<R, antlr4_runtime::AntlrError>,
) -> Result<TParserParseOutput<R, L>, antlr4_runtime::AntlrError>
{
parse_stream_with_parser(
antlr4_runtime::InputStream::new(input.as_ref()),
lexer,
entry,
)
}

/// Parses a caller-provided character stream by constructing the lexer, token
/// stream, parser, and caller-selected entry rule in one call.
///
/// Unlike [`parse`], this accepts any [`antlr4_runtime::CharStream`], including
/// a named [`antlr4_runtime::InputStream`] or a byte-oriented
/// [`antlr4_runtime::ByteStream`].
pub fn parse_stream<I: antlr4_runtime::CharStream, L: TokenSource>(
input: I,
lexer: impl FnOnce(I) -> L,
entry: impl FnOnce(&mut TParser<L>) -> Result<antlr4_runtime::NodeId, antlr4_runtime::AntlrError>,
) -> Result<antlr4_runtime::ParsedFile, antlr4_runtime::AntlrError>
{
let TParserParseOutput { result, parser } =
parse_stream_with_parser(input, lexer, entry)?;
Ok(parser.into_parsed_file(result))
}

/// Parses a caller-provided character stream and validates the completed tree.
pub fn parse_stream_validated<I: antlr4_runtime::CharStream, L: TokenSource>(
input: I,
lexer: impl FnOnce(I) -> L,
entry: impl FnOnce(&mut TParser<L>) -> Result<antlr4_runtime::NodeId, antlr4_runtime::AntlrError>,
) -> Result<TValidatedTree, TValidationError>
{
let output = parse_stream_with_parser(input, lexer, entry)
.map_err(TValidationError::Recognition)?;
output.validate()
}

/// Parses a caller-provided character stream like [`parse_stream`] while
/// returning the parser after the entry rule has run.
pub fn parse_stream_with_parser<I: antlr4_runtime::CharStream, L: TokenSource, R>(
input: I,
lexer: impl FnOnce(I) -> L,
entry: impl FnOnce(&mut TParser<L>) -> Result<R, antlr4_runtime::AntlrError>,
) -> Result<TParserParseOutput<R, L>, antlr4_runtime::AntlrError>
{
let lexer = lexer(input);
let tokens = CommonTokenStream::new(lexer);
let mut parser = TParser::new(tokens);
let result = entry(&mut parser)?;
Ok(TParserParseOutput { result, parser })
antlr4_runtime::__antlr4_rust_parser_entry_points! {
parser: TParser,
output: TParserParseOutput,
validated_tree: TValidatedTree,
validation_error: TValidationError,
validate_tree: validate_tree_structure,
}
Loading
Loading