summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs95
1 files changed, 59 insertions, 36 deletions
diff --git a/src/lib.rs b/src/lib.rs
index f60d5d9..a908897 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,7 +6,12 @@
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
-
+#![doc(
+ html_root_url = "https://docs.rs/pest_derive",
+ html_logo_url = "https://raw.githubusercontent.com/pest-parser/pest/master/pest-logo.svg",
+ html_favicon_url = "https://raw.githubusercontent.com/pest-parser/pest/master/pest-logo.svg"
+)]
+#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
//! # pest. The Elegant Parser
//!
//! pest is a general purpose parser written in Rust with a focus on accessibility, correctness,
@@ -24,12 +29,16 @@
//!
//! * API reference on [docs.rs]
//! * play with grammars and share them on our [fiddle]
-//! * leave feedback, ask questions, or greet us on [Gitter]
+//! * find previous common questions answered or ask questions on [GitHub Discussions]
+//! * leave feedback, ask questions, or greet us on [Gitter] or [Discord]
//!
-//! [book]: https://pest-parser.github.io/book
+//! [book]: https://pest.rs/book
//! [docs.rs]: https://docs.rs/pest
-//! [fiddle]: https://pest-parser.github.io/#editor
-//! [Gitter]: https://gitter.im/dragostis/pest
+//! [fiddle]: https://pest.rs/#editor
+//! [Gitter]: https://gitter.im/pest-parser/pest
+//! [Discord]: https://discord.gg/XEGACtWpT2
+//! [GitHub Discussions]: https://github.com/pest-parser/pest/discussions
+//!
//!
//! ## `.pest` files
//!
@@ -55,7 +64,7 @@
//!
//! Comments start with `//` and end at the end of the line.
//!
-//! ```ignore
+//! ```text
//! // a comment
//! ```
//!
@@ -143,37 +152,50 @@
//!
//! 1. Terminals
//!
-//! | Terminal | Usage |
-//! |------------|----------------------------------------------------------------|
-//! | `"a"` | matches the exact string `"a"` |
-//! | `^"a"` | matches the exact string `"a"` case insensitively (ASCII only) |
-//! | `'a'..'z'` | matches one character between `'a'` and `'z'` |
-//! | `a` | matches rule `a` |
+//! | Terminal | Usage |
+//! |------------|----------------------------------------------------------------|
+//! | `"a"` | matches the exact string `"a"` |
+//! | `^"a"` | matches the exact string `"a"` case insensitively (ASCII only) |
+//! | `'a'..'z'` | matches one character between `'a'` and `'z'` |
+//! | `a` | matches rule `a` |
//!
//! Strings and characters follow
//! [Rust's escape mechanisms](https://doc.rust-lang.org/reference/tokens.html#byte-escapes), while
-//! identifiers can contain alpha-numeric characters and underscores (`_`), as long as they do not
+//! identifiers can contain alphanumeric characters and underscores (`_`), as long as they do not
//! start with a digit.
//!
//! 2. Non-terminals
//!
-//! | Non-terminal | Usage |
-//! |-----------------------|------------------------------------------------------------|
-//! | `(e)` | matches `e` |
-//! | `e1 ~ e2` | matches the sequence `e1` `e2` |
-//! | <code>e1 \| e2</code> | matches either `e1` or `e2` |
-//! | `e*` | matches `e` zero or more times |
-//! | `e+` | matches `e` one or more times |
-//! | `e{n}` | matches `e` exactly `n` times |
-//! | `e{, n}` | matches `e` at most `n` times |
-//! | `e{n,} ` | matches `e` at least `n` times |
-//! | `e{m, n}` | matches `e` between `m` and `n` times inclusively |
-//! | `e?` | optionally matches `e` |
-//! | `&e` | matches `e` without making progress |
-//! | `!e` | matches if `e` doesn't match without making progress |
-//! | `PUSH(e)` | matches `e` and pushes it's captured string down the stack |
-//!
-//! where `e`, `e1`, and `e2` are expressions.
+//! | Non-terminal | Usage |
+//! |-----------------------|------------------------------------------------------------|
+//! | `(e)` | matches `e` |
+//! | `e1 ~ e2` | matches the sequence `e1` `e2` |
+//! | <code>e1 \| e2</code> | matches either `e1` or `e2` |
+//! | `e*` | matches `e` zero or more times |
+//! | `e+` | matches `e` one or more times |
+//! | `e{n}` | matches `e` exactly `n` times |
+//! | `e{, n}` | matches `e` at most `n` times |
+//! | `e{n,}` | matches `e` at least `n` times |
+//! | `e{m, n}` | matches `e` between `m` and `n` times inclusively |
+//! | `e?` | optionally matches `e` |
+//! | `&e` | matches `e` without making progress |
+//! | `!e` | matches if `e` doesn't match without making progress |
+//! | `PUSH(e)` | matches `e` and pushes it's captured string down the stack |
+//!
+//! where `e`, `e1`, and `e2` are expressions.
+//!
+//! Matching is greedy, without backtracking. Note the difference in behavior for
+//! these two rules in matching identifiers that don't end in an underscore:
+//!
+//! ```ignore
+//! // input: ab_bb_b
+//!
+//! identifier = @{ "a" ~ ("b"|"_")* ~ "b" }
+//! // matches: a b_bb_b nothing -> error!
+//!
+//! identifier = @{ "a" ~ ("_"* ~ "b")* }
+//! // matches: a b, _bb, _b in three repetitions
+//! ```
//!
//! Expressions can modify the stack only if they match the input. For example,
//! if `e1` in the compound expression `e1 | e2` does not match the input, then
@@ -181,6 +203,10 @@
//! `e1` did. Repetitions and optionals (`e*`, `e+`, `e{, n}`, `e{n,}`,
//! `e{m,n}`, `e?`) can modify the stack each time `e` matches. The `!e` and `&e`
//! expressions are a special case; they never modify the stack.
+//! Many languages have "keyword" tokens (e.g. if, for, while) as well as general
+//! tokens (e.g. identifier) that matches any word. In order to match a keyword,
+//! generally, you may need to restrict that is not immediately followed by another
+//! letter or digit (otherwise it would be matched as an identifier).
//!
//! ## Special rules
//!
@@ -266,7 +292,7 @@
//! ```
//!
//! For historical reasons, `PEEK_ALL` matches from top to bottom, while `PEEK[start..end]` matches
-//! from bottom to top. There is currectly no syntax to match a slice of the stack top to bottom.
+//! from bottom to top. There is currently no syntax to match a slice of the stack top to bottom.
//!
//! ## `Rule`
//!
@@ -289,13 +315,10 @@
//! * `ASCII` - matches a character from \x00..\x7f
//! * `NEWLINE` - matches either "\n" or "\r\n" or "\r"
-#![doc(html_root_url = "https://docs.rs/pest_derive")]
-
-extern crate pest_generator;
-extern crate proc_macro;
-
use proc_macro::TokenStream;
+/// The main method that's called by the proc macro
+/// (a wrapper around `pest_generator::derive_parser`)
#[proc_macro_derive(Parser, attributes(grammar, grammar_inline))]
pub fn derive_parser(input: TokenStream) -> TokenStream {
pest_generator::derive_parser(input.into(), true).into()