7 unstable releases

0.3.0 Apr 24, 2023
0.2.1 Mar 9, 2022
0.2.0 Feb 10, 2022
0.1.2 Jan 11, 2022
0.0.0 Nov 5, 2021

#275 in Parser implementations

Download history 14815/week @ 2023-12-11 13713/week @ 2023-12-18 3657/week @ 2023-12-25 8918/week @ 2024-01-01 14742/week @ 2024-01-08 12794/week @ 2024-01-15 13071/week @ 2024-01-22 12318/week @ 2024-01-29 11769/week @ 2024-02-05 12972/week @ 2024-02-12 12972/week @ 2024-02-19 15837/week @ 2024-02-26 15061/week @ 2024-03-04 16420/week @ 2024-03-11 15697/week @ 2024-03-18 12919/week @ 2024-03-25

60,484 downloads per month
Used in 2 crates

MIT/Apache

145KB
3K SLoC

Cucumber Expressions for Rust

crates.io Rust 1.62+ Unsafe Forbidden
CI Rust docs

Rust implementation of Cucumber Expressions.

This crate provides AST parser, and Regex expansion of Cucumber Expressions.

# // `Regex` expansion requires `into-regex` feature.
# #[cfg(feature = "into-regex")] {
use cucumber_expressions::Expression;

let re = Expression::regex("I have {int} cucumbers in my belly").unwrap();
let caps = re.captures("I have 42 cucumbers in my belly").unwrap();

assert_eq!(&caps[0], "I have 42 cucumbers in my belly");
assert_eq!(&caps[1], "42");
# }

Cargo features

  • into-regex: Enables expansion into Regex.

Grammar

This implementation follows a context-free grammar, which isn't yet merged. Original grammar is impossible to follow while creating a performant parser, as it consists errors and describes not an exact Cucumber Expressions language, but rather some superset language, while being also context-sensitive. In case you've found some inconsistencies between this implementation and the ones in other languages, please file an issue!

EBNF spec of the current context-free grammar implemented by this crate:

expression              = single-expression*

single-expression       = alternation
                           | optional
                           | parameter
                           | text-without-whitespace+
                           | whitespace+
text-without-whitespace = (- (text-to-escape | whitespace))
                           | ('\', text-to-escape)
text-to-escape          = '(' | '{' | '/' | '\'

alternation             = single-alternation, (`/`, single-alternation)+
single-alternation      = ((text-in-alternative+, optional*)
                            | (optional+, text-in-alternative+))+
text-in-alternative     = (- alternative-to-escape)
                           | ('\', alternative-to-escape)
alternative-to-escape   = whitespace | '(' | '{' | '/' | '\'
whitespace              = ' '

optional                = '(' text-in-optional+ ')'
text-in-optional        = (- optional-to-escape) | ('\', optional-to-escape)
optional-to-escape      = '(' | ')' | '{' | '/' | '\'

parameter               = '{', name*, '}'
name                    = (- name-to-escape) | ('\', name-to-escape)
name-to-escape          = '{' | '}' | '(' | '/' | '\'

Regex Production Rules

Follows original production rules.

License

This project is licensed under either of

at your option.

Dependencies

~2–3MB
~65K SLoC