我需要匹配一些输入,构造一个复杂的对象,然后以两种方式匹配其余输入,具体取决于某些道具。的构建对象。 我试过了qi :: eps(/ 条件 /)>> p1 | p2但结果对我来说很明显。 简化代码http://liveworkspace.org/code/1NzThA $ 6助力精神气 - 条件解析
在代码片段,我从输入int_匹配,如果该值== 0尝试匹配“a”或者 - “B” 但我得到了“0B”输入OK!我试图玩大括号,但没有运气。
我需要匹配一些输入,构造一个复杂的对象,然后以两种方式匹配其余输入,具体取决于某些道具。的构建对象。 我试过了qi :: eps(/ 条件 /)>> p1 | p2但结果对我来说很明显。 简化代码http://liveworkspace.org/code/1NzThA $ 6助力精神气 - 条件解析
在代码片段,我从输入int_匹配,如果该值== 0尝试匹配“a”或者 - “B” 但我得到了“0B”输入OK!我试图玩大括号,但没有运气。
这是你的规则:
qi::rule<char const*> r =
qi::int_ [phoenix::ref(p) = qi::_1]
>> (qi::eps(phoenix::ref(p) == 0)
>> qi::char_('a') | qi::char_('b'))
那对我说:接受与 'B' 结束 '0A' 或任何东西。这与您在代码段中获得的结果相符。
我承认我并不完全理解你的问题,但是如果你试图获得某种'独占'或'事情发生(如代码片段中的注释所示),那么这个规则是不完整的。您在评论中提出的解决方法(实际上更多的是“修复”而不是“解决方法”)是一种解决方案,但您不需要,因为基于凤凰的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')))
;
如果你喜欢使用当地人<>您在您的评论加入,那也没关系,但使用参考p
的代码添加较少的开销,只要你记住不要设置p
其他地方在你的语法中,你不会最终建立一个递归该规则的语法:)
我个人不会轻易使用语义动作(或凤凰)。这不是齐的“精神”(双关半意)。
这是我的看法:
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
}
通过补气可能的解决方法::懒http://liveworkspace.org/code/2B4VCK$8 – user2008982
我已经添加了一个没有语义行为的答案([Boost Spirit:“Semantic actions is evil”?](http://stackoverflow.com/questions/8259440/boost-spirit-semantic-actions-are-evil/8259585#8259585)) – sehe
@sehe:语义行为是邪恶的:你的文章很大一部分是专门讨论基本:)虽然,虽然采取了点,但恕我直言问题与解析器中的上下文敏感性,而不是使其成为一个实际的解析问题,该示例是一个微不足道的表达。我的2c。不过,如果我们中的一个人被接受,这将是一件好事... – FatalFlaw