Matching variables with spaces using cucumber anonymous expresion - cucumber

With a feature containing a Scenario Outline and an Example table like:
Feature: Demonstrate Issue
Scenario Outline: Parameters with spaces don't match
Given a variable containing <var>
Examples:
| var |
| No_Spaces |
| Some Spaces |
I'm struggling to match the <var> in my steps using cucumber expression with cucumberjs.
I know that the {string} parameter type requires double quotes rather than the angular brackets, but I expected the anonymous type to match:
Given('a variable containing {}', function(expectedVar) {
return true;
});
But it doesn't.
I know I can use the regex option:
Given(/^a variable containing (.*)$/, function(expectedVar) {
return true;
});
I would just like to know where I'm going wrong in my use of the anonymous parameter type.

Related

How can the scope of jq 'as' variables be extended to pass down inside functions?

With jq, I'm trying to use entries in one array to index into a separate array. A simple JSON input would look like this:
{
"myArray": [ "AA", "BB", "CC", "DD", "EE" ],
"myFlags": [ 4, 3, 2, 1, 0 ]
}
jq's nifty 'as' operator is then able to bring the myArray array into scope and the indexing works fine:
.myArray as $Array | .myFlags | .[] | $Array[.] ====> yields "EE","DD","CC","BB","AA"
So far so jq-manual. However, if I try and move the $Array array access down into a function, the as-variable scope disappears:
def myFun: $Array[.]; .myArray as $Array | .myFlags | .[] | myFun
jq: error: $Array is not defined at <top-level>, line 1:
def myFun: $Array[.]; .myArray as $Array | .myFlags | .[] | myFun
To get around this, I currently pass down a temporary JSON object containing both the index and the array:
def myFun: .a[.b]; .myArray as $Array | .myFlags | .[] | { a: $Array, b: . } | myFun
Though this works, I have to say I'm not hugely comfortable with it.
Really, this doesn't feel to me as though this is proper jq language behaviour. It seems to me that the 'as'-scope ought to persist down into invoked def-functions. :-(
Is there a better way of extending as-scope down into def-functions? Am I missing some jq subtlety?
It actually is possible to make an "as" variable visible inside a function without passing it in as a parameter (see "Lexical Scoping" below), but it is usually unnecessary, and in fact using "as" variables is often unnecessary as well.
Avoiding the "as" variable
You can simplify your original query to:
.myArray[.myFlags[]]
Using function arguments
You can write jq functions with one or more arguments. This is the appropriate way to parameterize filters.
The syntax is quite conventional except that for functions with more than one argument, the semicolon (";") is used as the argument separator, both in the function definitions and invocations.
Note also that jq function arguments can themselves be filters, e.g. you could write:
def myFun(array; $ix): array | .[$ix];
myFun(.myArray; .myFlags[])
Lexical scoping
Here's an example showing how an 'as' variable can be made visible inside a function:
[1,2] as $array | def myFun: $array[1]; myFun

Meaning for = in antlr4

I have a grammar like
rule1 : GO (count=DECIMAL)? ;
rule2 : name '=' expression
I dont understand the difference between '=' sign in rule1 and rule2
The assignment is a variable assignment. ANTLR4 will generate a member variable named count for you, which gets the DECIMAL token when matched (since it is optional, count might be empty/null).
You can use count for instance in your listener code to directly get that value, however you could also just use DECIMAL instead. So it's mostly useful for action code or predicates in your grammar. You can refer to such variables by using e.g. $count:
rule1: GO (count = DECIMAL)? { $count.toString().toInteger() < 4}?;
which matches only if GO is followed by a value less than 4.
Side note: toInteger() is just pseudo code here. Use your target's string-to-int conversion API.

the following sets of rules are mutually left-recursive

The sumScalarOperator gives me this error, it seems that antlr see it like a possible infinite recursion loop. How can i avoid it?
sumScalarOperator: function SUM_TOKEN function;
function :
| INTEGER_TOKEN
| NUMERIC_TOKEN
| sumScalarOperator
| ID;
ID : [A-Za-z_-] [a-zA-Z0-9_-]*;
INTEGER_TOKEN: [0-9]+;
NUMERIC_TOKEN: [0-9]+'.'[0-9]+ ;
ANTLR4 can't cope with mutually left-recursive rules, but it can rewrite single left-recursive rules automatically to eliminate the left-recursion, so you can just feed it with something like:
function : function SUM_TOKEN function # sumScalarOperator
| INTEGER_TOKEN # value
| NUMERIC_TOKEN # value
| ID # value
;
Replace the value label with anything you need.

Comma separated variable list in Xtext

I have a grammar for a specific DSL. Here is a snippet (written in Xtext):
Vars: 'var' (vars += Var)
Var: ID (',' ID) * ':' Type ';'
And here is an example input:
var
a,b,c : int;
d,e: bool;
I'm really interested in Xtend automatic code generation option and want to have a single object for every Variable, storing it's id and it's type. Using Xtex grammar synatx all I can do is :
Var: ids+=ID (',' ids+=ID)* ':' type =[Type] ';'
Meaning that I may have more than one ID in a single object. How can I store each 'a','b','c' in a single object?
It's not possible to store each variable together with it's type. You'd have to implement some logic that traverses your model to find the type. You could do this with derived properties on the Var itself.

Token empty when matching grammar although rule matched

So my rule is
/* Addition and subtraction have the lowest precedence. */
additionExp returns [double value]
: m1=multiplyExp {$value = $m1.value;}
( op=AddOp m2=multiplyExp )* {
if($op != null){ // test if matched
if($op.text == "+" ){
$value += $m2.value;
}else{
$value -= $m2.value;
}
}
}
;
AddOp : '+' | '-' ;
My test ist 3 + 4 but op.text always returns NULL and never a char.
Does anyone know how I can test for the value of AddOp?
In the example from ANTLR4 Actions and Attributes it should work:
stat: ID '=' INT ';'
{
if ( !$block::symbols.contains($ID.text) ) {
System.err.println("undefined variable: "+$ID.text);
}
}
| block
;
Are you sure $op.text is always null? Your comparison appears to check for $op.text=="+" rather than checking for null.
I always start these answers with a suggestion that you migrate all of your action code to listeners and/or visitors when using ANTLR 4. It will clean up your grammar and greatly simplify long-term maintenance of your code.
This is probably the primary problem here: Comparing String objects in Java should be performed using equals: "+".equals($op.text). Notice that I used this ordering to guarantee that you never get a NullPointerException, even if $op.text is null.
I recommend removing the op= label and referencing $AddOp instead.
When you switch to using listeners and visitors, removing the explicit label will marginally reduce the size of the parse tree.
(Only relevant to advanced users) In some edge cases involving syntax errors, labels may not be assigned while the object still exists in the parse tree. In particular, this can happen when a label is assigned to a rule reference (your op label is assigned to a token reference), and an error appears within the labeled rule. If you reference the context object via the automatically generated methods in the listener/visitor, the instances will be available even when the labels weren't assigned, improving your ability to report details of some errors.

Resources