]> git.proxmox.com Git - rustc.git/blob - vendor/pest_derive/_README.md
Update upstream source from tag 'upstream/1.32.0_beta.2+dfsg1'
[rustc.git] / vendor / pest_derive / _README.md
1 <p align="center">
2 <img src="https://raw.github.com/pest-parser/pest/master/pest-logo.svg?sanitize=true" width="80%"/>
3 </p>
4
5 # pest. The Elegant Parser
6
7 [![Join the chat at https://gitter.im/dragostis/pest](https://badges.gitter.im/dragostis/pest.svg)](https://gitter.im/dragostis/pest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8 [![Book](https://img.shields.io/badge/book-WIP-4d76ae.svg)](https://pest-parser.github.io/book)
9 [![Docs](https://docs.rs/pest/badge.svg)](https://docs.rs/pest)
10 (docs are currently [broken on docs.rs](https://github.com/onur/docs.rs/issues/23#issuecomment-359179441); build them locally with `cargo doc`)
11
12 [![Build Status](https://travis-ci.org/pest-parser/pest.svg?branch=master)](https://travis-ci.org/pest-parser/pest)
13 [![codecov](https://codecov.io/gh/pest-parser/pest/branch/master/graph/badge.svg)](https://codecov.io/gh/pest-parser/pest)
14 [![Crates.io](https://img.shields.io/crates/d/pest.svg)](https://crates.io/crates/pest)
15 [![Crates.io](https://img.shields.io/crates/v/pest.svg)](https://crates.io/crates/pest)
16
17 pest is a [PEG](https://en.wikipedia.org/wiki/Parsing_expression_grammar) parser with [simplicity][1] and [speed][2] in mind.
18
19 [1]: https://github.com/pest-parser/pest#elegant-grammar
20 [2]: https://github.com/pest-parser/pest#sheer-performance
21
22 ## Elegant grammar
23
24 Defining a grammar for a list of alpha-numeric identifiers where the first identifier does not start with a digit is as
25 straight-forward as:
26
27 ```rust
28 alpha = { 'a'..'z' | 'A'..'Z' }
29 digit = { '0'..'9' }
30
31 ident = { (alpha | digit)+ }
32
33 ident_list = _{ !digit ~ ident ~ (" " ~ ident)+ }
34 // ^
35 // ident_list rule is silent which means it produces no tokens
36 ```
37
38 This is then saved in a `.pest` grammar file and is never mixed up with Rust code which results in an always up-to-date
39 formal definition of the grammar which is very easy to maintain.
40
41 ## Pairs API
42
43 The grammar can be used to derive a `Parser` implementation automatically. Parsing returns an iterator of nested token
44 pairs:
45
46 ```rust
47 extern crate pest;
48 #[macro_use]
49 extern crate pest_derive;
50
51 use pest::Parser;
52
53 #[derive(Parser)]
54 #[grammar = "ident.pest"]
55 struct IdentParser;
56
57 fn main() {
58    let pairs = IdentParser::parse(Rule::ident_list, "a1 b2").unwrap_or_else(|e| panic!("{}", e));
59
60 // Because ident_list is silent, the iterator will contain idents
61 for pair in pairs {
62 // A pair is a combination of the rule which matched and a span of input
63 println!("Rule: {:?}", pair.as_rule());
64 println!("Span: {:?}", pair.clone().into_span());
65 println!("Text: {}", pair.clone().into_span().as_str());
66
67 // A pair can be converted to an iterator of the tokens which make it up:
68 for inner_pair in pair.into_inner() {
69 match inner_pair.as_rule() {
70 Rule::alpha => println!("Letter: {}", inner_pair.into_span().as_str()),
71 Rule::digit => println!("Digit: {}", inner_pair.into_span().as_str()),
72 _ => unreachable!()
73 };
74 }
75 }
76 }
77 ```
78
79 This produces the following output:
80 ```
81 Rule: ident
82 Span: Span { start: 0, end: 2 }
83 Text: a1
84 Letter: a
85 Digit: 1
86 Rule: ident
87 Span: Span { start: 3, end: 5 }
88 Text: b2
89 Letter: b
90 Digit: 2
91 ```
92
93 ## Meaningful error reporting
94
95 Parsing `"123"` instead of `"a1 b2"` in the code above will result in the following panic:
96
97 ```
98 thread 'main' panicked at ' --> 1:1
99 |
100 1 | 123
101 | ^---
102 |
103 = unexpected digit', src/main.rs:12
104 ```
105
106 while parsing `"ab *"` will result in:
107
108 ```
109 thread 'main' panicked at ' --> 1:4
110 |
111 1 | ab *
112 | ^---
113 |
114 = expected ident', src/main.rs:12
115 ```
116
117 ## Sheer performance
118
119 pest provides parsing performance in the same league as carefully written manual parsers.
120 The following JSON benchmark puts it somewhere in between one of the most optimized JSON parsers,
121 [ujson4c](https://github.com/esnme/ujson4c), and a static native-speed parser, [nom](https://github.com/Geal/nom).
122
123 The first entry of pest scores 36ms, while the second scores 96ms since it's mapping `Pair`s
124 to a custom JSON AST. While the first entry forms a perfectly usable tree, it does not process
125 the file to a fully-processed JSON object. The second one does, but since it has an extra
126 intermediate representation of the object, it repeats some work.
127
128 <p align="center">
129 <img src="https://raw.github.com/pest-parser/pest/master/results.svg?sanitize=true"/>
130 </p>
131
132 The [benchmark](https://github.com/Geal/pestvsnom) uses
133 [a large 2MB JSON file](https://github.com/miloyip/nativejson-benchmark/blob/master/data/canada.json).
134 Tested on a 2.6GHz Intel® Core™ i5 running macOS.
135
136 ## Other features
137
138 * precedence climbing
139 * input handling
140 * custom errors
141 * runs on stable Rust
142
143 ## Usage
144 pest requires [Cargo and Rust 1.23](https://www.rust-lang.org/en-US/downloads.html).
145
146 Add the following to `Cargo.toml`:
147
148 ```toml
149 pest = "^1.0"
150 pest_derive = "^1.0"
151 ```
152
153 and in your Rust `lib.rs` or `main.rs`:
154
155 ```rust
156 extern crate pest;
157 #[macro_use]
158 extern crate pest_derive;
159 ```
160
161 ## Projects using pest
162
163 * [brain](https://github.com/brain-lang/brain)
164 * [comrak](https://github.com/kivikakk/comrak)
165 * [graphql-parser](https://github.com/Keats/graphql-parser)
166 * [handlebars-rust](https://github.com/sunng87/handlebars-rust)
167 * [pest](https://github.com/pest-parser/pest/blob/master/pest_derive/src/parser.rs) (bootstrapped)
168 * [Huia](https://gitlab.com/huia-lang/huia-parser)
169 * [rouler](https://github.com/jarcane/rouler)
170 * [RuSh](https://github.com/lwandrebeck/RuSh)
171 * [rs_pbrt](https://github.com/wahn/rs_pbrt)
172 * [stache](https://github.com/dgraham/stache)
173 * [tera](https://github.com/Keats/tera)
174 * [ui_gen](https://github.com/emoon/ui_gen)
175 * [ukhasnet-parser](https://github.com/adamgreig/ukhasnet-parser)
176
177 ## Special thanks
178
179 A special round of applause goes to prof. Marius Minea for his guidance and all pest contribuitors,
180 some of which being none other than my friends.