一遍解析器中有几次匹配? [英] Several matches in a one pass parser?

查看:74
本文介绍了一遍解析器中有几次匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试(但仍)使用从日志中解析出的数据填充多个向量.关键是要尽可能快且高效地执行此操作,因此我想一次收集所有数据(而不是规则之间的或").

I am trying (yet) to populate several vectors with data parsed from a log. The key is do it as fast and efficient as possible, so I would like to collect all the data in only one pass (not "or" between rules).

我发现了下一个问题:

1)每次我使用Spirit时,它都无法按预期工作,我发现自己完全迷失了自我,尝试了两个小时的测试和错误.是否有任何调试指令可以提示发生了什么问题?

1) Every time I use spirit and it does not work as expected I find myself totally loss and trying test and error for two hours. Is there any debug directive that gives some hint about what has gone wrong?

2)使用phoenix构造方法是否有效?我的意思是,它可以像我在代码中所做的那样避免使用符号表吗?

2) Is it valid the way I use phoenix construct? I mean, can it be used as I have done in code for avoiding using a symbol table?

3)有什么方法可以获取一条规则的信息并将其用于另一条规则?我曾经尝试过phoenix :: ref,但与BOOST_FUSION_ADAPT_STRUCT结合使用时会混淆数据.

3) Is there any way of getting info for a rule and using it into another rule? I have tried with phoenix::ref but it confuses data when using combined with BOOST_FUSION_ADAPT_STRUCT.

4)这样使用代码是否会造成严重错误?我的意思是,我应该使用自动规则将其包装的语法还是只简化使用两个规则,一个用于位置",另一个用于位置+事件",然后使用凤凰?

4) Am I making a deep error using code as this? I mean, should I use a grammar wrapping this with auto rules or just simplify using two rules one for "location" and other for "location + event" and then using phoenix?

#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>
#include <boost/phoenix/phoenix.hpp>
#include <cstring> // strlen

typedef char const* It;
enum kind { SLOPE, GEAR };

struct Location {
    int driver;
    double time;
    double vel;
    double km;
    std::string date;
    std::string road;
};

struct Event {
    int event;
    double time;
    double value;
};

BOOST_FUSION_ADAPT_STRUCT(Location, date, time, driver, vel, road, km)
BOOST_FUSION_ADAPT_STRUCT(Event, event, value)//Same "time" as its previous "Location" header. Please do not adapt "time" unless necesssary.


//They shall be defined in another compilation unit and defined as extern in production code. Please do not insert within dispatcher struct.
std::vector<Location> container1;
std::vector<Event> container2;

struct dispatcher
{
    static void add(const Location& loc) { container1.push_back(loc); }
    static void add(const Event& ev)     { container2.push_back(ev);  }
};

namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;

namespace boost { namespace spirit { namespace traits
{
    template <> struct is_container<dispatcher> : std::true_type { };

    template <> struct container_value<dispatcher>
    {
        typedef boost::variant<Location, Event> type;
    };

    template <typename T> struct push_back_container<dispatcher, T>
    {
        struct Visitor
        {
            typedef void result_type;
            template <typename U> void operator()(U const& ev) const { dispatcher::add(ev); }
        };

        static bool call(dispatcher& log, T const& attribute)
        {
            boost::apply_visitor(Visitor(), attribute);
            return true;
        }
    };
} } }

void parse_test_1(It b, It e) {
    using namespace qi;

    auto date = copy(
        repeat(4)[digit] >> '-' >> repeat(3)[alpha] >> '-' >> repeat(2)[digit] >> ' ' >> 
        repeat(2)[digit] >> ':' >> repeat(2)[digit] >> ':' >> repeat(2)[digit] >> '.' >> +digit);

    qi::rule<It, Event()> slope = lit(" - SLOPE: ")[px::construct<int>(kind::SLOPE)] >> double_;
    qi::rule<It, Event()> gear = lit(" - GEAR: ")[px::construct<int>(kind::GEAR)] >> double_;

    qi::rule<It, Location()> line = '[' >> raw[date] >> "] - "
        >> double_ >> " s"
        >> " => Driver: "  >> int_
        >> " - Speed: "    >> double_
        >> " - Road: "     >> raw[+graph]
        >> " - Km: "       >> double_
        >> -(slope | gear)
        >> (eol | eoi);

    parse(b, e, *boost::spirit::repository::qi::seek[line], dispatcher());
}

