The Elegant Parser

Related tags

Parsing rust parsing peg
Overview

pest. The Elegant Parser

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

Build Status codecov Fuzzit Status 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.

Comments
  • Extract the `parser` and `validator` from the `pest_derive` crate into `pest_meta`

    Extract the `parser` and `validator` from the `pest_derive` crate into `pest_meta`

    This is the first step towards #158 . It provides the new crate pest_meta, which grants access to the implementations of the parser and validator used by pest_derive. However, in order to declare them usable, there needs to be some experimentation outside their original intended use.

    This PR is a WIP mainly to get early feedback and to prevent working inside the proverbial cave for too long.

    Open questions:

    • [x] I am not sure how versioning should work. I just put the same version for pest_meta as for all the other crates in the pest workspace but I am not sure if that's what I was supposed to do :smiley:

    Once the design & implementation kinks are ironed out and any new ideas are implemented (or postponed, dropped), this PR still needs:

    • [ ] documentation for pest_meta targeted at people who want to use it for building tools for pest (syntax highlighting, linting, completion, etc.)
    opened by Victor-Savu 42
  • Add lifetimes — refs into StrInput<'i> are bound by &'i

    Add lifetimes — refs into StrInput<'i> are bound by &'i

    Here's a preliminary attempt at resolving #141. We bind the input Input by a lifetime; for StrInput, that's the lifetime of the string it references.

    It works, happily! If you have pair: Pair<'i, Rule, StrInput<'i>> , then pair.as_str() correctly returns a &'i str (rather than &str bound by pair's lifetime). There isn't actually a test case added yet that demonstrates this, but I'd add one if we were merging. (Right now testing against a local library that I'm using pest with.)

    There's one problem I haven't resolved and without which this cannot be merged: what to do about StringInput? Right now I've added two hacky transmute calls just so it'd compile and I could get on with the work ([1], [2]), but this needs to be resolved as it's currently super-unsound.

    Thoughts welcome! If this isn't the direction you'd like to go (SO MANY LIFETIME REFERENCES), that's of course understandable; I just wanted to give this a hack, and no hard feelings if you don't merge!

    (Fixes #141. Closes #6.)

    /cc @sunng87 @dragostis

    opened by kivikakk 36
  • add some basic types to pest so it improves grammar readability

    add some basic types to pest so it improves grammar readability

    I think having some already defined types would help to enhance readability. alpha, decdigit, hexdigit, octdigit, alphanumeric, space, signedint, unsignedint, signedfloat, unsignedfloat, singlequoted, doublequoted

    and maybe a couple others, but these should cover most common needs.

    in-progress 
    opened by lwandrebeck 29
  • Make pest no_std compatible.

    Make pest no_std compatible.

    This is another attempt to fix #240 and make pest no_std compatible, allowing it to be used for example in web applications via WASM. I started slowly by converting the core pest crate only. All tests pass.

    There is however one breaking change: In my new version, pest's Error type does not implement std::error::Error, because this trait is part of std. If implementing this trait is important, it could be implemented behind a feature flag.

    opened by 01mf02 27
  • Handling indentation

    Handling indentation

    Hi! I don’t know if this is a question or a feature request, but I want to parse reStructuredText. It allows nesting blocks, and indentation works in a special way:

    Several constructs begin with a marker, and the body of the construct must be indented relative to the marker. For constructs using simple markers (bullet lists, enumerated lists, footnotes, citations, hyperlink targets, directives, and comments), the level of indentation of the body is determined by the position of the first line of text, which begins on the same line as the marker. For example, bullet list bodies must be indented by at least two columns relative to the left edge of the bullet:

    - This is the first line of a bullet list
      item's paragraph.  All lines must align
      relative to the first line.  [1]_
    
          This indented paragraph is interpreted
          as a block quote.
    
    Because it is not sufficiently indented,
    this paragraph does not belong to the list
    item.
    
    .. [1] Here's a footnote.  The second line is aligned
       with the beginning of the footnote label.  The ".."
       marker is what determines the indentation.
    

    For constructs using complex markers (field lists and option lists), where the marker may contain arbitrary text, the indentation of the first line after the marker determines the left edge of the body. For example, field lists may have very long markers (containing the field names):

    :Hello: This field has a short field name, so aligning the field
            body with the first line is feasible.
    
    :Number-of-African-swallows-required-to-carry-a-coconut: It would
        be very difficult to align the field body with the left edge
        of the first line.  It may even be preferable not to begin the
        body on the same line as the marker.
    

    How can I parse this? Would I parse it manually, I’d define an “indent stack” (like [2, 4] for the first example). Is the best idea to create an iterator that handles this indent stack and only feeds the blocks it found into pest? Or is there another way?

    enhancement grammar 
    opened by flying-sheep 25
  • Removed position::new and replaced it with position::Position::new,

    Removed position::new and replaced it with position::Position::new,

    Addresses issue #301 . Replaced unsafe code with Options and unwrapping where appropriate (which is everywhere unsafe code was being used).

    I've also changed the position::new function to position::Position::new, since it is now safe. Moreover, I've encountered an issue in my own parser project - I wanted to use the position API to find the line + column of an error but couldn't because I can't create my own position object. This pull request should fix that.

    opened by jkarns275 25
  • Factor out `.pest` parser for use by other tools

    Factor out `.pest` parser for use by other tools

    I was wondering if it would make sense to factor out the part of the code which (bootstrappingly?) parses the .pest file so that other tools such as syntax highlighters and completion engines could use it.

    maintenance 
    opened by Victor-Savu 21
  • New Travis matrix

    New Travis matrix

    This PR has been limited to the Travis matrix update, with most jobs allowed to fail temporarily. I will resubmit the fmt, clippy, and misc. test improvements changes removed from this PR momentarily as a new PR.


    Original text:

    Closes #294, closes #295, supersedes #310

    This has a rather large diff since I did a cargo fmt across the whole workspace, but it should enable mindless rustfmt from here on. I can tweak the rustfmt.toml as well if there are other configurations we want to change; I've deliberately pinned rustfmt to a nightly version.

    Clippy is pinned to 1.29.0 as that's the first rust toolchain to contain clippy-preview. As we'd like to take advantage of the new edition eventually, #300, I'm thinking that we won't officially commit to old compiler versions until 1.31 and edition 2018. At that point we can probably pin both rustfmt and clippy to the final 1.31 nightly to reduce the number of build jobs.

    opened by CAD97 20
  • Unmatched expressions modify the stack

    Unmatched expressions modify the stack

    While working with pest, I discovered that expressions that aren't matched still can modify the stack with push or pop, which seems like a bug. Consider:

    grammar.pest

    foo = ${ soi ~ push("") ~ (aba | a) ~ eoi }
    a = @{ peek ~ "a" }
    aba = @{ push("a") ~ "b" ~ pop }
    

    main.rs

    #[macro_use]
    extern crate pest_derive;
    extern crate pest;
    
    use pest::Parser;
    
    #[cfg(debug_assertions)]
    const _GRAMMAR: &'static str = include_str!("grammar.pest");
    
    #[derive(Parser)]
    #[grammar = "grammar.pest"]
    pub struct MyParser;
    
    fn parse_string(s: &str) {
        match MyParser::parse_str(Rule::foo, s) {
            Ok(o) => println!("ok: {:?}", o),
            Err(e) => println!("err: {}", e),
        }
    }
    
    fn main() {
        parse_string("a");
        parse_string("aa");
    }
    

    The output when running this is

    err:  --> 1:1
      |
    1 | a
      | ^---
      |
      = expected foo
    ok: Pairs { pairs: [Pair { rule: foo, span: Span { start: 0, end: 2 }, inner: Pairs { pairs: [Pair { rule: a, span: Span { start: 0, end: 2 }, inner: Pairs { pairs: [] } }] } }] }
    

    I would expect The string "a" to parse correctly, and the string "aa" to fail parsing, but the parser does the opposite. What I think happens is this:

    1. Starting with the foo rule, soi ~ push("") matches, so the stack is now [""].
    2. The next step is ~ (aba | a), so the parser tries rule aba first.
    3. The parser sees that push("a") matches, so the stack is now ["", "a"].
    4. The parser sees that ~ "b" doesn't match, so aba doesn't match, so it goes back up to ~ (aba | a) and tries a next. Note that even though aba didn't match, it modified the stack.
    5. We're in rule a now. Since the top of the stack is "a", peek ~ "a" can only match the string "aa", not "a".
    6. In the "aa" example, the final part is ~ eoi, which matches.

    The surprising part is that even though aba didn't match, it still modified the stack. This seems like a bug. I would expect the stack to be left unmodified by expressions that don't match (i.e. restore the stack after the expression fails to match).

    In addition to (aba | a), aba in other expressions exhibits the same behavior, such as (aba? ~ a) and (!aba ~ a).

    Assuming this is a bug, here are a couple of strategies to fix this:

    1. One solution is to clone the stack at the beginning of each expression in a branch (expr?, expr1 | expr2, etc.) or !expr in the parser, and then if the expression fails to match, restore the stack from the clone. I wouldn't expect the clone to be very expensive because the stack only contains Span items (which are small), unless you're parsing a very deeply nested document which builds a large stack.

    2. Instead of cloning, another solution is to use a persistent stack that makes it possible to store past versions of the stack without cloning the whole thing. This is often implemented as a singly linked list, which comes with its own issues but would work.

    If the existing behavior is intentional, it should be better documented, and I would consider adding push_maybe and pop_maybe commands that only modify the stack if the expressions containing them match.

    I can spend some time on a fix or better documentation.

    opened by jturner314 17
  • Grammar file not found on workspace

    Grammar file not found on workspace

    I use pest in a crate of a workspace, so this crate has no src folder. I was forced to create an empty src subfolder in my crate so that pest could find my file, it's not clean.

    It's easy to reproduce this bug, create a new workspace project and try to import pest grammar file from a crate of workspace.

    bug question derive 
    opened by librelois 16
  • Fix error display if pos is after \n

    Fix error display if pos is after \n

    I had to add an API for moving a position back.

    An alternative would have been to modify skip_while to take a slice of std::str::pattern::Patterns instead of &[&str] and add a skip_back_while function that does the same but backwards. Then we could have skipped back until we hit a non-newline character.

    Should I do that instead?

    Fixes #348

    opened by flying-sheep 15
  • Breaking change between 2.1 and 2.4/2.5

    Breaking change between 2.1 and 2.4/2.5

    Describe the bug

    During this discussion Implicit expression · #761 I have discovered that there is a difference of behavior for the following syntax between pest 2.1 and pest 2.4/2.5, for now I don't know if it's the expected behavior or not. I open an issue to know how to decide this.

    To Reproduce For the following grammar:

    program = _{ SOI ~ implicit ~ EOI  }
    implicit= ${ or ~ (WHITESPACE+ ~ or )* }
    
    or  = !{ and ~ (or_op ~ and)+ | and }
    and = { comp ~ (and_op ~ comp)+ | comp }
    comp = { array ~ eq_op ~ array | array }
    
    array = ${ term }
    
    term = _{ ASCII_ALPHANUMERIC+ }
    or_op = { "||" }
    and_op = { "&&" }
    eq_op = { "=" }
    WHITESPACE = _{ " " | "\t" | NEWLINE }
    

    The input a a return this error for pest 2.4/2.5 :x: :

     --> 1:3
      |
    1 | a a
      |   ^---
      |
      = expected EOI, or_op, and_op, or eq_op
    

    Success for 2.1 :heavy_check_mark:

    Expected behavior

    Run without error and return two array.

    bug help-wanted needs-reproduction 
    opened by vincent-herlemont 1
  • Add to support `include!` for load partial for Pest grammars.

    Add to support `include!` for load partial for Pest grammars.

    Resolve #197 #333

    Example

    base.pest

    WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
    

    json.pest

    include!("base.pest")
    
    json = { ... }
    

    Will same as:

    WHITESPACE = _{ " " | "\t" | "\r" | "\n" }
    
    json = { ... }
    
    opened by huacnlee 3
  • Request: Insert doc comments from `.pest` file to the `Rule` struct.

    Request: Insert doc comments from `.pest` file to the `Rule` struct.

    It would be incredibly helpful if the Rule struct and its variants have documentation to assist user.

    Example

    //! Documentation of the Rule struct itself.
    
    /// Documentation of the `my_rule` variant.
    my_rule - { ... }
    

    should generate:

    /// Documentation of the Rule struct itself.
    enum Rule {
        /// Documentation of the `my_rule` variant.
        my_rule,
    }
    
    enhancement pest generator 
    opened by KSXGitHub 0
  • [feature] Generating constant str rules

    [feature] Generating constant str rules

    Problem

    Often the grammar requires some constant strings in it (keywords, operators, etc). These can be introduced as a separate rule, example:

    return_type_operator = { "->" }
    function_keyword = { "fn" }
    

    and then reused in some other rules. When parsing and then generating the AST, these constant tokens are lost (which is obviously a good thing). But when we want to serialize the AST back to its code form we need these constant tokens. Since pest does not generate these constant strings as public (they are inlined), one could not reuse them. The final solution is to redefine them, for example by attaching them to the AST nodes:

    impl FunctionNode {
    	const KEYWORD: &str = "fn";
    }
    

    This leads to a problem when we want to change a constant string; we need to remember to change it in both places.

    Proposal

    Pest could detect const rules and generate constants for them, for example:

    // After #[derive(Parser)]
    impl Constants {
    	const return_type_operator: &str = "->";
    	const function_keyword: &str = "fn";
    }
    

    I see two paths that can be taken here:

    1. If a rule is composed of a single literal string, we generate a constant for it
    2. If the rule can be evaluated as const, we generate a constant for it

    Path 2 is obviously preferred, but harder to implement: then there would be a need of some const eval engine. For instance, a rule is constant if all rules used inside are constant, if the repetition count is constant, etc. Then a the rule would be have to be evaluated to a single final constant string.

    I don't know the codebase at all, but I'm pretty sure I would be able to implement path 1 and send a PR for it if it is wanted. I would only worry about whether such a primitive feature would feel incomplete compared to path 2.

    enhancement generator derive 
    opened by shilangyu 3
  • Performance issues/timeouts on some grammars

    Performance issues/timeouts on some grammars

    Possibly related issues:

    • https://github.com/pest-parser/pest/issues/675
    • https://github.com/pest-parser/pest/issues/603
    • https://github.com/pest-parser/pest/issues/571
    • https://github.com/pest-parser/pest/issues/402
    • https://github.com/pest-parser/pest/issues/279

    Suggestions from @dragostis :

    Ideally, the optimizer should be able to detect all exponential cases and have replacement rules for them. Maybe someone could take a look at egg and implement a simplified version of the grammar there so peephole optimizations can be more easily written?

    plus more context on why packrat parsing wasn't used: https://github.com/pest-parser/pest/pull/684#issuecomment-1210310442

    bug help-wanted pest runtime-performance 
    opened by tomtau 0
  • [feature request] Character separated list

    [feature request] Character separated list

    Could we have a grammar for that? Something similar to this:

    arguments = { argument * "," }
    ipv4 = @{ ASCII_DIGIT{1,3} {3} "." }
    

    (There should be better design but this is just an illustration.)

    enhancement maybe grammar 
    opened by StarlightIbuki 0
Releases(v2.5.2)
  • v2.5.2(Dec 23, 2022)

    What's Changed

    • Allow use of rust keywords as pest rules by @DvvCz in https://github.com/pest-parser/pest/pull/750
    • Add Unicode Script into built-in rules. by @huacnlee in https://github.com/pest-parser/pest/pull/751

    New Contributors

    • @DvvCz made their first contribution in https://github.com/pest-parser/pest/pull/750

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.5.1...v2.5.2

    Happy Holidays and Best Wishes for 2023! ☃️🎄 🎆

    Source code(tar.gz)
    Source code(zip)
  • v2.5.1(Dec 2, 2022)

    What's Changed

    • Fix unexpected argument panic in pest_debugger by @dffdff2423 in https://github.com/pest-parser/pest/pull/740
    • ci: add pest_debugger to semver checks by @tomtau in https://github.com/pest-parser/pest/pull/741
    • doc: fix tables of (non-)terminals by @birkenfeld in https://github.com/pest-parser/pest/pull/743
    • doc: explain that matching is greedy without backtracking by @birkenfeld in https://github.com/pest-parser/pest/pull/744
    • perf: add a faster skip_until using SIMD memchr by @tomtau in https://github.com/pest-parser/pest/pull/745 it can be enabled by using the memchr feature.

    New Contributors

    • @dffdff2423 made their first contribution in https://github.com/pest-parser/pest/pull/740

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.5.0...v2.5.1

    Source code(tar.gz)
    Source code(zip)
  • v2.5.0(Nov 24, 2022)

    What's Changed

    • chore: clippy fixes and ignores by @tomtau in https://github.com/pest-parser/pest/pull/733
    • ci: add CIFuzz GitHub action by @DavidKorczynski in https://github.com/pest-parser/pest/pull/738
    • feature: added a pest_debugger crate (fixes #98) by @dragostis and @tomtau in https://github.com/pest-parser/pest/pull/736

    New Contributors

    • @DavidKorczynski made their first contribution in https://github.com/pest-parser/pest/pull/738

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.4.1...v2.5.0

    Accidental breakage of semantic versioning since v2.2.0 in pest_meta

    We found out that, in addition to a breaking change in pest that was reverted, there were a few breaking changes in pest_meta in v2.2.0:

    • pest_meta::validator::validate_undefined now takes 2 parameters instead of 3,
    • pest_meta::validator::validate_pest_keywords now takes 1 parameter instead of 2,
    • and pest_meta::validator::validate_rust_keywords now takes 1 parameter instead of 2.

    Given pest_meta is primarily used within pest's own crates[^1] and no one opened an issue regarding these breaking changes, we decided not to revert the post-2.2.0 releases and keep those functions as they are now in 2.5.0[^2].

    Having said that, we now have a CI action to check for semantic versioning, so we should be able to avoid accidental breaking changes in the future.

    [^1]: Those three pest_meta functions are rather internal and perhaps did not need to be made public early on.

    [^2]: If these accidental pest_meta breaking changes cause any trouble in your code, please feel free to open an issue though!

    Introducing a new grammar debugger CLI and crate (pest_debugger)

    While pest's focus is on accessibility, developers can sometimes struggle to understand what is going under the hood and why a particular input is parsed in a particular way (or fails to parse). A long time ago, @dragostis implemented a simple CLI debugger that could help in this aspect, but this effort was not finished. This implementation was revived and you are now welcome to use it. You should be able to install it using:

    cargo install pest_debugger
    

    You can then run the interactive debugger by calling pest_debugger and view its help by typing h in its prompt:

    > h
    
    Use the following commands:
    g <grammar filename>          - load .pest grammar
    i <input filename>            - load input from a file
    id <input text>               - load input directly from a single-line input
    ba                            - add breakpoints at all rules
    b <rule>                      - add a breakpoint at a rule
    d <rule>                      - delete a breakpoint at a rule
    da                            - delete all breakpoints
    r <rule>                      - run a rule
    c                             - continue
    l                             - list breakpoints
    h                             - help
    

    The commands are self-explanatory; for a quick reference, the basic usage is:

    > g ...file path to your grammar...
    > i ...file path to your input...
    > b ...name of the rule you want to stop at...
    > r ...the rule to start running at...
    

    :bulb: There is a tab completion for file paths and command history.

    And then, once the debugger hits a breakpoint, you can continue the execution by typing:

    > c
    

    :bulb: You can also start up the debugger with command-line arguments that will do those steps during initialisation:

    Usage: pest_debugger [options]
    
    Options:
    -g, --grammar <grammar file>    - load .pest grammar
    -i, --input <input file>        - load input file
    -r, --rule <rule>               - run rule
    -b, --breakpoint <rule>         - breakpoint at rule
    -s, --session <session file>    - load session history file
    -h, --help                      - print this help menu
    

    Looking for a side project?

    If you are using pest in your projects and would like to contribute to its development by organising its issues, reviewing its pull requests etc., please feel free to comment on this post to join the triage team!

    In addition to that, here are also a few potential ideas for work that can help anyone who would like to get familiar with pest's implementation:

    Does any of these ideas sound interesting to you and would like to work on them? Or do you have other pest-related ideas you are working on or would like to explore? Please don't hesitate to share them in the comments below the announcement!

    Source code(tar.gz)
    Source code(zip)
  • v2.4.1(Nov 4, 2022)

    What's Changed

    • Update deps and switch to 2021 edition by @lwandrebeck in https://github.com/pest-parser/pest/pull/715
    • feature: added http request grammar by @tomtau in https://github.com/pest-parser/pest/pull/726
    • Update README.md by @carnoxen in https://github.com/pest-parser/pest/pull/728
    • doc: improve documentation by @tomtau in https://github.com/pest-parser/pest/pull/730

    New Contributors

    • @carnoxen made their first contribution in https://github.com/pest-parser/pest/pull/728

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.4.0...v2.4.1

    pest.rs domain is back!

    Big thanks to all contributors on GitHub Sponsors and on Open Collective! 🙏

    Source code(tar.gz)
    Source code(zip)
  • v2.4.0(Oct 1, 2022)

    What's Changed

    • chore: update to unicode 15 by @tomtau in https://github.com/pest-parser/pest/pull/709
    • feature: unary prefix/suffix operator support via PrattParser by @segeljakt in https://github.com/pest-parser/pest/pull/710

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.3.1...v2.4.0

    Source code(tar.gz)
    Source code(zip)
  • v2.3.1(Sep 12, 2022)

    What's Changed

    • fix: Search for grammar file from CARGO_MANIFEST_DIR by @Nukesor in https://github.com/pest-parser/pest/pull/702
    • Use new sha-1 package name by @davidkna in https://github.com/pest-parser/pest/pull/704
    • fix: speed up Position::line_col for large inputs using SIMD by @tomtau in https://github.com/pest-parser/pest/pull/707

    pest crate now has an optional fast-line-col feature flag which will speed up Position::line_col calculations. Note that this feature brings two extra dependencies and may incur extra overheads on small inputs.

    New Contributors

    • @Nukesor made their first contribution in https://github.com/pest-parser/pest/pull/702
    • @davidkna made their first contribution in https://github.com/pest-parser/pest/pull/704

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.3.0...v2.3.1

    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Aug 21, 2022)

    What's Changed

    • More ways for users to manipulate Span (https://github.com/pest-parser/pest/pull/681 https://github.com/pest-parser/pest/pull/682)
    • An optional call limit setting for parser state execution (https://github.com/pest-parser/pest/pull/684)
    • A breaking change of v2.2.x from v2.1.x was fixed, i.e. a trait bound was removed from Error type (https://github.com/pest-parser/pest/pull/694)

    New Contributors

    • @Alextopher made their first contribution in https://github.com/pest-parser/pest/pull/681
    • @kianmeng made their first contribution in https://github.com/pest-parser/pest/pull/688

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.2.1...v2.3.0

    Source code(tar.gz)
    Source code(zip)
  • v2.2.1(Jul 29, 2022)

    What's Changed

    • reverted https://github.com/pest-parser/pest/pull/522 by @tomtau in https://github.com/pest-parser/pest/pull/673

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.2.0...v2.2.1

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Jul 29, 2022)

    What's Changed

    • Unicode 14 support
    • sha-1 upgraded and unnecessary dependencies removed
    • code quality improvements and migration to the 2018 edition
    • benchmark code migrated to criterion
    • optimizations (see https://github.com/pest-parser/pest/pull/473 and https://github.com/pest-parser/pest/pull/554 )
    • no_std compatibility
    • error reporting improvements (using thiserror, better printing, API improvements)
    • allowing infix operators in prefix expressions

    New Contributors

    • @yamafaktory made their first contribution in https://github.com/pest-parser/pest/pull/361
    • @cch123 made their first contribution in https://github.com/pest-parser/pest/pull/368
    • @adamAndMath made their first contribution in https://github.com/pest-parser/pest/pull/371
    • @Nadrieril made their first contribution in https://github.com/pest-parser/pest/pull/375
    • @golddranks made their first contribution in https://github.com/pest-parser/pest/pull/395
    • @PvdBerg1998 made their first contribution in https://github.com/pest-parser/pest/pull/403
    • @alex made their first contribution in https://github.com/pest-parser/pest/pull/406
    • @roblabla made their first contribution in https://github.com/pest-parser/pest/pull/410
    • @cr0sh made their first contribution in https://github.com/pest-parser/pest/pull/408
    • @Schaeff made their first contribution in https://github.com/pest-parser/pest/pull/404
    • @shnewto made their first contribution in https://github.com/pest-parser/pest/pull/422
    • @bookmoons made their first contribution in https://github.com/pest-parser/pest/pull/412
    • @gkelly made their first contribution in https://github.com/pest-parser/pest/pull/435
    • @nagisa made their first contribution in https://github.com/pest-parser/pest/pull/442
    • @pr2502 made their first contribution in https://github.com/pest-parser/pest/pull/445
    • @jakubadamw made their first contribution in https://github.com/pest-parser/pest/pull/465
    • @MarinPostma made their first contribution in https://github.com/pest-parser/pest/pull/454
    • @SkiFire13 made their first contribution in https://github.com/pest-parser/pest/pull/480
    • @teymour-aldridge made their first contribution in https://github.com/pest-parser/pest/pull/470
    • @MaxBondABE made their first contribution in https://github.com/pest-parser/pest/pull/486
    • @rafael-patronilo made their first contribution in https://github.com/pest-parser/pest/pull/468
    • @01mf02 made their first contribution in https://github.com/pest-parser/pest/pull/498
    • @lucperkins made their first contribution in https://github.com/pest-parser/pest/pull/487
    • @mitnk made their first contribution in https://github.com/pest-parser/pest/pull/511
    • @nkreipke made their first contribution in https://github.com/pest-parser/pest/pull/514
    • @kaikalii made their first contribution in https://github.com/pest-parser/pest/pull/534
    • @mrtnzlml made their first contribution in https://github.com/pest-parser/pest/pull/532
    • @huacnlee made their first contribution in https://github.com/pest-parser/pest/pull/529
    • @tmandry made their first contribution in https://github.com/pest-parser/pest/pull/522
    • @Turbo87 made their first contribution in https://github.com/pest-parser/pest/pull/537
    • @aofdev made their first contribution in https://github.com/pest-parser/pest/pull/538
    • @NoahTheDuke made their first contribution in https://github.com/pest-parser/pest/pull/556
    • @Anton-4 made their first contribution in https://github.com/pest-parser/pest/pull/561
    • @andybest made their first contribution in https://github.com/pest-parser/pest/pull/562
    • @Geobert made their first contribution in https://github.com/pest-parser/pest/pull/575
    • @bryantbiggs made their first contribution in https://github.com/pest-parser/pest/pull/585
    • @jwpjrdev made their first contribution in https://github.com/pest-parser/pest/pull/592
    • @tomtau made their first contribution in https://github.com/pest-parser/pest/pull/609
    • @bobbbay made their first contribution in https://github.com/pest-parser/pest/pull/641
    • @abhimanyu003 made their first contribution in https://github.com/pest-parser/pest/pull/567

    Full Changelog: https://github.com/pest-parser/pest/compare/v2.1.0...v2.2.0

    Source code(tar.gz)
    Source code(zip)
  • v2.1.3-generator(Mar 13, 2020)

  • v2.1.3-pest(Feb 22, 2020)

  • v2.1.3-meta(Feb 22, 2020)

  • v2.1.2-generator(Feb 22, 2020)

  • v2.1.2-pest(Sep 2, 2019)

  • v2.1.2-meta(Sep 2, 2019)

  • v2.1.1-generator(Sep 2, 2019)

  • v2.1.1-pest(Apr 15, 2019)

  • v2.1.1-meta(Apr 15, 2019)

  • v2.1.0(Dec 21, 2018)

  • v2.0.2-pest(Oct 21, 2018)

  • v2.0.3-meta(Oct 2, 2018)

  • v2.0.2-meta(Oct 2, 2018)

  • v2.0.1-pest(Oct 2, 2018)

  • v2.0.1-derive(Oct 1, 2018)

  • v2.0.1-meta(Sep 30, 2018)

  • v2.0.0(Sep 30, 2018)

    We're happy to release pest 2.0!

    While there are a lot of changes that came into this release, here are some of the highlights:

    • improved performance significantly
    • revamped error reporting
    • improved grammar validation to a point where almost all degenerate grammars are now rejected
    • improved stack behavior so that you can now define whitespace-aware languages
    • added unicode builtin rules and other helpers
    • pest_meta crate for parsing, validating, and optimizing grammars
    • pest_vm crate for running grammars on-the-fly
    • finally removed funky const _GRAMMAR paper-cut
    • errors are now owned and much easier to use
    • made EOI non-silent for better error reporting
    • changed special rules to be SHOUT_CASE (e.g. ANY, WHITESPACE)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.7(Mar 31, 2018)

  • v1.0.6(Mar 25, 2018)

  • v1.0.3(Jan 26, 2018)

  • v1.0.2(Jan 22, 2018)

Owner
pest
The Elegant Parser
pest
Yet Another Parser library for Rust. A lightweight, dependency free, parser combinator inspired set of utility methods to help with parsing strings and slices.

Yap: Yet another (rust) parsing library A lightweight, dependency free, parser combinator inspired set of utility methods to help with parsing input.

James Wilson 117 Dec 14, 2022
Website for Microformats Rust parser (using 'microformats-parser'/'mf2')

Website for Microformats Rust parser (using 'microformats-parser'/'mf2')

Microformats 5 Jul 19, 2022
A native Rust port of Google's robots.txt parser and matcher C++ library.

robotstxt A native Rust port of Google's robots.txt parser and matcher C++ library. Native Rust port, no third-part crate dependency Zero unsafe code

Folyd 72 Dec 11, 2022
Rust parser combinator framework

nom, eating data byte by byte nom is a parser combinators library written in Rust. Its goal is to provide tools to build safe parsers without compromi

Geoffroy Couprie 7.6k Jan 7, 2023
url parameter parser for rest filter inquiry

inquerest Inquerest can parse complex url query into a SQL abstract syntax tree. Example this url: /person?age=lt.42&(student=eq.true|gender=eq.'M')&

Jovansonlee Cesar 25 Nov 2, 2020
Parsing Expression Grammar (PEG) parser generator for Rust

Parsing Expression Grammars in Rust Documentation | Release Notes rust-peg is a simple yet flexible parser generator that makes it easy to write robus

Kevin Mehall 1.2k Dec 30, 2022
A fast monadic-style parser combinator designed to work on stable Rust.

Chomp Chomp is a fast monadic-style parser combinator library designed to work on stable Rust. It was written as the culmination of the experiments de

Martin Wernstål 228 Oct 31, 2022
A parser combinator library for Rust

combine An implementation of parser combinators for Rust, inspired by the Haskell library Parsec. As in Parsec the parsers are LL(1) by default but th

Markus Westerlind 1.1k Dec 28, 2022
LR(1) parser generator for Rust

LALRPOP LALRPOP is a Rust parser generator framework with usability as its primary goal. You should be able to write compact, DRY, readable grammars.

null 2.4k Jan 7, 2023
A typed parser generator embedded in Rust code for Parsing Expression Grammars

Oak Compiled on the nightly channel of Rust. Use rustup for managing compiler channels. You can download and set up the exact same version of the comp

Pierre Talbot 138 Nov 25, 2022
Rust query string parser with nesting support

What is Queryst? This is a fork of the original, with serde and serde_json updated to 0.9 A query string parsing library for Rust inspired by https://

Stanislav Panferov 67 Nov 16, 2022
A fast, extensible, command-line arguments parser

parkour A fast, extensible, command-line arguments parser. Introduction ?? The most popular argument parser, clap, allows you list all the possible ar

Ludwig Stecher 18 Apr 19, 2021
Soon to be AsciiDoc parser implemented in rust!

pagliascii "But ASCII Doc, I am Pagliascii" Soon to be AsciiDoc parser implemented in rust! This project is the current implementation of the requeste

Lukas Wirth 49 Dec 11, 2022
An LR parser generator, implemented as a proc macro

parsegen parsegen is an LR parser generator, similar to happy, ocamlyacc, and lalrpop. It currently generates canonical LR(1) parsers, but LALR(1) and

Ömer Sinan Ağacan 5 Feb 28, 2022
A rusty, dual-wielding Quake and Half-Life texture WAD parser.

Ogre   A rusty, dual-wielding Quake and Half-Life texture WAD parser ogre is a rust representation and nom parser for Quake and Half-Life WAD files. I

Josh Palmer 16 Dec 5, 2022
A modern dialogue executor and tree parser using YAML.

A modern dialogue executor and tree parser using YAML. This crate is for building(ex), importing/exporting(ex), and walking(ex) dialogue trees. convo

Spencer Imbleau 27 Aug 3, 2022
A friendly parser combinator crate

Chumsky A friendly parser combinator crate that makes writing LL-1 parsers with error recovery easy. Example Here follows a Brainfuck parser. See exam

Joshua Barretto 2.4k Jan 8, 2023
Minimalist pedantic command line parser

Lexopt Lexopt is an argument parser for Rust. It tries to have the simplest possible design that's still correct. It's so simple that it's a bit tedio

Jan Verbeek 155 Dec 28, 2022
Universal configuration library parser

LIBUCL Table of Contents generated with DocToc Introduction Basic structure Improvements to the json notation General syntax sugar Automatic arrays cr

Vsevolod Stakhov 1.5k Jan 7, 2023