#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;
}