Opened 7 years ago
Closed 5 years ago
#12085 closed Bugs (fixed)
(a - b) === (!b >> a) does not hold in X3
Reported by: | Owned by: | Joel de Guzman | |
---|---|---|---|
Milestone: | To Be Determined | Component: | spirit |
Version: | Boost 1.61.0 | Severity: | Problem |
Keywords: | Cc: |
Description
Following program checks that two grammars (GRAMMAR1 and GRAMMAR2) are giving the same result for x3 and qi. They don't.
GRAMMAR1 is (!b >> a), GRAMMAR2 is (a - b).
When x3 is used (USE_X3==1) output is:
1 d
1 abcd
When qi is used (USE_X3==0) output is:
1 abcd
1 abcd
#define USE_X3 1 #if USE_X3 == 1 #include <boost/spirit/home/x3.hpp> #else #include <boost/spirit/include/qi.hpp> #endif #include <iostream> #include <string> #include <vector> #define GRAMMAR1 !lexeme[keywords >> !(alnum | '_')] >> lexeme[(alpha | '_') >> *(alnum | '_')] #define GRAMMAR2 lexeme[(alpha | '_') >> *(alnum | '_')] - lexeme[keywords >> !(alnum | '_')] int main() { std::string str = "abcd"; auto end = str.end(); #if USE_X3 == 1 { using namespace boost::spirit::x3; symbols<> keywords({"k1", "k2", "k3"}); { std::string v; auto begin = str.begin(); bool full = boost::spirit::x3::parse(begin, end, GRAMMAR1, v) && begin == end; std::cout << full << " " << v << std::endl; } { std::string v; auto begin = str.begin(); bool full = boost::spirit::x3::parse(begin, end, GRAMMAR2, v) && begin == end; std::cout << full << " " << v << std::endl; } } #else { using namespace boost::spirit::qi; symbols<> keywords; keywords = "k1", "k2", "k3"; { std::string v; auto begin = str.begin(); bool full = boost::spirit::qi::parse(begin, end, GRAMMAR1, v) && begin == end; std::cout << full << " " << v << std::endl; } { std::string v; auto begin = str.begin(); bool full = boost::spirit::qi::parse(begin, end, GRAMMAR2, v) && begin == end; std::cout << full << " " << v << std::endl; } } #endif }
Change History (9)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Yes. What do you think about https://github.com/boostorg/spirit/pull/181/commits/1f6d6c61849e89527c9b7be0818a16ce4833e8cf ? Should this work in x3 or should it not in qi?
comment:3 by , 7 years ago
I'm not sure. I still need to investigate. That said, if this one is a TST issue, then the test should be minimized further. It will be confusing to conflate the TST issue and the (!b >> a) and (a - b) issue together.
comment:4 by , 7 years ago
I think all this can be minimized to -
static_assert(traits::is_substitute<fusion::deque<char, std::string>, std::string>::value == 1, "");
or even simpler
static_assert(traits::is_substitute<char, std::string>::value == 1, "");
Which is kind of makes sense - if we have a char, we can put it to a string.
If this compiles, then test passes. I've tried this by adding specialization
template <typename T, typename Attribute> struct is_substitute<T, Attribute, typename enable_if<is_container<Attribute> >::type> : is_substitute<typename mpl::eval_if < fusion::traits::is_sequence<T>, fusion::result_of::front<T>, mpl::identity<T> >::type, typename container_value<Attribute>::type> {};
follow-up: 6 comment:5 by , 7 years ago
So it's not a TST issue then. An is_substitute specialization would be easy to add.
comment:6 by , 7 years ago
Replying to djowel:
So it's not a TST issue then. An is_substitute specialization would be easy to add. Does your specialization compile? Seems too complicated.
comment:9 by , 5 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Is this a TST issue?