void parse_test_2(It b, It e) {
    using namespace qi;

    double t = 0;
    auto date = copy(
        repeat(4)[digit] >> '-' >> repeat(3)[alpha] >> '-' >> repeat(2)[digit] >> ' ' >> 
        repeat(2)[digit] >> ':' >> repeat(2)[digit] >> ':' >> repeat(2)[digit] >> '.' >> +digit);

    qi::rule<It, Event()> slope = lit(" - SLOPE: ")[px::construct<int>(kind::SLOPE)] >> double_;
    qi::rule<It, Event()> gear = lit(" - GEAR: ")[px::construct<int>(kind::GEAR)] >> double_;

    qi::rule<It, Location()> line = '[' >> raw[date] >> "] - "
        >> double_ >> " s"
        >> " => Driver: "  >> int_
        >> " - Speed: "    >> double_
        >> " - Road: "     >> raw[+graph]
        >> " - Km: "       >> double_
        >> -(slope | gear)
        >> (eol | eoi);

    parse(b, e, *line, dispatcher());
}

//Not all the lines will match the parser!
static char input1[] = 
"[2018-Mar-13 13:13:59.580482] - 0.200 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - SLOPE: 5.5\n\
[2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - GEAR: 1\n\
[2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
[2018-Mar-13 13:14:01.170203] - 1.790 s => I do not care about this line\n\
[2018-Mar-13 13:14:01.819966] - 2.440 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
[2018-Mar-13 13:14:01.170203] - 2.440 s => Neither I do about this other line\n\
[2018-Mar-13 13:15:01.819966] - 3.440 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90.0 - SLOPE: 10\n";

static const size_t len1 = strlen(input1);

//All the lines shall match the parser!
static char input2[] = 
"[2018-Mar-13 13:13:59.580482] - 0.200 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - SLOPE: 5.5\n\
[2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - GEAR: 1\n\
[2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
[2018-Mar-13 13:14:01.819966] - 2.440 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
[2018-Mar-13 13:15:01.819966] - 3.440 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90.0 - SLOPE: 10\n";

static const size_t len2 = strlen(input2);

int main()
{
    parse_test_1(input1, input1+len1);
    std::cout << "TEST 1:\n";
    std::cout << "Locations:\n";
    std::for_each(std::begin(container1), std::end(container1), [](const Location& loc)
    {
        std::cout << "[" << loc.date << "] - " << loc.time << " s => Driver: " << loc.driver << " - Speed: " << loc.vel << " - Road: " << loc.road << " - Km: " << loc.km << std::endl;
    });

    std::cout << "Events:\n";
    std::for_each(std::begin(container2), std::end(container2), [](const Event& ev)
    {
        std::cout << ev.time << " s => EVENT(" << ev.event << ") : " << ev.value << std::endl;
    });

    container1.clear();
    container2.clear();

    parse_test_2(input2, input2+len2);
    std::cout << "\nTEST 2:\n";
    std::cout << "Locations:\n";
    std::for_each(std::begin(container1), std::end(container1), [](const Location& loc)
    {
        std::cout << "[" << loc.date << "] - " << loc.time << " s => Driver: " << loc.driver << " - Speed: " << loc.vel << " - Road: " << loc.road << " - Km: " << loc.km << std::endl;
    });

    std::cout << "Events:\n";
    std::for_each(std::begin(container2), std::end(container2), [](const Event& ev)
    {
        std::cout << ev.time << " s => EVENT(" << ev.event << ") : " << ev.value << std::endl;
    });

    return 0;
}

结果:预期结果应为以下结果:

RESULT: The expected result should be this one:

