使用 boostspirit 识别带双括号的令牌字符串时遇到问题

问题描述 投票:0回答:1

解析字符串时:

1815 ((sd-pam)) S 1778 1778 1778 ...

我试图省略“((sd-pam))”标记

我使用了以下内容:

omit_string %= lexeme['(' >> +(char_ - ')') >> ')'];

然后我会按以下方式使用它:

    start %=
        int_
        >> omit[omit_string >> char_ >> repeat(10)[long_]]
        >> long_ >> long_ >> long_ >> long_
     ;

这适用于末尾的单个括号(例如“((sd-pam)”),但不适用于 ned 上的多个括号。我似乎找不到任何有关相关语法的文档来计算我如何才能达到预期的结果。

boost boost-spirit boost-spirit-qi
1个回答
0
投票

这完全取决于你的实际语法。

您的样品不足以指定您想要的。要解析示例,您只需调整规则即可:

omit_string = "((" >> *(qi::char_ - "))") >> "))";

也支持

(sd-pam)
:

omit_string =                             //
    "((" >> *(qi::char_ - "))") >> "))" | //
    "(" >> *(qi::char_ - ")") >> ")"      //
    ;

看到它在Coliru上直播

// #define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iomanip>
#include <iostream>
namespace qi = boost::spirit::qi;

namespace Parsing {
    struct Data {
        int  leader;
        long a, b, c, d;
    };
    using boost::fusion::operator<<;
} // namespace Parsing

BOOST_FUSION_ADAPT_STRUCT(Parsing::Data, leader, a, b, c, d)

namespace Parsing {
    template <typename It> struct DataParser : qi::grammar<It, Data()> {
        DataParser() : DataParser::base_type(start) {
            start = qi::skip(qi::space)[data];

            omit_string =                             //
                "((" >> *(qi::char_ - "))") >> "))" | //
                "(" >> *(qi::char_ - ")") >> ")"      //
                ;

            data = qi::int_                                                        //
                >> qi::omit[omit_string >> qi::char_ >> qi::repeat(10)[qi::long_]] //
                >> qi::long_ >> qi::long_ >> qi::long_ >> qi::long_                //
                ;

            BOOST_SPIRIT_DEBUG_NODES((start)(data)(omit_string));
        }

      private:
        qi::rule<It, Data()>                 start;
        qi::rule<It, Data(), qi::space_type> data;
        // lexemes:
        qi::rule<It> omit_string;
    };
} // namespace Parsing

int main() {
    using It = std::string::const_iterator;
    static Parsing::DataParser<It> const p{};

    for (std::string const input : {
             "1815 ((sd-pam)) S 1778 1778 1778 1778 1778 1778 1778 1778 1778 1778 11 22 33 44",
             "1815 (sd-pam) S 0 0 0 0 0 0 0 0 0 0 -11 -22 -33 -44",
         }) {
        std::cout << "========\nTesting " << quoted(input) << "\n";

        auto f = begin(input), l = end(input);
        if (Parsing::Data d; parse(f, l, p, d)) {
            std::cout << "Parsed: " << d << "\n";
        } else {
            std::cout << "Parsed failed\n";
        }

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

========

Testing "1815 ((sd-pam)) S 1778 1778 1778 1778 1778 1778 1778 1778 1778 1778 11 22 33 44"

Parsed: (1815 11 22 33 44)

========

Testing "1815 (sd-pam) S 0 0 0 0 0 0 0 0 0 0 -11 -22 -33 -44"

Parsed: (1815 -11 -22 -33 -44)
© www.soinside.com 2019 - 2024. All rights reserved.