I don't know there similar question, or not.
How to simplify
(a == 78 || a == 98 || a == 73 || a == 11 || a == 90 || a==103 || a==45 )
expression to
MY_CHECK(a, (78, 98, 73, 11, 90, 103, 45) )
With boost preprocessor ??
Is there any ready solution in boost preprocessor.
I couldn't find better than a transform followed by a fold, since BOOST_PP_SEQ_FOLD_LEFT does not carry a data parameter around. Still:
#define MY_CHECK_FOLD_OR(s, a, b) a || b
#define MY_CHECK_FOLD_EQ(s, var, elem) (var) == (elem)
#define MY_CHECK(var, values) \
(BOOST_PP_SEQ_FOLD_LEFT( \
MY_CHECK_FOLD_OR, false, \
BOOST_PP_SEQ_TRANSFORM( \
MY_CHECK_FOLD_EQ, var, \
BOOST_PP_TUPLE_TO_SEQ(values) \
) \
))
... which expands:
if (MY_CHECK(a, (1, 2, 3)))
... into:
if ((false || (a) == (1) || (a) == (2) || (a) == (3)))
See it live on Coliru
There's no need to use the preprocessor here. A variadic template will do just fine. Here's an example using a C++17 fold expression:
template <typename Needle, typename... Haystack>
bool my_check(const Needle& needle, const Haystack&... haystack)
{
return ((needle == haystack) || ...);
}
live example on wandbox
Related
For example, if we want to check an array is either nil or empty, we can write as follows:
if !a || a.empty?
puts "nil or empty!"
end
#-> OK
however, if we want to check two arrays in the same way, an error occurs:
if !a || !b || a.empty? || b.empty?
puts "nil or empty!"
end
#-> Error, `undefined method 'empty?' for Nil`
# in the expression `a.empty?`
Swapping the position of !b and a.empty? doesn't help, but different place is pointed to as an error:
if !a || a.empty? || !b || b.empty?
puts "nil or empty!"
end
#-> Still error, `undefined method 'empty?' for Nil`
# but this error is in the expression `b.empty?`
Why in this (multiple variable's) case compiler can't infer that a and b are non-nil when a.empty? and b.empty? are called, respectively?
The whole reproducible code is following.
def foo (flag)
if flag
[] of Int32
else
nil
end
end
# note, foo returns `Array(T) | Nil`
a = foo(true)
b = foo(true)
if !a || a.empty?
puts "nil or empty!"
end
#-> OK
if !a || !b || a.empty? || b.empty?
puts "nil or empty!"
end
#-> Error, `undefined method 'empty?' for Nil`
# in the expression `a.empty?`
if !a || a.empty? || !b || b.empty?
puts "nil or empty!"
end
#-> Still error, `undefined method 'empty?' for Nil`
# but this error is in the expression `b.empty?`
It's not a bug.
a || b || c || d
is parsed as:
(((a || b) || c) || d)
so in your example you have:
!a || !b || a.empty? || b.empty?
which means it's
(((!a || !b) || a.empty?) || b.empty?)
so from:
!a || !b
you can't deduce anything about a or b.
It works if you add parentheses:
if !a || (!b || (a.empty? || b.empty?))
It seems like a compiler bug.
But you can just put the conditions in parenthesis to make it work: (!a || a.empty?) || (!b || b.empty?)
I am following this example: https://github.com/boostorg/spirit/blob/develop/example/x3/calc/calc9/expression_def.hpp
What I am trying to accomplish is to write a rule that parses and generates like min{x}{y}. Mostly the code is using expression grammar like x + y, but now I want to place and parse both operands to the rhs of the operator.
I added the following code in expression_def.hpp file:
...
x3::symbols<ast::optoken> additive_op;
x3::symbols<ast::optoken> multiplicative_op;
x3::symbols<ast::optoken> binarypost_op;
x3::symbols<ast::optoken> unary_op;
x3::symbols<> keywords;
...
binarypost_op.add
("min", ast::op_divide) // Dummy operation usage for now
;
...
struct binarypost_expr_class;
struct unary_expr_class;
...
typedef x3::rule<binarypost_expr_class, ast::expression>
binarypost_expr_type;
...
binarypost_expr_type const binarypost_expr = "binarypost_expr";
...
auto const multiplicative_expr_def =
binarypost_expr
>> *(multiplicative_op > binarypost_expr)
;
auto const binarypost_expr_def = // See the chaining operation
('{' > unary_expr > '}')
>> *(binarypost_op > ('{' > unary_expr > '}'))
;
auto const unary_expr_def =
primary_expr
| (unary_op > primary_expr)
;
This works fine. But it can only parse something like , {x} min {y}. I want to be able to parse min {x} {y}. I tried the many combinations such as :
binarypost_op >> ('{' > unary_expr > '}') > ('{' > unary_expr > '}') etc. But I cant seem to figure it out as to what is the right way to write this? Any suggestions / comments ?
Ok, here's the changes. The hard part is actually code-generating the builtin function.
Parsing
Step 1: extend AST
Always start with the AST. We want operands that can be function calls:
In ast.hpp:
struct function_call; // ADDED LINE
// ...
struct operand :
x3::variant<
nil
, unsigned int
, variable
, x3::forward_ast<unary>
, x3::forward_ast<expression>
, x3::forward_ast<function_call> // ADDED LINE
>
{
using base_type::base_type;
using base_type::operator=;
};
// ...
enum funtoken
{
fun_min,
fun_max,
};
// ...
struct function_call : x3::position_tagged
{
funtoken fun;
std::list<operand> args;
};
In ast_adapted.hpp:
BOOST_FUSION_ADAPT_STRUCT(client::ast::function_call,
fun, args
)
Step 2: extend grammar
(This is all in expression_def.hpp)
Let's be generic, so parse function name tokens using a symbol table:
x3::symbols<ast::funtoken> functions;
Which we have to initialize in add_keywords:
functions.add
("min", ast::fun_min)
("max", ast::fun_max)
;
Now declare a rule for function calls:
struct function_call_class;
typedef x3::rule<function_call_class, ast::function_call> function_call_type;
function_call_type const function_call = "function_call";
That's all red-tape. The "interesting thing" is the rule definition:
auto const function_call_def =
functions
>> '(' >> expression % ',' >> ')'
;
Well. That's underwhelming. Let's integrate into our primary expression rule:
auto const primary_expr_def =
uint_
| bool_
| function_call
| (!keywords >> identifier)
| ('(' > expression > ')')
;
Note the ordering. If you want to be able to add function names that collide with a keyword, you'll need to add precautions.
Also, lets make AST annotation work for our node:
struct function_call_class : x3::annotate_on_success {};
Code generation
It's easy to find where to add support for the new AST node:
In compiler.hpp:
bool operator()(ast::function_call const& x) const;
Now comes the hard part.
What's really required for general n-ary is an accumulator. Since we don't have registers, this would need to be a temporary (local). However, since the VM implementation doesn't have these, I've limited the implementation to a fixed binary function call only.
Note that the VM already has support for function calls. Functions can have locals. So, if you code-gen a variable-argument built-in function you can implement a left-fold recursive solution.
In compiler.cpp:
bool compiler::operator()(ast::function_call const& x) const
{
auto choice = [&](int opcode) {
BOOST_ASSERT(x.args.size() == 2); // TODO FIXME hardcoded binary builtin
auto it = x.args.begin();
auto& a = *it++;
if (!boost::apply_visitor(*this, a))
return false;
auto& b = *it++;
if (!boost::apply_visitor(*this, b))
return false;
program.op(opcode); // the binary fold operation
program.op(op_jump_if, 0);
size_t const branch = program.size()-1;
if (!boost::apply_visitor(*this, a))
return false;
program.op(op_jump, 0);
std::size_t continue_ = program.size()-1;
program[branch] = int(program.size()-branch);
if (!boost::apply_visitor(*this, b))
return false;
program[continue_] = int(program.size()-continue_);
return true;
};
switch (x.fun) {
case ast::fun_min: return choice(op_lt);
case ast::fun_max: return choice(op_gt);
default: BOOST_ASSERT(0); return false;
}
return true;
}
I've just taken inspiration from the surrounding code on how to generate the jump labels.
Trying It Out
A simplistic example would be: var x = min(1,3);
Assembler----------------
local x, #0
start:
op_stk_adj 1
op_int 1
op_int 3
op_lt
op_jump_if 13
op_int 1
op_jump 15
13:
op_int 3
15:
op_store x
end:
-------------------------
Results------------------
x: 1
-------------------------
Running it with some random contrived input:
./test <<< "var a=$(($RANDOM % 100)); var
b=$(($RANDOM % 100)); var contrived=min(max(27,2*a), 100+b);"
Prints e.g.:
Assembler----------------
local a, #0
local b, #1
local contrived, #2
start:
op_stk_adj 3
op_int 31
op_store a
op_int 71
op_store b
op_int 27
op_int 2
op_load a
op_mul
op_gt
op_jump_if 24
op_int 27
op_jump 29
24:
op_int 2
op_load a
op_mul
29:
op_int 100
op_load b
op_add
op_lt
op_jump_if 58
op_int 27
op_int 2
op_load a
op_mul
op_gt
op_jump_if 51
op_int 27
op_jump 56
51:
op_int 2
op_load a
op_mul
56:
op_jump 63
58:
op_int 100
op_load b
op_add
63:
op_store contrived
end:
-------------------------
Results------------------
a: 31
b: 71
contrived: 62
-------------------------
I am using this statement
if ((pm && pn) || (pm == false && pn == false))
it is supposed to return true only if both pm and pn are true or if both are false. But this is also returning true if only only first one (pm) is true.
So now it is acting like this:
0 0 = 1
0 1 = 0
1 0 = 1
1 1 = 1
but I need it to work like this:
0 0 = 1
0 1 = 0
1 0 = 0
1 1 = 1
can you tell me where am I making mistake?
What you want is simply:
if (pm == pn)
You are checking if pm is true twice. You also need to check if both are the same, not whether they are both true. So,
if ((pm == pn)
^^ ^^
pm && pm
should be
pm && pn
^
The whole expression can be simplified to
pm == pn
if the variables already have bool type.
Why not try xor?
if (!(pm ^ pn)) { /*...*/ }
Or simply equal?
if (pm == pn) { /*...*/ }
if ((pm && pm) || (pm == false && pn == false))
it is supposed to return true only if both pm and pn are true or if both are false. But this is also returning true if only only first one (pm) is true.
Because you made a typo. You meant pm && pn.
Instead just write if (pm == pn), which is equivalent along as the only semantic values are indeed true and false for both variables.
Plus, consider making your variable names clearer and more distinct.
Note that operator precedence has nothing to do with this.
Since the question's title asks about precedence, note that || has lower precedence than &&. So the two sets of inner parentheses are redundant, and the original expression is just a longer way of saying
if (pm && pm || pm == false && pn == false)
Now, fixing the obvious typo:
if (pm && pn || pm == false && pn == false)
Removing the unneeded explicit comparisons:
if (pm && pn || !pm && !pn)
And, finally, a less obvious transformation, which others have suggested:
if (pm == pn)
For each of the following write the equivalent C++ expressions, without any unary negation operators (!). (!= is still permitted)
Use DeMorgan's law
!( P && Q) = !P || !Q
!( P || Q) = !P && !Q
For
!(x!=5 && x!=7)
!(x<5 || x>=7)
!( !(a>3 && b>4) && (c != 5))
My answers:
(x>5 || x<5) || (x>7 || x<7)
x>=5 && x < 7
(a>3 && b > 4) && (c!=5)
Are these correct? If not, can you give me answers and explain why they are wrong?
I am a beginner in C++ so take it easy.
Check this out:
!(x!=5 && x!=7) --> x==5 || x==7
!(x<5 || x>=7) --> x>=5 && x<7
!( !(a>3 && b>4) && (c != 5)) --> (a>3 && b>4) || c==5
So, just #2 from your solutions is correct.
I have problem to make regExp for search panel
&& (item.get('prodAddDate') >= dateStartValue.format("Y-m-d"))
&& (item.get('prodAddDate') <= dateEndValue.format("Y-m-d"));
I'm not sure if this is task for refExp but don't have any other idea
Problem is that when I'm don't fill field with date I can't filtr data with other conditions
I was trying something like this but don't working
&& ((item.get('prodAddDate') >= dateStartValue.format("Y-m-d")) || (new RegExp(dateStartValue)).test(item.get('prodAddDate'))) &&
((item.get('prodAddDate') <= dateEndValue.format("Y-m-d")) || (new RegExp(dateEndValue)).test(item.get('prodAddDate')));
Not entirely sure what you're trying to do, but here are some pieces of information that I hope can help you to solve your problem.
Comparison operators priority
The && operator has priority over ||, which means that:
A || B && C || D
Is equivalent to:
A || (B && C) || D
Not to:
(A || B) && (C || D)
Date comparison
You can compare Date objects directly:
// example data
var d1 = new Date('2012-12-12'),
d2 = new Date('2012-12-12'),
d3 = new Date('2013-01-01');
And get the result you expect with <, >, <=, and >=:
// logical results
d1 < d3 // true
d1 < d2 // false
d2 > d3 // false
d1 <= d2 // true
d1 => d2 // true
But not with equality comparison ==:
d1 == d2 // false
// yet...
d1 <= d2 && d1 => d2 // true
Conclusion: to test if one date is before or after another one, direct comparison is OK. But, in order to test if two dates are identical, use string comparisons:
// is this the same day?
d1.format('Y-m-d') === d2.format('Y-m-d') // true
// is this the same day and hour?
d1.format('Y-m-d H:i:s') === d2.format('Y-m-d H:i:s') // true
Ext.isEmpty()
Ext.isEmpty returns true for: null, undefined and empty strings '' only.
Ext.isEmpty(null) // true
Ext.isEmpty(undefined) // true
Ext.isEmpty('') // true
Ext.isEmpty(' ') // false
Ext.isEmpty(false) // false
// etc.
That may be useful to address your empty field case:
...
&& (Ext.isEmpty(item.get('prodAddDate') || item.get('prodAddDate') >= dateStartValue)
&& (Ext.isEmpty(item.get('prodAddDate') || item.get('prodAddDate') <= dateEndValue)
Finally
What's this obsession about regex? They're useful for complex string testing/extracting, but that's all. You should probably forget about them for a while, dude ;p