سؤال

لقد بدأت للتو في البحث في Boost :: Spirit ، أحدث إصدار من الآن - v2.4. جوهر مشكلتي هو اتباع:

أود تحليل سلاسل مثل "1A2" أو "3B4". لذا فإن القاعدة التي أستخدمها هي:

  (double_ >> lit('b') >> double_)
| (double_ >> lit('a') >> double_);

يجب أن تكون سمة القاعدة "متجهًاu003Cdouble> ". وأنا أقرأها في الحاوية.

الرمز الكامل:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cstring>

int main(int argc, char * argv[])
{
    using namespace std;
    using namespace boost::spirit;
    using namespace boost::spirit::qi;
    using boost::phoenix::arg_names::arg1;

    char const * first = "1a2";
    char const * last  = first + std::strlen(first);
    vector<double> h;

    rule<char const *, vector<double>()> or_test;
    or_test %=    (double_ >> lit('b') >> double_) 
            | (double_ >> lit('a') >> double_);

    if (parse(first, last, or_test,h)) {
           cout << "parse success: "; 
           for_each(h.begin(), h.end(), (cout << arg1 << " "));
           cout << "end\n";
    } else cout << "parse error\n" << endl;
    return 0;
 }

أقوم بتجميعه مع G ++ 4.4.3. ويعود "1 1 2". بينما أتوقع "1 2".

بقدر ما أفهم حدوث هذا لأن المحلل:

  • يذهب إلى البديل الأول
  • يقرأ Double_ ويخزنها في الحاوية
  • ثم يتوقف عند "A" ، بينما يتوقع مضاءة ("B")
  • يذهب إلى البديل الثاني
  • يقرأ زوجين آخرين

سؤالي هو - هل هذا سلوك صحيح ، وإذا كانت الإجابة بنعم - لماذا؟

هل كانت مفيدة؟

المحلول

هذا هو السلوك المتوقع. أثناء التراجع ، لا تتغير روح "إلغاء" إلى السمات. لذلك ، يجب عليك استخدام hold[] توجيهات إجبار بشكل صريح على المحلل على التمسك بنسخة من السمة (مما يسمح بإعادة أي تغيير في السمة):

or_test =    
        hold[double_ >> lit('b') >> double_)]
    |   (double_ >> lit('a') >> double_)
    ; 

يجب تطبيق هذا التوجيه على جميع البدائل التي تعدل السمة ، باستثناء آخرها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top