@@ -208,10 +208,91 @@ where
208208 }
209209 }
210210
211- /// Sets the precedence level of the parser.
211+ /// Sets the precedence level for the current instance of the parser.
212+ ///
213+ /// It defaults to 0, which is traditionally treated as the "lowest"
214+ /// possible precedence when parsing an expression.
212215 ///
213216 /// This is useful to disambiguate grammars based on the parent operator's
214- /// precedence.
217+ /// precedence. This comes up primarily when parsing recursive expressions.
218+ ///
219+ /// The parsing machinery underpinning [`Expression`] assumes that a "more
220+ /// tightly binding" operator is numerically large, while a "more loosely
221+ /// binding" operator is numerically small. For example, `13` is a higher
222+ /// precedence level than `1` because `13 > 1`.
223+ ///
224+ /// Other ways of describing this relationship:
225+ /// - `13` has a higher precedence compared to `1`
226+ /// - `13` has a higher binding power compared to `1`
227+ ///
228+ /// Note: Binding power and precedence both refer to the same concept and
229+ /// may be used interchangeably.
230+ ///
231+ /// # Motivation
232+ ///
233+ /// If you don't understand why this is useful to have, this section tries
234+ /// to explain in more detail.
235+ ///
236+ /// The [C-style Expressions][crate::_topic::arithmetic#c-style-expression]
237+ /// example has source code for parsing the expression described below, and
238+ /// can provide a clearer usage example.
239+ ///
240+ /// Consider the following expression in the C language:
241+ ///
242+ /// ```c
243+ /// int x = (1 == 1 ? 0 : 1, -123); // <-- let's parse this
244+ /// printf("%d\n", x); // -123
245+ /// ```
246+ ///
247+ /// Let's look at the right-hand side of the expression on the first line,
248+ /// and replace some of the sub-expressions with symbols:
249+ ///
250+ /// ```text
251+ /// (1 == 1 ? 0 : 1, -123) // rhs
252+ /// (a ? b : c, d ) // symbolic
253+ /// (a ? b : c, d) // remove whitespace
254+ /// (, (? a b c) d) // prefix notation
255+ /// ```
256+ ///
257+ /// Written symbolically:
258+ /// - `a` is the condition, like `1 == 1`
259+ /// - `b` is the value when the condition is true
260+ /// - `c` is the value when the condition is false
261+ /// - `d` is a secondary expression unrelated to the ternary
262+ ///
263+ /// In prefix notation, it's easier to see the specific operators and what
264+ /// they bind to:
265+ /// - COMMA (`,`) binds to `(? a b c)` and `d`
266+ /// - TERNARY (`?`) binds to `a`, `b`, and `c`
267+ ///
268+ /// ## Parsing `c` and `d`
269+ ///
270+ /// Let's focus on parsing the sub-expressions `c` and `d`, as that
271+ /// motivates why a parser precedence level is necessary.
272+ ///
273+ /// To parse `c`, we would really like to re-use the parser produced by
274+ /// [`expression()`], because `c` is really *any* valid expression that
275+ /// can be parsed by `expression()` already.
276+ ///
277+ /// However, we can't re-use the parser naively. When parsing `c`, we need
278+ /// to "escape" from the inner parser when encountering the comma separating
279+ /// `c` from `d`.
280+ ///
281+ /// The reason we have to "escape" is because of how operator precedence is
282+ /// defined in the C language: the comma operator has the lowest precedence
283+ /// among all the operators. When we're parsing `c`, we're in the context of
284+ /// the ternary operator. We don't want to parse any valid expression! Just
285+ /// what the ternary operator captures.
286+ ///
287+ /// That's where the precedence level comes in: you specify the minimum
288+ /// precedence this parser is willing to accept. If you come across an
289+ /// expression in the top-level with a lower binding power than the starting
290+ /// precedence, you know to stop parsing.
291+ ///
292+ /// The parsing machinery inside of [`Expression`] handles most of this for
293+ /// you, but it can't determine what the precedence level should be for a
294+ /// given expression. That's a language-specific detail, and it depends on
295+ /// what you want to parse.
215296 #[ inline( always) ]
216297 pub fn precedence_level (
217298 mut self ,
0 commit comments