提升精神气 - 条件解析

时间:2013-01-24 21:38:26

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

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

在代码片段中,我匹配来自输入的int_,如果值== 0,请尝试匹配'a' - 'b' 但我对'0b'的输入感到满意!我试过用括号玩,但没有运气。

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分: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::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')))
;

如果您更喜欢使用本地人&lt;&gt;你在评论中添加了,也没关系,但使用p的引用会增加代码的开销,只要你记得不要在你的语法中的任何其他地方设置p,并且你不要最终建立一个递归该规则的语法:)

相关问题