Skip to content

Custom Input โ€‹

What you'll learn โ€‹

  • How to implement the Input.read callback for chunked or generated source.
  • When to buffer (parseWithInput) versus stream (parseStream).

Complete example โ€‹

See Parsing Source for the full Chunked implementation and examples/custom_input.zig. Run it with:

sh
zig build run-custom_input

Expected output โ€‹

text
parsed from chunks: 12 + 34 error=false

How it works โ€‹

The callback receives an opaque payload, a byte index, and the position at that index, and returns a pointer plus the available length. The parser pulls monotonically increasing offsets, so ring buffers, paged storage, and generated streams all fit naturally. Return null or length 0 at end of input.

Buffering versus streaming โ€‹

  • parseWithInput(old, edit, input) buffers the whole input first, then parses. Use it when you also pass an old tree: subtree reuse needs the complete new text.
  • parseStream(null, null, input) pulls bytes on demand as the lexer advances โ€” no pre-buffering โ€” and the tree takes ownership of exactly the consumed prefix. Ideal for files, sockets, and decompressors behind std.Io.Reader. With an old tree it falls back to buffering so reuse still applies.
zig
var tree = try parser.parseStream(null, null, source.input());
defer tree.deinit();

Inputs are UTF-8; offsets are u32 (4 GiB limit, shared by the whole runtime).

API used โ€‹

  • Input, Parser โ€” parseWithInput, parseStream, StreamBuffer.

Released under the MIT License.