TEST 1:
Locations:
[2018-Mar-13 13:13:59.580482] - 0.2 s => Driver: 0 - Speed: 0 - Road: A-11 - Km: 90
[2018-Mar-13 13:14:01.170203] - 1.79 s => Driver: 0 - Speed: 0 - Road: A-11 - Km: 90
[2018-Mar-13 13:14:01.170203] - 1.79 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90
[2018-Mar-13 13:14:01.819966] - 2.44 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90
[2018-Mar-13 13:15:01.819966] - 3.44 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90
Events:
0.2 s => EVENT(0): 5.5
1.79 s => EVENT(1): 1
3.44 s => EVENT(0): 10

TEST 2:
Locations:
[2018-Mar-13 13:13:59.580482] - 0.2 s => Driver: 0 - Speed: 0 - Road: A-11 - Km: 90
[2018-Mar-13 13:14:01.170203] - 1.79 s => Driver: 0 - Speed: 0 - Road: A-11 - Km: 90
[2018-Mar-13 13:14:01.170203] - 1.79 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90
[2018-Mar-13 13:14:01.819966] - 2.44 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90
[2018-Mar-13 13:15:01.819966] - 3.44 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90
Events:
0.2 s => EVENT(0): 5.5
1.79 s => EVENT(1): 1
3.44 s => EVENT(0): 10

推荐答案

首先,是我在答案中给了您全部,在具有特征的单独向量"下.唯一的区别似乎是类型和事实,使您成为LogEvents成员的全局变量(ick).

First off: I gave you all of that in that answer, under "Separate vectors with a trait". The only difference appears to be the types and the fact that you made LogEvents members global variables (ick).

转到您的问题代码:

 parse(b, e, *boost::spirit::repository::qi::seek[line], dispatcher());

您为什么要在那儿传递调度员?分派器不是兼容属性(实际上只有静态的非数据成员).

Why are you passing the dispatcher there? Dispatcher is not a compatible attribute (in fact has only static non-data members).

因此,让我们将其修复为合理的数据结构(而不​​是全局变量):

So, let's fix it back to a sane data structure (instead of global variables):

struct ParsedData
{
    std::vector<Location> _locations;
    std::vector<Event> _events;
    void add(const Location& loc) { _locations.push_back(loc); }
    void add(const Event& ev)     { _events.push_back(ev);  }
};

