Recipes for whitespace, lists, commits, and borrows.
<div style="background-color: #fff8e1; border-left: 4px solid #f9a825; padding: 0.75em 1em; margin: 1em 0;">
**AI assistance:** This chapter was drafted with AI assistance while the library is still young. The guide is expected to improve over time as APIs and examples stabilize. If anything looks wrong or confusing, please [report it on GitHub](https://github.com/ArneCode/marser/issues/new).
</div>
# Common patterns
Short recipes experienced users often look for when sketching a grammar.
## Whitespace
Treat runs of ignorable tokens as a **matcher** you clone into sequences:
```rust
use std::rc::Rc;
use marser::matcher::multiple::many;
use marser::one_of::one_of;
let ws = Rc::new(many(one_of((' ', '\t', '\n', '\r'))));
// use ws.clone() before/after tokens where flexibility helps
# let _ = ws;
```
Keep whitespace **out** of token parsers when you want keywords to match exactly at boundaries; pull `ws` into the surrounding rule instead.
## Comma-separated lists
Typical shape: optional first element, then zero or more `,` + element repetitions. Inside `capture!`, use **repeated binds** (`*items`) for each `bind!(..., *items)` that appends.
Sketch:
```text
[ optional(elem (, elem)*) ]
```
See [Build a Simple JSON Parser](crate::guide::worked_json_example) for arrays/objects, and `examples/json/grammar.rs` for recovery-aware commas.
## Distinctive-prefix commits
Use `commit_on(prefix, rest)` after the parser has seen a prefix that clearly picks one construct. Good commit points are:
- an opening delimiter such as `(`, `{`, `[`
- a keyword such as `let`, `if`, `while`
- a prefix that would produce misleading backtracking if another branch were tried
Avoid committing on tokens that several constructs still share. The goal is: **backtrack while still deciding what the user meant; commit once you know the construct**.
## Recursive rules
Use `recursive` whenever a rule refers to itself (JSON `value`, expressions, blocks).
Annotating the `DeferredWeak` input (here for `&str` parsers) is enough for type
inference; a real grammar would clone that handle into nested rules instead of
ignoring it:
```rust
use marser::capture;
use marser::matcher::{any_token::AnyToken, negative_lookahead::negative_lookahead};
use marser::parser::{recursive, DeferredWeak, Parser};