diff --git a/src/lib.rs b/src/lib.rs index bb0633f..a76a552 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,20 +4,19 @@ //! //! [wikipedia-peg]: https://en.wikipedia.org/wiki/Parsing_expression_grammar //! -//! The `parser!{}` macro encloses a `grammar` definition containing a set of -//! `rule`s which match components of your language. The grammar is defined over -//! an [input type, normally `str`](#custom-input-types), and expands to a Rust -//! `mod`. +//! The `parser!{}` macro encloses a `grammar` definition and expands to a Rust +//! `mod`. The `grammar` contains a set of `rule`s which match components of your language. //! //! Rules can accept parameters and optionally return a value when they match. A //! `rule` not marked `pub` can only be called from other rules within the //! grammar. //! -//! Each `rule` marked `pub` expands to a function in the module which -//! accepts a reference to an input sequence, followed by any additional -//! parameters defined on the `rule`. It returns a `Result` -//! carrying either the successfully parsed value, or a `ParseError` containing -//! the failure position and the set of tokens expected there. +//! Each `rule` marked `pub` expands to a function in the module. To parse an +//! input, call this function, passing a reference to the input sequence, along +//! with any additional parameters defined on the `rule`. The call returns a +//! `Result` carrying either the successfully parsed value, or a +//! `ParseError` containing the failure position and the set of tokens expected +//! there. //! //! The body of the rule, following the `=`, is a PEG expression, definining how //! the input is matched to produce a value. @@ -38,25 +37,30 @@ //! } //! ``` //! -//! ## Expressions +//! ## Expression Reference //! +//! ### Atoms +//! //! * `"keyword"` - _Literal:_ match a literal string. //! * `['0'..='9']` - _Pattern:_ match a single element that matches a Rust `match`-style //! pattern. [(details)](#match-expressions) //! * `some_rule()` - _Rule:_ match a rule defined elsewhere in the grammar and return its //! result. Arguments in the parentheses are Rust expressions. -//! * `_` or `__` or `___`: _Rule (underscore):_ As a special case, rule names +//! * `_` or `__` or `___` - _Rule (underscore):_ As a special case, rule names //! consisting of underscores are invoked without parentheses. These are //! conventionally used to match whitespace between tokens. //! * `(e)` - _Parentheses:_ wrap an expression into a group to override //! normal precedence. Returns the same value as the inner expression. (Use //! an _Action_ block to set the return value for a sequence). +//! +//! ### Combining +//! //! * `e1 e2 e3` - _Sequence:_ match expressions in sequence (`e1` followed by `e2` followed by -//! `e3`). -//! * `a:e1 e2 b:e3 c:e4 { rust }` - _Action:_ Match `e1`, `e2`, `e3`, `e4` in +//! `e3`), ignoring the return values. +//! * `a:e1 e2 b:e3 c:e4 { rust }` - _Action:_ match `e1`, `e2`, `e3`, `e4` in //! sequence, like above. If they match successfully, run the Rust code in //! the block and return its return value. The variable names before the -//! colons in the preceding sequence are bound to the results of the +//! colons in the sequence are bound to the results of the //! corresponding expressions. It is important that the Rust code embedded //! in the grammar is deterministic and free of side effects, as it may be //! called multiple times. @@ -67,7 +71,9 @@ //! parse error with the `&str` `e`. //! * `e1 / e2 / e3` - _Ordered choice:_ try to match `e1`. If the match succeeds, return its //! result, otherwise try `e2`, and so on. -//! * `expression?` - _Optional:_ match one or zero repetitions of `expression`. Returns an +//! +//! ### Repetition +//! * `expression?` - _Optional:_ match zero or one repetitions of `expression`. Returns an //! `Option`. //! * `expression*` - _Repeat:_ match zero or more repetitions of `expression` and return the //! results as a `Vec`. @@ -77,28 +83,32 @@ //! return the results as a `Vec`. [(details)](#repeat-ranges) //! * `expression ** delim` - _Delimited repeat:_ match zero or more repetitions of `expression` //! delimited with `delim` and return the results as a `Vec`. -//! * `&expression` - _Positive lookahead:_ Match only if `expression` matches at this position, +//! +//! ### Special +//! * `$(e)` - _Slice:_ match the expression `e`, and return the slice of the input +//! corresponding to the match. +//! * `&e` - _Positive lookahead:_ Match only if `e` matches at this position, //! without consuming any characters. -//! * `!expression` - _Negative lookahead:_ Match only if `expression` does not match at this +//! * `!e` - _Negative lookahead:_ Match only if `e` does not match at this //! position, without consuming any characters. -//! * `$(e)` - _Slice:_ match the expression `e`, and return the `&str` slice of the input -//! corresponding to the match. -//! * `position!()` - return a `usize` representing the current offset into the input, and -//! consumes no characters. -//! * `quiet!{ e }` - match expression, but don't report literals within it as "expected" in +//! * `position!()` - return a `usize` representing the current offset into +//! the input without consuming anything. +//! * `quiet!{ e }` - match the expression `e`, but don't report literals within it as "expected" in //! error messages. -//! * `expected!("something")` - fail to match, and report the specified string as an expected -//! symbol at the current location. +//! * `expected!("something")` - fail to match, and report the specified string as expected +//! at the current location. //! * `precedence!{ ... }` - Parse infix, prefix, or postfix expressions by precedence climbing. //! [(details)](#precedence-climbing) //! -//! ### Match expressions +//! ## Expression details +//! +//! ### Pattern expressions //! //! The `[pat]` syntax expands into a [Rust `match` //! pattern](https://doc.rust-lang.org/book/ch18-03-pattern-syntax.html) against the next character //! (or element) of the input. //! -//! This is commonly used for matching sets of characters with Rust's `..=` inclusive range pattern +//! To match sets of characters, use Rust's `..=` inclusive range pattern //! syntax and `|` to match multiple patterns. For example `['a'..='z' | 'A'..='Z']` matches an //! upper or lower case ASCII alphabet character. //! @@ -148,11 +158,12 @@ //! rule beginning and ending with `@` is an infix expression. Prefix and postfix rules have one //! `@` at the beginning or end, and atoms do not include `@`. //! -//! ## Custom input types +//! ## Input types //! -//! `rust-peg` handles input types through a series of traits, and comes with implementations for -//! `str`, `[u8]`, and `[T]`. Define the traits below to use your own types as -//! input to `peg` grammars: +//! The first line of the grammar declares an input type. This is normally +//! `str`, but `rust-peg` handles input types through a series of traits. The +//! library comes with implementations for `str`, `[u8]`, and `[T]`. Define the +//! traits below to use your own types as input to `peg` grammars: //! //! * `Parse` is the base trait required for all inputs. The others are only required to use the //! corresponding expressions. @@ -167,7 +178,7 @@ //! //! [gh-flat-token-tree]: https://github.com/kevinmehall/rust-peg/blob/master/peg-macros/tokens.rs //! -//! ### Error reporting +//! ## Error reporting //! //! When a match fails, position information is automatically recorded to report a set of //! "expected" tokens that would have allowed the parser to advance further.