我是精神新手,目前正在尝试将一个类似ini的文件解析为一个结构。创建语法是可以的,但映射生成对我来说仍然是一种魔力。该文件如下所示:
[fine]
@cmp1
@cmp2
muh=b
[fail]
@cmp1
a=b
@cmp2
只要我有订购的要求和属性(#34;罚款"),它就可以工作但如果要求和属性是交错的,我就无法工作(第34节"失败&#34)。我的结构定义如下所示:
typedef std::map<std::string, std::string> Pairs;
struct Section
{
std::string name;
std::vector<std::string> requirements;
Pairs properties;
};
BOOST_FUSION_ADAPT_STRUCT(
Section,
(std::string, name)
(std::vector<std::string>, requirements)
(Pairs, properties)
)
我目前的语法如下:
template <typename Iterator, typename Skipper>
struct SectionParser : qi::grammar<Iterator, Section(), Skipper>
{
qi::rule<Iterator, Section(), Skipper> section;
qi::rule<Iterator, std::pair<std::string, std::string>(), Skipper> pair;
qi::rule<Iterator, std::vector<std::string>()> requirements;
qi::rule<Iterator, std::string()> key, value, sectionIdent, name, component;
SectionParser()
: SectionParser::base_type(section, "entity grammar")
{
using namespace qi;
sectionIdent = *(qi::char_ - (qi::lit('[') | qi::lit(']') | qi::eol));
name = *qi::eol > qi::lit('[') > sectionIdent > qi::lit(']') > (qi::eol | qi::eoi);
component = qi::char_('@') > *(qi::char_ - (qi::eol)) > (qi::eol | qi::eoi);
value = *(qi::char_ - (qi::eol | qi::eoi));
key = qi::char_("a-zA-Z_") > *qi::char_("a-zA-Z_0-9");
pair = key > qi::lit('=') > value > (qi::eol | qi::eoi);
section = name >> *component >> *pair;
}
};
这就是我如何运行解析器:
std::vector<Section> sections;
bool ok = phrase_parse(first, last, (sectionParser % +qi::eol) >> *qi::eol > qi::eoi, qi::blank, sections);
我也有这样的感觉,我使线条结束处理比应该更复杂......
答案 0 :(得分:1)
阅读parsing into several vector members后,我发现只使用语义动作的解决方案。
结构定义保持不变:
struct Section
{
std::string name;
std::vector<std::string> requirements;
Pairs properties;
};
不再使用adapt struct。
语法变为:
template <typename Iterator, typename Skipper>
struct SectionParser : qi::grammar<Iterator, Section(), Skipper>
{
qi::rule<Iterator, Section(), Skipper> start;
qi::rule<Iterator, std::string()> value, ident, name, component;
qi::rule<Iterator, std::pair<std::string, std::string>()> pair;
SectionParser()
: SectionParser::base_type(start, "section grammar")
{
auto add_component = phx::push_back(phx::bind(&Section::requirements, qi::_val), qi::_1);
auto add_pair = phx::insert(phx::bind(&Section::properties, qi::_val), qi::_1);
auto set_name = phx::assign(phx::bind(&Section::name, qi::_val), qi::_1);
ident = +qi::char_("a-zA-Z0-9_");
component = qi::char_('@') > ident >> (qi::eol | qi::eoi);
value = *(qi::char_ - (qi::eol | qi::eoi));
pair = ident > qi::lit('=') > value >> (qi::eol | qi::eoi);
name = qi::lit('[') > ident > qi::lit(']') >> (qi::eol | qi::eoi);
start = name[set_name] >> *(component[add_component] | pair[add_pair]);
}
};