我需要匹配一些輸入,構造一個複雜的對象,然後以兩種方式匹配其餘輸入,具體取決於某些道具。的構建對象。 我試過了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