如果运算符“>>”的右侧失败,如何使规则失败,以提高精神气
How to make the rule fail if the right side of operator ">>" fails, in boost spirit qi
为了简单起见,假设我需要先解析 A
,然后再解析 B
我不是指字母,当然,A
和B
可以是(qi::char_)
,或者(qi::char_('$') | qi::char_('_') | ascii::alpha)
,或者其他什么。
所以:
rule = A >> B;
问题是如果 B
失败,规则不会失败,我得到 A
。我试过 +B
但结果是一样的。并且:
rule = A > B;
如果失败则抛出异常。
UPDATE:我编辑了这个问题来解释上面的陈述是错误的(正如用户 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
没有失败。现在我知道这是一个不同的问题。但是规则 确实 失败了。
问。 问题是如果 B 失败,规则不会失败,我得到 A
一个。这不是真的,请参阅下面的大量演示
问。后面可以跟E,但我不想得到CE
一个。在下面的测试用例中寻找 positive assertion(C >> &E
会在这里做)
这是因为我要解析关键字和标识符,所以int是关键字,int4是标识符。因此关键字是我定义的一个字符串,后面没有数字或字母。有什么想法吗?
是的,请参阅:
- boost::spirit::qi keywords and identifiers
distinct
精神宝库
#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
为了简单起见,假设我需要先解析 A
,然后再解析 B
我不是指字母,当然,A
和B
可以是(qi::char_)
,或者(qi::char_('$') | qi::char_('_') | ascii::alpha)
,或者其他什么。
所以:
rule = A >> B;
问题是如果 B
失败,规则不会失败,我得到 A
。我试过 +B
但结果是一样的。并且:
rule = A > B;
如果失败则抛出异常。
UPDATE:我编辑了这个问题来解释上面的陈述是错误的(正如用户 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
没有失败。现在我知道这是一个不同的问题。但是规则 确实 失败了。
问。 问题是如果 B 失败,规则不会失败,我得到 A
一个。这不是真的,请参阅下面的大量演示
问。后面可以跟E,但我不想得到CE
一个。在下面的测试用例中寻找 positive assertion(C >> &E
会在这里做)
这是因为我要解析关键字和标识符,所以int是关键字,int4是标识符。因此关键字是我定义的一个字符串,后面没有数字或字母。有什么想法吗?
是的,请参阅:
- boost::spirit::qi keywords and identifiers
distinct
精神宝库
#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