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

#1760 in Parser implementations

Download history 24589/week @ 2024-07-24 22648/week @ 2024-07-31 21670/week @ 2024-08-07 20433/week @ 2024-08-14 19876/week @ 2024-08-21 18999/week @ 2024-08-28 25756/week @ 2024-09-04 21670/week @ 2024-09-11 25174/week @ 2024-09-18 22112/week @ 2024-09-25 24136/week @ 2024-10-02 18452/week @ 2024-10-09 25611/week @ 2024-10-16 26287/week @ 2024-10-23 136224/week @ 2024-10-30 142797/week @ 2024-11-06

335,013 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

~1.2–2.6MB
~54K SLoC