Module Parsing.MakeSource

Core parser over a Menhir incremental API, without the fast parser. The incremental parser produces both the AST and, via Parser_messages, the error in a single pass, so this is all an in-process consumer that only wants parse_diagnostics needs. See Make_parser for the fast-path variant.

Parameters

module Output : sig ... end
module Tokens : sig ... end
module _ : sig ... end
module _ : sig ... end
module _ : sig ... end

Signature

Sourceval parse : ?color:Wax_utils.Colors.flag -> filename:string -> unit -> Output.t * Wax_utils.Trivia.context

Parse a file from a filename (reads from stdin if filename is empty or "-"). On a syntax error the diagnostic is printed and Syntax_error is raised; the caller decides how to terminate (the CLI exits 128).

Sourceval parse_from_string : ?color:Wax_utils.Colors.flag -> filename:string -> string -> Output.t * Wax_utils.Trivia.context

Parse from a string. On a syntax error the diagnostic is printed and Syntax_error is raised; the caller decides how to terminate (the CLI exits 128).

Sourceval parse_diagnostics : filename:string -> string -> (Output.t * Wax_utils.Trivia.context, syntax_error) result

Parse from a string, returning Ok (ast, context) or Error error without printing or exiting. For in-process use — e.g. an editor that wants the syntax error as data to report as a diagnostic — where the print-and-exit behaviour of parse_from_string is unwanted.

Sourceval parse_recover : filename:string -> sync:(Tokens.token -> sync_class) -> ?insert:(Tokens.token * Wax_utils.Message.t) list -> ?closers:Tokens.token list -> ?barrier:(Tokens.token * (Tokens.token -> bool) * (Tokens.token -> bool)) -> string -> Output.t option * syntax_error list * Wax_utils.Trivia.context

Parse with panic-mode error recovery, collecting every syntax error instead of stopping at the first. On each error the parser stack is resynchronized: tokens are discarded up to the next boundary (as classified by sync), the stack is unwound to the closest state that can shift that boundary, the boundary is shifted, and parsing resumes; see sync_class. A lexer error (bad character, malformed byte) is likewise recorded and skipped, so a stray character does not truncate the parse. Returns the best-effort AST (Some ast if parsing reached an accepting state, None if recovery could not), the errors in source order, and the trivia context. Nothing is printed. Intended for in-process consumers such as a language server that must report all errors and keep a partial AST across them.

insert is a list of candidate tokens (each with the diagnostic to report) that recovery may insert in front of an offending token instead of skipping to a boundary — a statement separator like ;, or a placeholder operand like a zero 0 that lets an incomplete construct complete. The candidates are tried in order; the engine's acceptable answers whether one fits, and the repair is kept only if the offending token then shifts too (validated, so a wrong guess is discarded). Insertion is attempted at most once per source position, so it cannot loop; it falls back to skip-based recovery. The candidates also serve close_pending (e.g. completing an unclosed construct at EOF). Omit ([]) to disable insertion.

closers lists the closing-bracket tokens. At end of input inside an unclosed bracketed construct, recovery auto-closes: it inserts whichever of these the parser accepts (and, between them, the insert separator when a statement must be terminated first), repeatedly, until EOF is accepted, so the construct the user is still typing reduces into the best-effort AST instead of being unwound away and dropped. The syntax error is still reported; only the recovered AST improves. Omit to keep the unwind-and-discard behaviour.

barrier adapts recovery to a fully parenthesized grammar (WAT), which has no separator or leader token: a missing closer then surfaces not as an unclosed construct but as a new field offered where an instruction was expected. It is a triple — the ( token to re-offer, a predicate for a field keyword written after a bare ( (offered as the pair ( ; kw), and a predicate for a fused (type/(import/(export opener the lexer folds into one token (offered alone) — and lets recovery close the enclosing field and restart at the new one instead of letting paren-depth counting swallow the sibling; both predicates fire only at the enclosing level, so a field-like opener nested in skipped content is not mistaken for a field. Supplying barrier also enables group-drop: when a closer cannot be shifted because an inner group's production is incomplete and needs more than one token to repair (e.g. (v128.const)), the broken group is dropped whole and its enclosing field kept. Omit (the default) in a grammar with real separator/leader anchors (Wax), where neither applies.