2

我需要匹配一些输入,构造一个复杂的对象,然后根据一些道具以两种方式匹配其余输入。的构造对象。我试过 qi::eps(/ condition /) >> p1 | p2 但结果对我来说很明显。简化代码http://liveworkspace.org/code/1NzThA $6

在代码片段中,我匹配输入中的 int_ 并且如果值 == 0 尝试匹配“a” - 'b' 但对于“0b”输入,我已经确定了!我试过玩牙套,但没有运气。

4

2 回答 2

3

我个人不会轻易使用语义动作(或凤凰)。这不是齐的“精神”(双关语)。

这是我的看法:

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
}
于 2013-01-29T08:30:08.853 回答
1

这是你的规则:

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在语法中的其他任何地方设置,并且您不最终构建了一个递归该规则的语法:)

于 2013-01-28T10:07:11.010 回答