【问题标题】:How to make the rule fail if the right side of operator ">>" fails, in boost spirit qi“>>”运算符右侧失败,如何使规则失败,在提升精神气
【发布时间】:2015-07-15 19:58:41
【问题描述】:

为了简单起见,假设我需要解析 A,然后是 B

我指的不是字母,当然,AB 可以是 (qi::char_),或 (qi::char_('$') | qi::char_('_') | ascii::alpha),或其他。

所以:

rule = A >> B;

问题是如果B 失败,规则不会失败,我得到A。我试过+B,但结果是一样的。并且:

rule = A > B;

如果失败则抛出异常。

更新:我编辑了这个问题以解释上述陈述是错误的(正如用户 sehe 所证明的那样),我认为该规则没有失败,因为当我尝试:

auto A = qi::copy(qi::char_("$") | qi::alpha);
auto B = qi::copy(qi::char_("z"));
auto C = qi::copy(qi::string("$x"));
std::string s1 = "$x";
std::string s2 = "";
qi::parse(s1.begin(), s1.end(), (A >> B) | C, s2);

我会得到 s2="$$x" ,所以我认为 A 没有失败。现在我知道这是一个不同的问题。但是规则确实失败了。

【问题讨论】:

  • SO 非常适合重点问题。您结合了许多问题(实际上是更多毫无根据的断言),并且只在最后一段中隐藏了您的真正目标。这对网站的未来用户没有用。 (我建议从问题中删除不需要的噪音并扩展您想要实现的目标)
  • 我认为qi::hold 可以帮助您解决更新中的问题 (qi::hold[A >> B] | C)。

标签: c++ boost boost-spirit-qi


【解决方案1】:

问。 问题是如果 B 失败,规则不会失败,我得到 A

A.这不是真的,请参阅下面的大量演示


问。后面可以跟着E,但我不想得到CE

A.在下面的测试用例中寻找肯定断言C >> &E 会在这里做)


这是因为我正在尝试解析关键字和标识符,所以 int 是关键字,int4 是标识符。因此,关键字是我定义的不跟数字或字母的字符串。有什么想法吗?

是的,请参阅:

Live Coliru

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

template <typename Grammar>
bool check(Grammar const& g, std::string const& input, qi::unused_type) {
    auto f = input.begin(), l = input.end();
    try {
        return qi::parse(f, l, g);
    } catch(...) {
        return false;
    }
}

template <typename Grammar, typename Skipper>
bool check(Grammar const& g, std::string const& input, Skipper const& s) {
    auto f = input.begin(), l = input.end();
    try {
        return qi::phrase_parse(f, l, g, s);
    } catch(...) {
        return false;
    }
}

#define REPORT(g, i, s, expect) do { assert(expect == check(g, i, s)); } while(0)
#define SHOULD_WORK(g, i, s) REPORT(g, i, s, true)
#define SHOULD_FAIL(g, i, s) REPORT(g, i, s, false)

template <typename Skipper = qi::unused_type>
void do_all_tests(Skipper const& s = Skipper()) {

    auto A = qi::copy(qi::char_("$_") | qi::alpha);
    auto B = qi::copy(qi::char_("z"));

    // using skipper:
    SHOULD_WORK(A >> B , "$z", s);
    SHOULD_FAIL(A >> B , "$.", s);
    SHOULD_FAIL(A >> B , "$" , s);

    SHOULD_WORK(A  > B , "$z", s);
    SHOULD_FAIL(A  > B , "$.", s);
    SHOULD_FAIL(A  > B , "$" , s);

    // positive assertion (does not consume B)
    SHOULD_WORK(A >> &B, "$z", s);
    SHOULD_FAIL(A >> &B, "$.", s);
    SHOULD_FAIL(A >> &B, "$" , s);

    SHOULD_WORK(A  > &B, "$z", s);
    SHOULD_FAIL(A  > &B, "$.", s);
    SHOULD_FAIL(A  > &B, "$" , s);

    // negative assertion:
    SHOULD_FAIL(A >> !B, "$z", s);
    SHOULD_WORK(A >> !B, "$.", s);
    SHOULD_WORK(A >> !B, "$" , s);

    SHOULD_FAIL(A  > !B, "$z", s);
    SHOULD_WORK(A  > !B, "$.", s);
    SHOULD_WORK(A  > !B, "$" , s);

}

int main() {
    do_all_tests(qi::unused); // no skipper
    do_all_tests(qi::space);
    std::cout << "All tests succeeded\n";
}

打印

All tests succeeded

【讨论】:

  • 扩展了我的答案以解决您在问题中遇到的所有问题和用例。
猜你喜欢
  • 1970-01-01
  • 2018-08-02
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
相关资源
最近更新 更多