Skip to content

Commit

Permalink
Cucumber Expressions AST into Regex expansion (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilslv committed Nov 22, 2021
1 parent b71500c commit 9cb8206
Show file tree
Hide file tree
Showing 9 changed files with 1,017 additions and 18 deletions.
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,39 @@ jobs:
# Testing #
###########

feature:
name: Feature
if: ${{ github.ref == 'refs/heads/main'
|| startsWith(github.ref, 'refs/tags/v')
|| !contains(github.event.head_commit.message, '[skip ci]') }}
strategy:
fail-fast: false
matrix:
feature:
- <none>
- into-regex
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true

- run: cargo +nightly update -Z minimal-versions

- run: cargo check --no-default-features
${{ matrix.feature != '<none>'
&& format('--features {0}', matrix.feature)
|| '' }}
env:
RUSTFLAGS: -D warnings

msrv:
name: MSRV
if: ${{ github.ref == 'refs/heads/main'
Expand Down Expand Up @@ -141,6 +174,7 @@ jobs:
name: Release on GitHub
needs:
- clippy
- feature
- msrv
- rustdoc
- rustfmt
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ All user visible changes to `cucumber-expressions` crate will be documented in t
### Added

- [Cucumber Expressions] AST and parser. ([#1])
- Expansion of [Cucumber Expressions] AST into [`Regex`] behind `into-regex` feature flag. ([#2])

[#1]: /../../pull/1
[#2]: /../../pull/2




[`Regex`]: https://docs.rs/regex

[Cucumber Expressions]: https://github.com/cucumber/cucumber-expressions#readme
[Semantic Versioning 2.0.0]: https://semver.org
14 changes: 13 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,22 @@ categories = ["compilers", "parser-implementations"]
keywords = ["cucumber", "expression", "expressions", "cucumber-expressions"]
include = ["/src/", "/LICENSE-*", "/README.md", "/CHANGELOG.md"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]

[features]
# Enables ability to expand AST into regex.
into-regex = ["either", "regex"]

[dependencies]
derive_more = { version = "0.99.16", features = ["as_ref", "deref", "deref_mut", "display", "error"], default_features = false }
derive_more = { version = "0.99.16", features = ["as_ref", "deref", "deref_mut", "display", "error", "from", "into"], default_features = false }
nom = "7.0"
nom_locate = "4.0"

# "into-regex" feature dependencies
either = { version = "1.6", optional = true }
regex = { version = "1.5", optional = true }

# TODO: Remove once `derive_more` 0.99.17 is released.
syn = "1.0.81"
36 changes: 32 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,32 @@
===============================

[![Documentation](https://docs.rs/cucumber-expressions/badge.svg)](https://docs.rs/cucumber-expressions)
[![CI](https://github.com/cucumber-rs/cucumber-expressions/workflows/CI/badge.svg?branch=master "CI")](https://github.com/cucumber-rs/cucumber-expressions/actions?query=workflow%3ACI+branch%3Amaster)
[![CI](https://github.com/cucumber-rs/cucumber-expressions/workflows/CI/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber-expressions/actions?query=workflow%3ACI+branch%3Amaster)
[![Rust 1.56+](https://img.shields.io/badge/rustc-1.56+-lightgray.svg "Rust 1.56+")](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html)
[![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance)

- [Changelog](https://github.com/cucumber-rs/cucumber-expressions/blob/main/CHANGELOG.md)

Rust implementation of [Cucumber Expressions].

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

```rust
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`].



Expand All @@ -27,7 +44,7 @@ single-expression = alternation
| optional
| parameter
| text-without-whitespace+
| whitespace
| whitespace+
text-without-whitespace = (- (text-to-escape | whitespace))
| ('\', text-to-escape)
text-to-escape = '(' | '{' | '/' | '\'
Expand All @@ -37,7 +54,8 @@ single-alternation = ((text-in-alternative+, optional*)
| (optional+, text-in-alternative+))+
text-in-alternative = (- alternative-to-escape)
| ('\', alternative-to-escape)
alternative-to-escape = ' ' | '(' | '{' | '/' | '\'
alternative-to-escape = whitespace | '(' | '{' | '/' | '\'
whitespace = ' '
optional = '(' text-in-optional+ ')'
text-in-optional = (- optional-to-escape) | ('\', optional-to-escape)
Expand All @@ -51,6 +69,13 @@ name-to-escape = '{' | '}' | '(' | '/' | '\'



## [`Regex`] Production Rules

Follows original [production rules].




## License

This project is licensed under either of
Expand All @@ -63,8 +88,11 @@ at your option.



[`Regex`]: https://docs.rs/regex

[AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
[Cucumber Expressions]: https://github.com/cucumber/cucumber-expressions#readme
[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus–Naur_form

[1]: https://github.com/cucumber/cucumber-expressions/issues/41
[2]: https://github.com/cucumber/cucumber-expressions/blob/main/ARCHITECTURE.md#production-rules
9 changes: 4 additions & 5 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,14 @@ pub enum SingleExpression<Input> {
/// [0]: crate#grammar
Parameter(Parameter<Input>),

/// Text without whitespaces.
/// [`text-without-whitespace+`][0] expression.
///
/// [0]: crate#grammar
Text(Input),

/// Whitespaces are treated as a special case to avoid placing every `text`
/// character in a separate [AST] node, as described in the
/// [grammar spec][0].
/// [`whitespace+`][0] expression.
///
/// [0]: crate#grammar
/// [AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
Whitespaces(Input),
}

Expand Down
Loading

0 comments on commit 9cb8206

Please sign in to comment.