Skip to content
The Elegant Parser
Branch: master
Clone or download
bors and Nadrieril Merge #375
375: Fix #374 r=CAD97 a=Nadrieril

As explained in #374, this looks like a bug. It seems this was missed by 2e33180

Co-authored-by: Nadrieril Feneanar <nadrieril@users.noreply.github.com>
Latest commit 70b5ae0 Feb 28, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.cargo Bootstrap from crates-io pest:2.0 in git; publish bootstrapped version Oct 2, 2018
bootstrap Fixed generator version. Dec 21, 2018
derive Added docs for grammar inlining. Dec 21, 2018
generator Updated version. Dec 21, 2018
grammars Updated version. Dec 21, 2018
meta Fix #374 Feb 28, 2019
pest Added docs for grammar inlining. Dec 21, 2018
vm Updated vm version. Dec 22, 2018
.bors.toml
.gitignore
.travis.yml Enable minimum-versions CI gate Dec 10, 2018
CONTRIBUTING.md
Cargo.toml
FUZZING.md
LICENSE-APACHE
LICENSE-MIT
README.md
codecov.yml Added even more tests. Sep 10, 2018
pest-logo.svg
results.svg
rustfmt.toml
update_unicode.sh

README.md

pest. The Elegant Parser

Join the chat at https://gitter.im/dragostis/pest Book Docs

Build Status codecov Crates.io Crates.io

pest is a general purpose parser written in Rust with a focus on accessibility, correctness, and performance. It uses parsing expression grammars (or PEG) as input, which are similar in spirit to regular expressions, but which offer the enhanced expressivity needed to parse complex languages.

Getting started

The recommended way to start parsing with pest is to read the official book.

Other helpful resources:

  • API reference on docs.rs
  • play with grammars and share them on our fiddle
  • leave feedback, ask questions, or greet us on Gitter

Example

The following is an example of a grammar for a list of alpha-numeric identifiers where the first identifier does not start with a digit:

alpha = { 'a'..'z' | 'A'..'Z' }
digit = { '0'..'9' }

ident = { (alpha | digit)+ }

ident_list = _{ !digit ~ ident ~ (" " ~ ident)+ }
          // ^
          // ident_list rule is silent which means it produces no tokens

Grammars are saved in separate .pest files which are never mixed with procedural code. This results in an always up-to-date formalization of a language that is easy to read and maintain.

Meaningful error reporting

Based on the grammar definition, the parser also includes automatic error reporting. For the example above, the input "123" will result in:

thread 'main' panicked at ' --> 1:1
  |
1 | 123
  | ^---
  |
  = unexpected digit', src/main.rs:12

while "ab *" will result in:

thread 'main' panicked at ' --> 1:1
  |
1 | ab *
  |    ^---
  |
  = expected ident', src/main.rs:12

Pairs API

The grammar can be used to derive a Parser implementation automatically. Parsing returns an iterator of nested token pairs:

extern crate pest;
#[macro_use]
extern crate pest_derive;

use pest::Parser;

#[derive(Parser)]
#[grammar = "ident.pest"]
struct IdentParser;

fn main() {
    let pairs = IdentParser::parse(Rule::ident_list, "a1 b2").unwrap_or_else(|e| panic!("{}", e));

    // Because ident_list is silent, the iterator will contain idents
    for pair in pairs {
        // A pair is a combination of the rule which matched and a span of input
        println!("Rule:    {:?}", pair.as_rule());
        println!("Span:    {:?}", pair.as_span());
        println!("Text:    {}", pair.as_str());

        // A pair can be converted to an iterator of the tokens which make it up:
        for inner_pair in pair.into_inner() {
            match inner_pair.as_rule() {
                Rule::alpha => println!("Letter:  {}", inner_pair.as_str()),
                Rule::digit => println!("Digit:   {}", inner_pair.as_str()),
                _ => unreachable!()
            };
        }
    }
}

This produces the following output:

Rule:    ident
Span:    Span { start: 0, end: 2 }
Text:    a1
Letter:  a
Digit:   1
Rule:    ident
Span:    Span { start: 3, end: 5 }
Text:    b2
Letter:  b
Digit:   2

Other features

  • Precedence climbing
  • Input handling
  • Custom errors
  • Runs on stable Rust

Projects using pest

Special thanks

A special round of applause goes to prof. Marius Minea for his guidance and all pest contributors, some of which being none other than my friends.

You can’t perform that action at this time.