boost 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;
}

}

此代码在调试模式下运行良好 解析器在发布模式下失败 规则是只解析 text=[];除此之外的任何事情都应该失败它在调试模式下工作正常但在发布模式下它显示结果不匹配任何字符串。

如果我输入像

这样的字符串
abc=[];

这按预期通过了调试,但在发布时失败了

Spirit v2 不能使用 auto:

  • Assigning parsers to auto variables

你有Undefined Behaviour

演示

我试图让(更多)理解其余代码。有多种情况永远不会起作用:

  1. txt('=')是一个无效的Qi表达式。我以为你想要 txt >> ('=') 而不是

  2. qi::char_("a-zA-Z0-9_.\:$\-{}[]+/()") 并没有按照你的想法去做,因为 $-{ 实际上是字符 "range" \x24-\x7b... 转义 -(或者像在其他 char_ 调用中一样将它放在集合的 end/start 处)。

  3. qi::char_('-','.','_') 不行。您是说 qi::char_("-._") 吗?

  4. specialtxtanytxt 未使用...

  5. 更喜欢const_iterator

  6. 首选命名空间别名高于 using namespace 以防止难以检测的错误

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";
    }

}

打印

MATCH
Trailing unparsed: ';'