Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.