การใช้ตัวแยกวิเคราะห์ที่เป็นทางเลือกใน Spirit Qi

ฉันกำลังพยายามแยกวิเคราะห์นิพจน์เพิ่มเติมในรูปแบบ "A+C" หรือ "A" เพียงอย่างเดียว หลังจากการทดสอบไม่กี่ครั้ง ฉันก็พบว่าปัญหาอยู่ที่การใช้ parser เผื่อเลือก ดังนั้นขอยกตัวอย่าง:

qi::rule<string::iterator, string()> Test;

Test =
(
    qi::string("A")[qi::_val= qi::_1]
    >> -(
            qi::string("B")[qi::_val += qi::_1]
            >> qi::string("C")[qi::_val += qi::_1]
        )
)
;

string s1, s2;
s1 = "AB";
bool a= qi::parse(s1.begin(), s1.end(), Test, s2);

แนวคิดคือการแยกวิเคราะห์ 'A' หรือ "ABC" แต่ถ้าค่า s1 เป็น "AB" โดยไม่มี 'C' ค่าของ a จะเป็นจริง ฉันเชื่อว่าแม้ว่าฉันจะใส่วงเล็บไว้หลังโอเปอเรเตอร์ '-' แล้วฉันก็ใช้โอเปอเรเตอร์ ">>" แต่ส่วน 'C' ก็ถือว่าเป็นทางเลือก ไม่ใช่ B>>C โดยรวม มีความคิดอะไรบ้าง?


person kaladin    schedule 28.09.2015    source แหล่งที่มา


คำตอบ (1)


แอตทริบิวต์คอนเทนเนอร์จะไม่ย้อนรอย

นั่นเป็นทางเลือกด้านประสิทธิภาพ คุณต้องควบคุมการแพร่กระจายอย่างชัดเจนโดยใช้เช่น qi::hold:

สดบน Coliru

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

namespace qi = boost::spirit::qi;

int main() {
    using It = std::string::const_iterator;
    qi::rule<It, std::string()> Test;

    Test =
        (
         qi::char_('A')
         >> -qi::hold [
                qi::char_('B')
            >> qi::char_('C')
         ]
        )
        ;

    for (std::string const input : { "A", "AB", "ABC" })
    {
        std::cout << "-------------------------\nTesting '" << input << "'\n";
        It f = input.begin(), l = input.end();

        std::string parsed;
        bool ok = qi::parse(f, l, Test, parsed);
        if (ok)
            std::cout << "Parsed success: " << parsed << "\n";
        else
            std::cout << "Parsed failed\n";

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}

พิมพ์:

-------------------------
Testing 'A'
Parsed success: A
-------------------------
Testing 'AB'
Parsed success: A
Remaining unparsed: 'B'
-------------------------
Testing 'ABC'
Parsed success: ABC

หมายเหตุ ฉันได้ทำการทำให้ง่ายขึ้นหลายประการ

ดูสิ่งนี้ด้วย:

person sehe    schedule 28.09.2015