请注意,容器不再是全局容器,它们除了我们现在有一个数据实例之外,boost::spirit::traits专长是相同的( mutatis mutandis ),因此我们将其绑定(同样,如

The boost::spirit::traits specializations are the same (mutatis mutandis) except that we now have a data instance, so we bind it (again, as in the original example linked above, line 52, so let's fix the usage:

ParsedData data;
parse(b, e, *boost::spirit::repository::qi::seek[line], data);
return data;

从这里开始,一切正常.

From here, it all worked.

注意:

  • 没有理由在C ++中使用原始char数组并strlen(我使用的是std::string)
  • 没有理由重复所有代码并将所有内容命名为_1_2.我成为主要人物:

  • there is no reason to use raw char arrays and strlen in C++ (I used std::string)
  • there is no reason to duplicate all the code and name everything _1 or _2. I made main:

int main() {
    do_test("TEST 1", input1, parse_test_1);
    do_test("TEST 2", input2, parse_test_2);
}

  • 没有理由将for_each与lambda一起使用,只要使用range-for就足够了.这是do_test:

  • there is no reason to use for_each with a lambda where a ranged-for would suffice. This is do_test:

    void do_test(std::string caption, std::string const& input, ParsedData(*f)(It,It)) {
        ParsedData const data = f(input.begin(), input.end());
        std::cout << caption << ":\n";
        std::cout << "Locations:\n";
        for (Location const& loc : data._locations) {
            std::cout << "[" << loc.date << "] - " << loc.time << " s => Driver: " << loc.driver << " - Speed: " << loc.vel << " - Road: " << loc.road << " - Km: " << loc.km << std::endl;
        }
    
        std::cout << "Events:\n";
        for (Event const& ev : data._events) {
            std::cout << " EVENT(" << ev.event << ") : " << ev.value << std::endl;
        }
    }
    

  • 我将time成员从Event中删除了,因为它未被使用.

  • I dropped the time member from Event since it was unused.

    在Coliru上直播

    #include <boost/fusion/adapted/struct.hpp>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/repository/include/qi_seek.hpp>
    #include <boost/phoenix/phoenix.hpp>
    #include <cstring> // strlen
    
    typedef std::string::const_iterator It;
    enum kind { SLOPE, GEAR };
    
    struct Location {
        int driver;
        double time;
        double vel;
        double km;
        std::string date;
        std::string road;
    };
    
    struct Event {
        int event;
        double value;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(Location, date, time, driver, vel, road, km)
    BOOST_FUSION_ADAPT_STRUCT(Event, event, value)
    
    struct ParsedData {
        std::vector<Location> _locations;
        std::vector<Event> _events;
        void add(const Location& loc) { _locations.push_back(loc); }
        void add(const Event& ev)     { _events.push_back(ev);  }
    };
    
    namespace qi = boost::spirit::qi;
    namespace px = boost::phoenix;
    
    namespace boost { namespace spirit { namespace traits {
        template <> struct is_container<ParsedData> : std::true_type {};
        template <> struct container_value<ParsedData> { typedef boost::variant<Location, Event> type; };
    
        template <typename T> struct push_back_container<ParsedData, T> {
            struct Visitor {
                ParsedData &data;
                typedef void result_type;
                template <typename U> void operator()(U const &ev) const { data.add(ev); }
            };
    
            static bool call(ParsedData &log, T const &attribute) {
                boost::apply_visitor(Visitor{ log }, attribute);
                return true;
            }
        };
    } } } // namespace boost::spirit::traits
    
    ParsedData parse_test_1(It b, It e) {
        using namespace qi;
    
        auto date = copy(
            repeat(4)[digit] >> '-' >> repeat(3)[alpha] >> '-' >> repeat(2)[digit] >> ' ' >> 
            repeat(2)[digit] >> ':' >> repeat(2)[digit] >> ':' >> repeat(2)[digit] >> '.' >> +digit);
    
        qi::rule<It, Event()> slope = lit(" - SLOPE: ")[px::construct<int>(kind::SLOPE)] >> double_;
        qi::rule<It, Event()> gear = lit(" - GEAR: ")[px::construct<int>(kind::GEAR)] >> double_;
    
        qi::rule<It, Location()> line = '[' >> raw[date] >> "] - "
            >> double_ >> " s"
            >> " => Driver: "  >> int_
            >> " - Speed: "    >> double_
            >> " - Road: "     >> raw[+graph]
            >> " - Km: "       >> double_
            >> -(slope | gear)
            >> (eol | eoi);
    
        ParsedData data;
        parse(b, e, *boost::spirit::repository::qi::seek[line], data);
        return data;
    }
    
    ParsedData parse_test_2(It b, It e) {
        using namespace qi;
    
        auto date = copy(
            repeat(4)[digit] >> '-' >> repeat(3)[alpha] >> '-' >> repeat(2)[digit] >> ' ' >> 
            repeat(2)[digit] >> ':' >> repeat(2)[digit] >> ':' >> repeat(2)[digit] >> '.' >> +digit);
    
        qi::rule<It, Event()> slope = lit(" - SLOPE: ")[px::construct<int>(kind::SLOPE)] >> double_;
        qi::rule<It, Event()> gear = lit(" - GEAR: ")[px::construct<int>(kind::GEAR)] >> double_;
    
        qi::rule<It, Location()> line = '[' >> raw[date] >> "] - "
            >> double_ >> " s"
            >> " => Driver: "  >> int_
            >> " - Speed: "    >> double_
            >> " - Road: "     >> raw[+graph]
            >> " - Km: "       >> double_
            >> -(slope | gear)
            >> (eol | eoi);
    
        ParsedData data;
        parse(b, e, *line, data);
        return data;
    }
    
    //Not all the lines will match the parser!
    static std::string const input1 = 
    "[2018-Mar-13 13:13:59.580482] - 0.200 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - SLOPE: 5.5\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - GEAR: 1\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => I do not care about this line\n\
    [2018-Mar-13 13:14:01.819966] - 2.440 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
    [2018-Mar-13 13:14:01.170203] - 2.440 s => Neither I do about this other line\n\
    [2018-Mar-13 13:15:01.819966] - 3.440 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90.0 - SLOPE: 10\n";
    
    //All the lines shall match the parser!
    static std::string const input2 = 
    "[2018-Mar-13 13:13:59.580482] - 0.200 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - SLOPE: 5.5\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - GEAR: 1\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
    [2018-Mar-13 13:14:01.819966] - 2.440 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
    [2018-Mar-13 13:15:01.819966] - 3.440 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90.0 - SLOPE: 10\n";
    
    void do_test(std::string caption, std::string const& input, ParsedData(*f)(It,It)) {
        ParsedData const data = f(input.begin(), input.end());
        std::cout << caption << ":\n";
        std::cout << "Locations:\n";
        for (Location const& loc : data._locations) {
            std::cout << "[" << loc.date << "] - " << loc.time << " s => Driver: " << loc.driver << " - Speed: " << loc.vel << " - Road: " << loc.road << " - Km: " << loc.km << std::endl;
        }
    
        std::cout << "Events:\n";
        for (Event const& ev : data._events) {
            std::cout << " EVENT(" << ev.event << ") : " << ev.value << std::endl;
        }
    }
    
    int main() {
        do_test("TEST 1", input1, parse_test_1);
        do_test("TEST 2", input2, parse_test_2);
    }
    

    进一步的观察:

    1. 我不清楚您何时期望Event规则(坡度/齿轮)匹配或综合属性.我还不清楚为什么这些选项是可选的(没有该部分,行的位置部分可能无法匹配).

    1. It is unclear to me when you'd expect the Event rules (slope/gear) to match or synthesize an attribute. It's also unclear to me why those would be optional (the location part of a line cannot possibly match without that part).

    此外,

    qi::rule<It, Location()> line = '[' >> raw[date] >> "] - "
        >> double_ >> " s"
        >> " => Driver: "  >> int_
        >> " - Speed: "    >> double_
        >> " - Road: "     >> raw[+graph]
        >> " - Km: "       >> double_
        >> -(slope | gear)
        >> (eol | eoi);
    

    位置会包含一个额外的字段:

    Would have Location contain an extra field:

    struct Location {
        int driver;
        double time;
        double vel;
        double km;
        std::string date;
        std::string road;
        boost::optional<Event> event;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(Event, event, value)
    BOOST_FUSION_ADAPT_STRUCT(Location, date, time, driver, vel, road, km, event)
    

  • 这些规则很奇怪:

  • These rules are odd:

    qi::rule<It, Event()> slope = lit(" - SLOPE: ")[px::construct<int>(kind::SLOPE)] >> double_;
    qi::rule<It, Event()> gear = lit(" - GEAR: ")[px::construct<int>(kind::GEAR)] >> double_;
    

    为什么不完全按照我在链接答案中显示的那样使用 symbols方法/98)?如果您坚持要笨拙",请不要使用语义动作(

    Why not use the symbols approach exactly as I showed in the linked answer (line 57/98)? If you insist on doing it "clumsy", do not use semantic actions (Boost Spirit: "Semantic actions are evil"?) but use qi::attr:

    qi::rule<It, Event()> slope = " - SLOPE: " >> attr(kind::SLOPE) >> double_;
    qi::rule<It, Event()> gear = " - GEAR: " >> attr(kind::GEAR) >> double_;
    

    在有用的效果中,可以将您的编译时间减少一半,并且还可以实际传播属性值(您的语义动作根本没有效果,并且主动抑制了属性的自动传播...).

    Among the helpful effects are that your compilation times can be cut in half, and also the attribute values actually propagate (your semantic actions had no effect at all, and actively suppressed automatic attribute propagation...).

    有了这些改进,我们得到了:

    With these improvements in place we get:

    在Coliru上直播

    #include <boost/fusion/adapted/struct.hpp>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/repository/include/qi_seek.hpp>
    
    typedef std::string::const_iterator It;
    enum kind { SLOPE, GEAR };
    
    struct Event {
        int event;
        double value;
    };
    
    struct Location {
        int driver;
        double time;
        double vel;
        double km;
        std::string date;
        std::string road;
        boost::optional<Event> event;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(Event, event, value)
    BOOST_FUSION_ADAPT_STRUCT(Location, date, time, driver, vel, road, km, event)
    
    using ParsedData = std::vector<Location>;
    
    namespace qi = boost::spirit::qi;
    namespace px = boost::phoenix;
    
    ParsedData parse_test(It b, It e) {
        using namespace qi;
    
        auto date = copy(
            repeat(4)[digit] >> '-' >> repeat(3)[alpha] >> '-' >> repeat(2)[digit] >> ' ' >> 
            repeat(2)[digit] >> ':' >> repeat(2)[digit] >> ':' >> repeat(2)[digit] >> '.' >> +digit);
    
        qi::rule<It, Event()> slope = " - SLOPE: " >> attr(kind::SLOPE) >> double_;
        qi::rule<It, Event()> gear = " - GEAR: " >> attr(kind::GEAR) >> double_;
    
        qi::rule<It, Location()> line = '[' >> raw[date] >> "] - "
            >> double_ >> " s"
            >> " => Driver: "  >> int_
            >> " - Speed: "    >> double_
            >> " - Road: "     >> raw[+graph]
            >> " - Km: "       >> double_
            >> -(slope | gear)
            >> (eol | eoi);
    
        ParsedData data;
        parse(b, e, *boost::spirit::repository::qi::seek[line], data);
        return data;
    }
    
    //Not all the lines will match the parser!
    static std::string const input = 
    "[2018-Mar-13 13:13:59.580482] - 0.200 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - SLOPE: 5.5\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.0 - Road: A-11 - Km: 90.0 - GEAR: 1\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
    [2018-Mar-13 13:14:01.170203] - 1.790 s => I do not care about this line\n\
    [2018-Mar-13 13:14:01.819966] - 2.440 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90.0\n\
    [2018-Mar-13 13:14:01.170203] - 2.440 s => Neither I do about this other line\n\
    [2018-Mar-13 13:15:01.819966] - 3.440 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90.0 - SLOPE: 10\n";
    
    int main() {
        auto parsed = parse_test(input.begin(), input.end());
        std::cout << "Locations:\n";
        for (Location const& loc : parsed) {
            std::cout << "[" << loc.date << "] - " << loc.time << " s => Driver: " << loc.driver << " - Speed: " << loc.vel << " - Road: " << loc.road << " - Km: " << loc.km << std::endl;
            if (loc.event)
                std::cout << " - event: " << loc.event->event << " value: " << loc.event->value << "\n";
        }
    }
    

    打印

    Locations:
    [2018-Mar-13 13:13:59.580482] - 0.2 s => Driver: 0 - Speed: 0 - Road: A-11 - Km: 90
     - event: 0 value: 5.5
    [2018-Mar-13 13:14:01.170203] - 1.79 s => Driver: 0 - Speed: 0 - Road: A-11 - Km: 90
     - event: 1 value: 1
    [2018-Mar-13 13:14:01.170203] - 1.79 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90
    [2018-Mar-13 13:14:01.1702032018-Mar-13 13:14:01.819966] - 2.44 s => Driver: 0 - Speed: 0.1 - Road: A-11 - Km: 90
    [2018-Mar-13 13:14:01.1702032018-Mar-13 13:15:01.819966] - 3.44 s => Driver: 0 - Speed: 0.2 - Road: A-11 - Km: 90
     - event: 0 value: 10
    

    这篇关于一遍解析器中有几次匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