gpt4 book ai didi

c++ - 是否可以在另一个语法定义中重用 boost::spirit::qi 语法?

转载 作者:IT老高 更新时间:2023-10-28 21:42:30 24 4
gpt4 key购买 nike

是否可以在另一个语法中重用 boost::spirit:qi 语法(例如规则)?

例如,如果我定义一个语法来将文本行解析为包含街道地址的结构。

   template< typename iter >
struct address_grammar : qi::grammar< iter, address() >
{
...

qi::rule< iter, std::string() > street_name;
qi::rule< iter, std::string() > street_number;
qi::rule< iter, address() > address_;
}

我可能想在其他两种语法中重用该语法,例如,一种可能用于解析存储在文件中的地址 vector 。另一种重用可能是更复杂的结构,其中一个字段是这个街道地址结构。

  template< typename iter >
struct company_grammar : qi::grammar< iter, company() >
{
...
qi::rule< iter, std::string() > comp_name;
// can I reuse the address grammar somehow here ???
qi::rule< iter, company() > company;
}

我没有在一个地方定义整个语法,而是考虑将其拆分为更小的可重用 block ,如果它们位于一个头文件中就可以了。我的数据结构稍微复杂一些(结构中的几个字段以及其他结构的列表等等),所以我不想把它放在一个语法中。

这种方式可以复用boost::spirit::qi语法吗?

编辑:想一想,我是否只是在命名空间中定义 qi::rules,然后根据我需要的规则组合一个语法?

最佳答案

当然可以。在您的情况下,只需输入 address_grammar<iter> address_;在你的代码中。

让我再举一个例子。您可以在此处找到可编译的代码: http://ideone.com/GW4jO (另见下文)

AFAIK,与 qi::grammar 不同,qi::rule 难以重用。


完整样本

#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

struct Date {
int year, month, day;
};
struct Time {
int hour, minute, second;
};

BOOST_FUSION_ADAPT_STRUCT(
Date,
(int, year)
(int, month)
(int, day)
)

BOOST_FUSION_ADAPT_STRUCT(
Time,
(int, hour)
(int, minute)
(int, second)
)

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
typedef std::string::const_iterator Iterator;

class DateParser:
public qi::grammar < Iterator, Date() > {
qi::rule < Iterator, Date() > main;
public:
DateParser(): base_type(main) {
main %= qi::int_ >> '-' >> // Year
qi::int_ >> '-' >> // Month
qi::int_; // Day
}
};

class TimeParser:
public qi::grammar < Iterator, Time() > {
qi::rule < Iterator, Time() > main;
public:
TimeParser(): base_type(main) {
main %= qi::int_ >> ':' >> // Hour
qi::int_ >> ':' >> // Minute
qi::int_; // Second
}
};

class DateTimeParser:
public qi::grammar < Iterator, boost::variant<Date, Time>() > {
qi::rule < Iterator, boost::variant<Date, Time>()> main;
public:
DateTimeParser(): base_type(main) {
main %= date_parser | time_parser;
}
DateParser date_parser;
TimeParser time_parser;
};

#include<iostream>
#include<cstdio>

struct Printer : public boost::static_visitor<> {
void operator()(Date a) const {
printf("Year: %d, Month: %d, Day: %d\n", a.year, a.month, a.day);
}
void operator()(Time a) const {
printf("Hour: %d, Minute: %d, Second: %d\n", a.hour, a.minute, a.second);
}
};

int main() {
std::string s;
std::getline(std::cin, s);
Iterator beg = s.begin(), end = s.end();
boost::variant<Date, Time> ret;
phrase_parse(beg, end, DateTimeParser(), ascii::space, ret);
if (beg != end)
puts("Parse failed.");
else
boost::apply_visitor(Printer(), ret);
}

关于c++ - 是否可以在另一个语法定义中重用 boost::spirit::qi 语法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9678440/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com