我需要匹配一些输入,构造一个复杂的对象,然后根据一些道具以两种方式匹配其余输入。的构造对象。我试过 qi::eps(/ condition /) >> p1 | p2 但结果对我来说很明显。简化代码http://liveworkspace.org/code/1NzThA $6
在代码片段中,我匹配输入中的 int_ 并且如果值 == 0 尝试匹配“a” - 'b' 但对于“0b”输入,我已经确定了!我试过玩牙套,但没有运气。
我需要匹配一些输入,构造一个复杂的对象,然后根据一些道具以两种方式匹配其余输入。的构造对象。我试过 qi::eps(/ condition /) >> p1 | p2 但结果对我来说很明显。简化代码http://liveworkspace.org/code/1NzThA $6
在代码片段中,我匹配输入中的 int_ 并且如果值 == 0 尝试匹配“a” - 'b' 但对于“0b”输入,我已经确定了!我试过玩牙套,但没有运气。
我个人不会轻易使用语义动作(或凤凰)。这不是齐的“精神”(双关语)。
这是我的看法:
rule<char const*, char()> r =
(omit [ int_(0) ] >> char_('a')) |
(omit [ int_(1) ] >> char_('b'))
;
看?干净多了。另外:自动属性传播。在http://liveworkspace.org/code/1T9h5上实时查看
输出:
ok: a
fail
fail
ok: b
完整示例代码:
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
template <typename P>
inline
void test_parser(char const* input, P const& p, bool full_match = true)
{
char const* f(input);
char const* l(f + strlen(f));
char result;
if (qi::parse(f, l, p, result) && (!full_match || (f == l)))
std::cout << "ok: " << result << std::endl;
else
std::cout << "fail" << std::endl;
}
int main()
{
int p;
using namespace qi;
rule<char const*, char()> r =
(omit [ int_(0) ] >> char_('a')) |
(omit [ int_(1) ] >> char_('b'))
;
BOOST_SPIRIT_DEBUG_NODE(r);
test_parser("0a", r); //should match
test_parser("0b", r); //should not match
test_parser("1a", r); //should not match
test_parser("1b", r); //should match
}
这是你的规则:
qi::rule<char const*> r =
qi::int_ [phoenix::ref(p) = qi::_1]
>> (qi::eps(phoenix::ref(p) == 0)
>> qi::char_('a') | qi::char_('b'))
这对我来说是:接受'0a'或任何以'b'结尾的东西。这与您在代码片段中获得的结果相匹配。
我承认我不完全理解您的问题,但是如果您试图让某种“排他性或”事情发生(如您的代码片段中的注释所示),那么此规则是不完整的。您在评论中提出的解决方法(实际上更像是“修复”而不是“解决方法”)是一种解决方案,尽管您不需要,qi::lazy
因为基于凤凰城的 Qi 当地人已经很懒惰,但您走在正确的轨道上. 这是另一个(更具可读性?)解决方案。
qi::rule<char const*> r =
qi::int_ [phoenix::ref(p) = qi::_1]
>> ((qi::eps(phoenix::ref(p) == 0) >> qi::char_('a')) |
(qi::eps(phoenix::ref(p) == 1) >> qi::char_('b')))
;
如果您更喜欢使用您在评论中添加的 locals<>,那也可以,但是使用引用 top
会减少代码的开销,只要您记住不要p
在语法中的其他任何地方设置,并且您不最终构建了一个递归该规则的语法:)