Search code examples
c++visual-studioboostboost-spiritboost-spirit-qi

boost spirit qi parser failed in release and pass in debug


 #include <boost/spirit/include/qi.hpp>
 #include <string>
 #include <vector>
 #include <iterator>
 #include <algorithm>
 #include <iostream>
using namespace boost::spirit;
int main()
{
std::string s;
std::getline(std::cin, s);
auto specialtxt = *(qi::char_('-', '.', '_'));
auto txt = no_skip[*(qi::char_("a-zA-Z0-9_.\\:$\'-"))];
auto anytxt = *(qi::char_("a-zA-Z0-9_.\\:${}[]+/()-"));
qi::rule <std::string::iterator, void(),ascii::space_type> rule2 = txt     ('=') >> ('[') >> (']');
auto begin = s.begin();
auto end = s.end();
if (qi::phrase_parse(begin, end, rule2, ascii::space))
{
    std::cout << "MATCH" << std::endl;
}
else
{
    std::cout << "NO MATCH" << std::endl;
}

}

this code works fine in debug mode parser fails in release mode rule is to just parse text=[]; any thing else than this should fail it works fine in debug mode but not in release mode it shows result no match for any string.

if i enter string like

abc=[];

this passes in debug as expected but fails in release


Solution

  • You can't use auto with Spirit v2:

    You have Undefined Behaviour

    DEMO

    I tried to make (more) sense of the rest of the code. There were various instances that would never work:

    1. txt('=') is an invalid Qi expression. I assumed you wanted txt >> ('=') instead

    2. qi::char_("a-zA-Z0-9_.\\:$\\-{}[]+/()") doesn't do what you think because $-{ is actually the character "range" \x24-\x7b... Escape the - (or put it at the very end/start of the set like in the other char_ call).

    3. qi::char_('-','.','_') can't work. Did you mean qi::char_("-._")?

    4. specialtxt and anytxt were unused...

    5. prefer const_iterator

    6. prefer namespace aliases above using namespace to prevent hard-to-detect errors

    Live On Coliru

    #include <boost/spirit/include/qi.hpp>
    #include <iostream>
    
    namespace qi = boost::spirit::qi;
    
    int main() {
        std::string const s = "abc=[];";
    
        auto specialtxt = qi::copy(*(qi::char_("-._")));
        auto anytxt     = qi::copy(*(qi::char_("a-zA-Z0-9_.\\:$\\-{}[]+/()")));
        (void) specialtxt;
        (void) anytxt;
    
        auto txt        = qi::copy(qi::no_skip[*(qi::char_("a-zA-Z0-9_.\\:$\'-"))]);
    
        qi::rule<std::string::const_iterator, qi::space_type> rule2 = txt >> '=' >> '[' >> ']';
    
        auto begin = s.begin();
        auto end   = s.end();
    
        if (qi::phrase_parse(begin, end, rule2, qi::space)) {
            std::cout << "MATCH" << std::endl;
        } else {
            std::cout << "NO MATCH" << std::endl;
        }
    
        if (begin != end) {
            std::cout << "Trailing unparsed: '" << std::string(begin, end) << "'\n";
        }
    
    }
    

    Printing

    MATCH
    Trailing unparsed: ';'