Boost.Spirit X3 -- 运算符减号没有按预期工作

Boost.Spirit X3 -- operator minus does not work as expected

考虑以下代码:

TEST_CASE("Requirements Parser Description", "[test]")
{
    namespace x3 = ::boost::spirit::x3;

    std::string s = "### Description\n\nSome\nmultiline\ntext."
                    "\n\n### Attributes";

    std::string expectedValue = "Some\nmultiline\ntext.";

    auto rule = x3::lit("### ") >> x3::lit("Description")
        >> (x3::lexeme
                [+x3::char_
                 - (x3::lit("###") >> *x3::space >> x3::lit("Attributes"))]);

    std::string value;
    bool success = x3::phrase_parse(s.begin(), s.end(), rule, x3::space, value);
    REQUIRE(success);
    REQUIRE(value == expectedValue);
}

产生以下输出:

test_boost_spirit_x3_parser.cpp:183: FAILED:
  REQUIRE( value == expectedValue )
with expansion:
  "Some
  multiline
  text.
  
### Attributes"
  ==
  "Some
  multiline
  text."

任何解释为什么减号运算符不能像我预期的那样工作?手头有什么修复方法吗?

可能是运算符优先级。一元 + 运算符优先于二元 - 运算符。这导致:

来自 boost 手册:- operator 差异解析器匹配 LHS 但不匹配 RHS。

LHS 是 +x3::char_

RHS 是 (x3::lit("###") >> *x3::space >> x3::lit("Attributes"))

现在 LHS +x3::char_ 匹配尽可能多的字符(贪婪匹配)。所以 LHS 的计算结果为

Some
  multiline
  text.
  
### Attributes

在那之后就没有字符了,所以 RHS 什么都不匹配。结果,- operator 也匹配(LHS 是,RHS 不是,这正是您所看到的)。

或者,换句话说:在 - operator 有机会之前,你的 +x3::char_ 吃掉了所有剩余的字符。

要修复它我猜你需要写

+(x3::char_ - (x3::lit...))

至少从我从这里的例子中收集到的信息:https://www.boost.org/doc/libs/1_78_0/libs/spirit/doc/html/spirit/qi/reference/operator/difference.html

test_parser("/*A Comment*/", "/*" >> *(char_ - "*/") >> "*/");

注意 (char_ - "*/")

两边的括号