Comments (12)
Given the effective EBNF from #44:
cucumber-expression = (alternation
| optional
| parameter
| text)*
text = (- text-to-escape) | ('\', 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 = ' ' | '(' | '{' | '/' | '\'
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 = '{' | '}' | '(' | '/' | '\'
This would add
left-right-space-optional = ' ', '(', text-in-optional+, ')', ' '
left-space-optional = ' ', '(', text-in-optional+, ')'
right-space-optional = '(', text-in-optional+, ')', ' '
optional = '(', text-in-optional+, ')'
And the production rules
left-right-space-optional -> "(?:(?: " + rewrite(node[0]) + ... + rewrite(node[n-1]) + " )?| )"
left-space-optional ->"(?:(?: " + rewrite(node[0]) + ... + rewrite(node[n-1]) + ")?|)"
right-space-optional -> "(?:(?:" + rewrite(node[0]) + ... + rewrite(node[n-1]) + " )?|)"
I don't immediately see any problems with this. Unfortunately the current parser structure does implement this EBNF, but doesn't match its structure so adding it would be a little bit trickier.
from cucumber-expressions.
Maybe not:
(a) (b) (c)
Would produce right-space-optional
, left-space-optional
, left-space-optional
and should match
a
a b
a c
a b c
b
b c
c
But won't match b
because it is not a left-space-optional
.
from cucumber-expressions.
But won't match
b
because it is not aleft-space-optional
.
Iβm not sure if I understand this. Would then cucumber(s) in my belly
produce a right-space-optional
and thus wonβt match cucumber in my belly
anymore?
from cucumber-expressions.
Worse, it would match cucumberin my belly
because the space is now optional.
I'm not good at EBNFs, but I think left-space-optional
and right-space-optional
would have to be anchored to the start and end of a line. So that means pulling it up to the cucumber-expression
.
cucumber-expression = right-space-optional?, (alternation
| optional
| parameter
| text)*,
left-space-optional?
from cucumber-expressions.
Mmh. But what about this trainwreck
hello\ (beautiful)\ world/good\ bye
This should match
hello world
hello beautiful world
good bye
But that will be tricky because the \
would be captured by both the alternative-to-escape
and left-right-space-optional
.
Or with the first \
removed.
hello (beautiful)\ world/good\ bye
This should match
hello world
hello beautiful world
hello good bye
But the (beautiful)\
would have to be some right-space-optional
variant that can be used in alternation
.
from cucumber-expressions.
cucumber-expression = right-space-optional?, (alternation | optional | parameter | text)*, left-space-optional?
Would then a (b) c
even be a cucumber-expression
? According to that code, text
canβt be at both sides of a β¦-space-optional
, can it?
from cucumber-expressions.
No, you're right. I'm being incredibly sloppy.
cucumber-expression = right-space-optional?, (alternation
| left-right-space-optional
| optional
| parameter
| text)*,
left-space-optional?
And then to handle variants like a (b)\ c/d
:
alternation = left-space-right-space-escaped-optional?, single-alternation, ('/', single_alternation)+, left-space-escaped-right-space-optional
single-alternation = ((text-in-alternative+, optional-in-alternation*)
| (optional-in-alternation+, text-in-alternative+))+
optional-in-alternation = left-space-escaped-right-space-escaped-optional | optional
I think.
Doesn't look like a simple change. π
from cucumber-expressions.
I guess we could reduce the complexity of this enhancement a lot, if we introduced only left-space-optional
but not right-space-optional
. What do you think?
I guess the only downside of this simplified approach is that it does not help with braces at the beginning of the cucumber expression. On the other hand, I cannot find a good example where this matters.
from cucumber-expressions.
Any hope for this one? π
from cucumber-expressions.
Bit hard to say, I'm trying to get a bit of a workflow setup so I'm not the sole decision maker.
Though given that this is a relatively large amount of work (compared to the available time) and given that between duplicating step definitions and/or using regex there are reasonable alternatives if we do think this is a good idea, we might only solicit a pull request.
from cucumber-expressions.
Thanks for the reply. I see. I am already using this feature a lot, enabled by my workaround (in TypeScript):
function toCucumberExpOrRegExp(description: string | RegExp) {
return typeof description === 'string' ? description.replace(' (', '( ') : description;
}
There might be exotic cases where this does not work, though.
from cucumber-expressions.
FWIW this makes intuitive sense to me to support it. It's often frustrated me too.
I'm not deep enough in the implementation to understand the implied complexity of making it happen (so it's easy for me to say!) though I'd be happy to pair with someone who is and see if I can add anything.
from cucumber-expressions.
Related Issues (20)
- Remove Python example illustrating how to define parameter types HOT 2
- Allow free-form text in optionals HOT 1
- Expression for an argument list HOT 4
- Improve Expression creation performance HOT 2
- Use action-publish-pypi in cucumber-expressions
- Optimize Cucumber expression creation in .Net implementation
- Action Required: Fix Renovate Configuration
- Bad CucumberExpression creation performance HOT 6
- Golang big.Float is not a big decimal HOT 12
- Feature: named capture groups HOT 13
- Missing source for source map
- RegEx "expressions" and defineParameterType feature file examples ?
- Add the ability to ignore a cucumber expression parameter just like a non capturing regex HOT 12
- Nested capture groups are not passed to custom param definition transformer HOT 8
- `end` as a method name / prop can cause some issues HOT 4
- LICENSE file is empty HOT 1
- Typo in error message for use of alternation inside an optional
- Unable to parse negative number in Norwegian HOT 11
- Released Ruby gem is missing LICENSE file. HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cucumber-expressions.