#define BOOST_SPIRIT_USE_PHOENIX_V3
#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/adapted.hpp>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <fstream>
struct IniSection
{
std::string name;
std::vector<std::string> inherits;
std::vector<std::string> components;
std::map<std::string, std::string> properties;
};
typedef std::map<std::string, std::string> Properties;
BOOST_FUSION_ADAPT_STRUCT(
IniSection,
(std::string, name)
(std::vector<std::string>, inherits)
(std::vector<std::string>, components)
(Properties, properties)
)
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
template<typename Iterator>
struct SkipperWithComments : public qi::grammar<Iterator>
{
qi::rule<Iterator> skip, comment, multi_comment;
SkipperWithComments()
: SkipperWithComments::base_type(skip, "skipper grammar")
{
comment = (qi::lit("//") | qi::lit(";") | qi::lit("#")) >> *(qi::char_ - qi::eol) >> qi::eol;
multi_comment = "/*" > *(qi::char_ - "*/") > "*/";
skip = qi::blank | comment | multi_comment;
//BOOST_SPIRIT_DEBUG_NODES((skip)(comment)(multi_comment));
}
};
template <typename Iterator, typename Skipper>
struct SectionParser : qi::grammar<Iterator, IniSection(), Skipper>
{
qi::rule<Iterator, IniSection(), Skipper> section;
qi::rule<Iterator, std::string(), Skipper> ident, value;
qi::rule<Iterator, std::vector<std::string>(), Skipper> sectionInherits, components;
qi::rule<Iterator, std::pair<std::string, std::string>(), Skipper> prop;
qi::rule<Iterator, std::map<std::string, std::string>(), Skipper> props;
SectionParser()
: SectionParser::base_type(section, "section grammar")
{
ident = +qi::char_("a-zA-Z0-9_");
value = *(qi::char_ - (qi::eol));
sectionInherits = qi::lit(':') >> ident % ',';
components = *qi::eol >> (qi::as_string[qi::char_('@') >> ident] % +qi::eol);
prop = ident >> qi::lit('=') >> value;
props = *qi::eol >> (prop % +qi::eol);
section =
qi::lit('[')
>> qi::as_string[-qi::char_("!") >> ident]
>> -sectionInherits
>> qi::lit(']')
>> -components
>> -props;
BOOST_SPIRIT_DEBUG_NODES((section)(components)(sectionInherits)(ident)(value)(props)(prop));
}
};
template <typename Iterator, typename Skipper>
bool parse_numbers(Iterator first, Iterator last, const Skipper& skipper, std::vector<IniSection>& sections)
{
SectionParser<Iterator, Skipper> sectionParser;
try
{
bool ok = qi::phrase_parse(first, last, *qi::eol >> (sectionParser % +qi::eol) >> qi::eoi, skipper, sections);
if (first != last)
{
std::cout << "warning, part of input is unparsed: " << std::string(first, last) << std::endl;
return false;
}
return ok;
}
catch (qi::expectation_failure<Iterator> const& e)
{
std::cout << "parse error: " << e.what() << ", unparsed: " << std::string(first, last) << std::endl;
return false;
}
}
template <typename Iterator>
bool doParse(Iterator first, Iterator last, std::vector<IniSection>& sections)
{
return parse_numbers(first, last, SkipperWithComments<Iterator>(), sections);
}
bool parse(const std::string& input, std::vector<IniSection>& out)
{
return doParse(input.begin(), input.end(), out);
}
bool parse(boost::spirit::istream_iterator first, boost::spirit::istream_iterator last, std::vector<IniSection>& out)
{
return doParse(first, last, out);
}
int main()
{
boost::spirit::istream_iterator begin(std::cin >> std::noskipws);
boost::spirit::istream_iterator end;
std::vector<IniSection> sections;
if (parse(begin, end, sections))
{
std::cout << "success!" << std::endl;
return 0;
}
std::cout << "fail!" << std::endl;
return -1;
}
I2RlZmluZSBCT09TVF9TUElSSVRfVVNFX1BIT0VOSVhfVjMKI2RlZmluZSBCT09TVF9TUElSSVRfREVCVUcKI2luY2x1ZGUgPGJvb3N0L3NwaXJpdC9pbmNsdWRlL3FpLmhwcD4KI2luY2x1ZGUgPGJvb3N0L3NwaXJpdC9pbmNsdWRlL3Bob2VuaXguaHBwPgojaW5jbHVkZSA8Ym9vc3QvZnVzaW9uL2FkYXB0ZWQuaHBwPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxmc3RyZWFtPgoKc3RydWN0IEluaVNlY3Rpb24KewoJc3RkOjpzdHJpbmcgbmFtZTsKCXN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBpbmhlcml0czsKCXN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBjb21wb25lbnRzOwoJc3RkOjptYXA8c3RkOjpzdHJpbmcsIHN0ZDo6c3RyaW5nPiBwcm9wZXJ0aWVzOwp9OwoKdHlwZWRlZiBzdGQ6Om1hcDxzdGQ6OnN0cmluZywgc3RkOjpzdHJpbmc+IFByb3BlcnRpZXM7CkJPT1NUX0ZVU0lPTl9BREFQVF9TVFJVQ1QoCglJbmlTZWN0aW9uLAoJKHN0ZDo6c3RyaW5nLCBuYW1lKQoJKHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiwgaW5oZXJpdHMpCgkoc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+LCBjb21wb25lbnRzKQoJKFByb3BlcnRpZXMsIHByb3BlcnRpZXMpCikKCm5hbWVzcGFjZSBxaSA9IGJvb3N0OjpzcGlyaXQ6OnFpOwpuYW1lc3BhY2UgcGh4ID0gYm9vc3Q6OnBob2VuaXg7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBJdGVyYXRvcj4Kc3RydWN0IFNraXBwZXJXaXRoQ29tbWVudHMgOiBwdWJsaWMgcWk6OmdyYW1tYXI8SXRlcmF0b3I+CnsKCXFpOjpydWxlPEl0ZXJhdG9yPiBza2lwLCBjb21tZW50LCBtdWx0aV9jb21tZW50OwoKCVNraXBwZXJXaXRoQ29tbWVudHMoKQoJCTogU2tpcHBlcldpdGhDb21tZW50czo6YmFzZV90eXBlKHNraXAsICJza2lwcGVyIGdyYW1tYXIiKQoJewoJCWNvbW1lbnQgPSAocWk6OmxpdCgiLy8iKSB8IHFpOjpsaXQoIjsiKSB8IHFpOjpsaXQoIiMiKSkgPj4gKihxaTo6Y2hhcl8gLSBxaTo6ZW9sKSA+PiBxaTo6ZW9sOwoJCW11bHRpX2NvbW1lbnQgPSAiLyoiID4gKihxaTo6Y2hhcl8gLSAiKi8iKSA+ICIqLyI7CgkJc2tpcCA9IHFpOjpibGFuayB8IGNvbW1lbnQgfCBtdWx0aV9jb21tZW50OwoJCS8vQk9PU1RfU1BJUklUX0RFQlVHX05PREVTKChza2lwKShjb21tZW50KShtdWx0aV9jb21tZW50KSk7Cgl9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcmF0b3IsIHR5cGVuYW1lIFNraXBwZXI+CnN0cnVjdCBTZWN0aW9uUGFyc2VyIDogcWk6OmdyYW1tYXI8SXRlcmF0b3IsIEluaVNlY3Rpb24oKSwgU2tpcHBlcj4KewoJcWk6OnJ1bGU8SXRlcmF0b3IsIEluaVNlY3Rpb24oKSwgU2tpcHBlcj4gc2VjdGlvbjsKCXFpOjpydWxlPEl0ZXJhdG9yLCBzdGQ6OnN0cmluZygpLCBTa2lwcGVyPiBpZGVudCwgdmFsdWU7CglxaTo6cnVsZTxJdGVyYXRvciwgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+KCksIFNraXBwZXI+IHNlY3Rpb25Jbmhlcml0cywgY29tcG9uZW50czsKCXFpOjpydWxlPEl0ZXJhdG9yLCBzdGQ6OnBhaXI8c3RkOjpzdHJpbmcsIHN0ZDo6c3RyaW5nPigpLCBTa2lwcGVyPiBwcm9wOwoJcWk6OnJ1bGU8SXRlcmF0b3IsIHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLCBzdGQ6OnN0cmluZz4oKSwgU2tpcHBlcj4gcHJvcHM7CgoJU2VjdGlvblBhcnNlcigpCgkJOiBTZWN0aW9uUGFyc2VyOjpiYXNlX3R5cGUoc2VjdGlvbiwgInNlY3Rpb24gZ3JhbW1hciIpCgl7CgkJaWRlbnQgPSArcWk6OmNoYXJfKCJhLXpBLVowLTlfIik7CgkJdmFsdWUgPSAqKHFpOjpjaGFyXyAtIChxaTo6ZW9sKSk7CgoJCXNlY3Rpb25Jbmhlcml0cyA9IHFpOjpsaXQoJzonKSA+PiBpZGVudCAlICcsJzsKCgkJY29tcG9uZW50cyA9ICpxaTo6ZW9sID4+IChxaTo6YXNfc3RyaW5nW3FpOjpjaGFyXygnQCcpID4+IGlkZW50XSAlICtxaTo6ZW9sKTsKCgkJcHJvcCA9IGlkZW50ID4+IHFpOjpsaXQoJz0nKSA+PiB2YWx1ZTsKCQlwcm9wcyA9ICpxaTo6ZW9sID4+IChwcm9wICUgK3FpOjplb2wpOwoKCQlzZWN0aW9uID0KCQkJcWk6OmxpdCgnWycpCgkJCT4+IHFpOjphc19zdHJpbmdbLXFpOjpjaGFyXygiISIpID4+IGlkZW50XQoJCQk+PiAtc2VjdGlvbkluaGVyaXRzCgkJCT4+IHFpOjpsaXQoJ10nKQoJCQk+PiAtY29tcG9uZW50cwoJCQk+PiAtcHJvcHM7CgoJCUJPT1NUX1NQSVJJVF9ERUJVR19OT0RFUygoc2VjdGlvbikoY29tcG9uZW50cykoc2VjdGlvbkluaGVyaXRzKShpZGVudCkodmFsdWUpKHByb3BzKShwcm9wKSk7Cgl9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcmF0b3IsIHR5cGVuYW1lIFNraXBwZXI+CmJvb2wgcGFyc2VfbnVtYmVycyhJdGVyYXRvciBmaXJzdCwgSXRlcmF0b3IgbGFzdCwgY29uc3QgU2tpcHBlciYgc2tpcHBlciwgc3RkOjp2ZWN0b3I8SW5pU2VjdGlvbj4mIHNlY3Rpb25zKQp7CglTZWN0aW9uUGFyc2VyPEl0ZXJhdG9yLCBTa2lwcGVyPiBzZWN0aW9uUGFyc2VyOwoKCXRyeQoJewoJCWJvb2wgb2sgPSBxaTo6cGhyYXNlX3BhcnNlKGZpcnN0LCBsYXN0LCAqcWk6OmVvbCA+PiAoc2VjdGlvblBhcnNlciAlICtxaTo6ZW9sKSA+PiBxaTo6ZW9pLCBza2lwcGVyLCBzZWN0aW9ucyk7CgoJCWlmIChmaXJzdCAhPSBsYXN0KQoJCXsKCQkJc3RkOjpjb3V0IDw8ICJ3YXJuaW5nLCBwYXJ0IG9mIGlucHV0IGlzIHVucGFyc2VkOiAiIDw8IHN0ZDo6c3RyaW5nKGZpcnN0LCBsYXN0KSA8PCBzdGQ6OmVuZGw7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXJldHVybiBvazsKCX0KCWNhdGNoIChxaTo6ZXhwZWN0YXRpb25fZmFpbHVyZTxJdGVyYXRvcj4gY29uc3QmIGUpCgl7CgkJc3RkOjpjb3V0IDw8ICJwYXJzZSBlcnJvcjogIiA8PCBlLndoYXQoKSA8PCAiLCB1bnBhcnNlZDogIiA8PCBzdGQ6OnN0cmluZyhmaXJzdCwgbGFzdCkgPDwgc3RkOjplbmRsOwoJCXJldHVybiBmYWxzZTsKCX0KfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEl0ZXJhdG9yPgpib29sIGRvUGFyc2UoSXRlcmF0b3IgZmlyc3QsIEl0ZXJhdG9yIGxhc3QsIHN0ZDo6dmVjdG9yPEluaVNlY3Rpb24+JiBzZWN0aW9ucykKewoJcmV0dXJuIHBhcnNlX251bWJlcnMoZmlyc3QsIGxhc3QsIFNraXBwZXJXaXRoQ29tbWVudHM8SXRlcmF0b3I+KCksIHNlY3Rpb25zKTsKfQoKYm9vbCBwYXJzZShjb25zdCBzdGQ6OnN0cmluZyYgaW5wdXQsIHN0ZDo6dmVjdG9yPEluaVNlY3Rpb24+JiBvdXQpCnsKCXJldHVybiBkb1BhcnNlKGlucHV0LmJlZ2luKCksIGlucHV0LmVuZCgpLCBvdXQpOwp9Cgpib29sIHBhcnNlKGJvb3N0OjpzcGlyaXQ6OmlzdHJlYW1faXRlcmF0b3IgZmlyc3QsIGJvb3N0OjpzcGlyaXQ6OmlzdHJlYW1faXRlcmF0b3IgbGFzdCwgc3RkOjp2ZWN0b3I8SW5pU2VjdGlvbj4mIG91dCkKewoJcmV0dXJuIGRvUGFyc2UoZmlyc3QsIGxhc3QsIG91dCk7Cn0KCmludCBtYWluKCkKewoJYm9vc3Q6OnNwaXJpdDo6aXN0cmVhbV9pdGVyYXRvciBiZWdpbihzdGQ6OmNpbiA+PiBzdGQ6Om5vc2tpcHdzKTsKCWJvb3N0OjpzcGlyaXQ6OmlzdHJlYW1faXRlcmF0b3IgZW5kOwoKCXN0ZDo6dmVjdG9yPEluaVNlY3Rpb24+IHNlY3Rpb25zOwoJaWYgKHBhcnNlKGJlZ2luLCBlbmQsIHNlY3Rpb25zKSkKCXsKCQlzdGQ6OmNvdXQgPDwgInN1Y2Nlc3MhIiA8PCBzdGQ6OmVuZGw7CgkJcmV0dXJuIDA7Cgl9CgoJc3RkOjpjb3V0IDw8ICJmYWlsISIgPDwgc3RkOjplbmRsOwoJcmV0dXJuIC0xOwp9
<section>
<try>[section]\n@one\n@two\n</try>
<ident>
<try>section]\n@one\n@two\np</try>
<success>]\n@one\n@two\nprop=val</success>
<attributes>[[s, e, c, t, i, o, n]]</attributes>
</ident>
<sectionInherits>
<try>]\n@one\n@two\nprop=val</try>
<fail/>
</sectionInherits>
<components>
<try>\n@one\n@two\nprop=val\n</try>
<ident>
<try>one\n@two\nprop=val\npr</try>
<success>\n@two\nprop=val\nprop2</success>
<attributes>[[@, o, n, e]]</attributes>
</ident>
<ident>
<try>two\nprop=val\nprop2=v</try>
<success>\nprop=val\nprop2=val2</success>
<attributes>[[@, t, w, o]]</attributes>
</ident>
<success>\nprop=val\nprop2=val2</success>
<attributes>[[[@, o, n, e], [@, t, w, o]]]</attributes>
</components>
<props>
<try>\nprop=val\nprop2=val2</try>
<prop>
<try>prop=val\nprop2=val2</try>
<ident>
<try>prop=val\nprop2=val2</try>
<success>=val\nprop2=val2</success>
<attributes>[[p, r, o, p]]</attributes>
</ident>
<value>
<try>val\nprop2=val2</try>
<success>\nprop2=val2</success>
<attributes>[[v, a, l]]</attributes>
</value>
<success>\nprop2=val2</success>
<attributes>[[[p, r, o, p], [v, a, l]]]</attributes>
</prop>
<prop>
<try>prop2=val2</try>
<ident>
<try>prop2=val2</try>
<success>=val2</success>
<attributes>[[p, r, o, p, 2]]</attributes>
</ident>
<value>
<try>val2</try>
<success></success>
<attributes>[[v, a, l, 2]]</attributes>
</value>
<success></success>
<attributes>[[[p, r, o, p, 2], [v, a, l, 2]]]</attributes>
</prop>
<success></success>
<attributes>[[[[p, r, o, p], [v, a, l]], [[p, r, o, p, 2], [v, a, l, 2]]]]</attributes>
</props>
<success></success>
<attributes>[[[s, e, c, t, i, o, n], [], [[@, o, n, e], [@, t, w, o]], [[[p, r, o, p], [v, a, l]], [[p, r, o, p, 2], [v, a, l, 2]]]]]</attributes>
</section>