Syntax.Parse.Support
The support layer of a production parser: the three-way parse outcome, the recursion budget, and the token classification every grammar family shares.
Syntax.Cursor owns the mechanics (peek, advance, expect, expectation merging); this module owns parser policy. The cursor’s Reply expresses an unmet expectation and nothing else, which is right for a token fault and wrong for the two other refusals a real parser needs: a deliberate diagnostic whose message names a rewrite rather than a token menu, and a depth refusal when nesting exhausts the recursion budget. Parsed carries all three, and a deliberate refusal travels as a Diagnostic value, never as a sentinel expectation name.
Types
Parsed
type Parsed(a) = PTook(a, Cursor) | PStuck(Cursor) | PFault(Diagnostic)
One parse step: the value and the cursor after it, an unmet expectation held in the cursor’s failure record, or a finished diagnostic that no expectation set can express.
Functions and Values
from_reply
from_reply : forall a. (Syntax.Cursor.Reply(a)) -> Syntax.Parse.Support.Parsed(a)
Lift a cursor reply into a parse outcome.
parsed_fault
parsed_fault : forall a. (Syntax.Parse.Support.Parsed(a)) -> Option(Syntax.Diagnostic.Diagnostic)
Finish a parse outcome as the diagnostic it refuses with: the cursor’s own merged-expectation diagnostic for a stuck parse, the carried diagnostic for a fault, and None for a success.
refuse
refuse : (Syntax.Source.Span, String) -> Syntax.Diagnostic.Diagnostic
A deliberate parse refusal: the general parse code, the given span, the given message, and no generic expectation set, because the message names the exact rewrite or bound rather than a token menu. Migration diagnostics are built with this.
refuse(span_at(3), "the retired form").code
E7100
depth_budget
depth_budget : () -> Int
The recursion budget a whole-file parse starts with. Deep enough that no authored program meets it, small enough that a generated hostile input is refused with a diagnostic instead of exhausting the stack; the supported bound is pinned by test, one point below and one beyond.
descend
descend : (Int, Syntax.Cursor.Cursor) -> Syntax.Parse.Support.Parsed(Int)
Spend one level of the budget, or refuse structurally: a nesting depth past the budget is a diagnostic at the current token, never an abort.
match descend(1, cursor_of(Nil, 0)) of
PTook(d, _) => d
_ => -1
0
token_text
token_text : (Syntax.Token.Token) -> String
The decoded text a token carries, empty for a fixed token.
peek_word
peek_word : (Syntax.Cursor.Cursor) -> String
The decoded text at the read position without consuming it, empty at the end or on a fixed token: the one lookahead a contextual keyword needs.
surface_float
surface_float : (String) -> String
Match Rust’s stable f64 debug spelling used by syntax artifacts. The Prism lexer has already round-tripped the value through show_float, which omits the .0 on integral finite values.
surface_int
surface_int : (String) -> String
Canonical decimal spelling of an already-validated integer token.
at_fixed
at_fixed : (Syntax.Cursor.Cursor, String) -> Bool
Whether the token at the read position is the fixed spelling s.
at_kind
at_kind : (Syntax.Cursor.Cursor, Syntax.Token.TokenKind) -> Bool
Whether the token at the read position is of kind k.
take_fixed
take_fixed : (Syntax.Cursor.Cursor, String) -> Syntax.Parse.Support.Parsed(Syntax.Token.Token)
Require the fixed spelling s, as a parse outcome.
take_kind
take_kind : (Syntax.Cursor.Cursor, Syntax.Token.TokenKind) -> Syntax.Parse.Support.Parsed(Syntax.Token.Token)
Require a token of kind k, as a parse outcome.
take_word
take_word : (Syntax.Cursor.Cursor, Syntax.Token.TokenKind) -> Syntax.Parse.Support.Parsed(String)
Require a token of kind k and return its decoded text.
skip_fixed
skip_fixed : (Syntax.Cursor.Cursor, String) -> (Bool, Syntax.Cursor.Cursor)
Consume the fixed spelling s if it is there, reporting whether it was: the optional-token step every trailing separator and modifier needs.