1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! # Cypress
//!
//! [](https://crates.io/crates/cypress)
//! [](https://docs.rs/cypress)
//!
//! Cypress is a parser combinator library for Rust, inspired by [FParsec] and [chumsky]. It aims to provide a
//! simple yet expressive framework for constructing parsers, especially for building small domain-specific
//! languages or interpreters.
//!
//! This library is still a work in progress, but it already supports recursive grammars, expressive combinators,
//! and error handling. Cypress emphasizes readability and composability, with an ergonomic macro-based DSL.
//!
//! ## Highlights
//!
//! - Recursive parsers via `recursive`
//! - Combinators for sequencing, mapping, branching, etc.
//! - Simple token-based parsing with custom input types
//! - Macros for more ergonomic parsing
//!
//! ## Example
//!
//! The following is a parser for [Brainfuck], demonstrating recursive parsing of a toy language:
//!
//! ```rust
//! use cypress::prelude::*;
//!
//! #[derive(Debug, Clone, PartialEq)]
//! enum Instruction {
//! Left,
//! Right,
//! Increment,
//! Decrement,
//! Read,
//! Write,
//! Loop(Vec<Self>),
//! }
//!
//! fn bf_parser<'a>() -> impl Parser<'a, u8, Vec<Instruction>> {
//! recursive(|expr| {
//! let instr = choice!(
//! select! {
//! '<' => Instruction::Left,
//! '>' => Instruction::Right,
//! '+' => Instruction::Increment,
//! '-' => Instruction::Decrement,
//! ',' => Instruction::Read,
//! '.' => Instruction::Write,
//! },
//! expr.many()
//! .between(just('['), just(']'))
//! .map(Instruction::Loop)
//! );
//!
//! Box::new(instr)
//! })
//! .many()
//! .until_end()
//! }
//!
//! let input = b"+++++[>>+<<-]".into_input();
//! let result = bf_parser().parse(input);
//! ```
//!
//! More examples, including interpreters and simple language grammars, can be found in the `/examples` folder.
//!
//! ## Getting Started
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml,ignore
//! cypress = "0.3.0"
//! ```
//!
//! Then import the prelude:
//!
//! ```rust
//! use cypress::prelude::*;
//! ```
//!
//! ## Feedback
//!
//! This is my first published project — ideas, feedback, and PRs are very welcome!
//!
//! ## License
//!
//! Cypress is licensed under the BSD 3-Clause License. See `LICENSE` for details.
//!
//! [FParsec]: https://www.quanttec.com/fparsec/
//! [chumsky]: https://docs.rs/chumsky
//! [Brainfuck]: https://gist.github.com/roachhd/dce54bec8ba55fb17d3a
/// The `parser` module contains the full implementation of the parser combinator library.
///
/// It exposes all core parser traits, combinators, and utilities for constructing
/// complex parsers from simple building blocks.
/// Common trait and implementations for parsing textlike values
/// Modules for displaying and organizing errors
/// The `prelude` module re-exports commonly used items from the parser library.
///
/// This module is intended for convenient import, allowing users to bring
/// essential parser combinators and utilities into scope with a single `use`.