Обязательный ответ на основе Boost Spirit:
Основной:
typedef std::map<size_t, std::string> Result;
// ...
const std::string input = // TODO read from file :)
"TEXDEF 1 Resources/Textures/tex2.png\n"
"TEXDEF 0 Resources/Textures/tex.png\n"
"TEXDEF 2 Resources/Textures/tex3.png";
Result result;
if (doTest(input, result))
{
std::cout << "Parse results: " << std::endl;
for (Result::const_iterator it = result.begin(); it!= result.end(); ++it)
std::cout << "Mapped: " << it->first << " to " << it->second << std::endl;
}
Выход:
Parse results:
Mapped: 0 to Resources/Textures/tex.png
Mapped: 1 to Resources/Textures/tex2.png
Mapped: 2 to Resources/Textures/tex3.png
Полный код:
#include <string>
#include <map>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
namespace qi = boost::spirit::qi;
typedef std::map<size_t, std::string> Result;
template <typename Iterator, typename Skipper> struct TexDefs
: qi::grammar<Iterator, Result(), Skipper>
{
TexDefs()
: TexDefs::base_type(texdefs)
{
texdefs = def >> *(qi::eol >> def);
def = "TEXDEF" >> key >> filename;
key = qi::uint_;
filename = qi::lexeme [ +(qi::char_ - qi::eol) ];
}
typedef Result::key_type key_t;
typedef Result::mapped_type value_t;
qi::rule<Iterator, Result(), Skipper> texdefs;
qi::rule<Iterator, std::pair<key_t, value_t>(), Skipper> def;
qi::rule<Iterator, key_t(), Skipper> key;
qi::rule<Iterator, value_t(), Skipper> filename;
};
template <typename Input, typename Skip>
bool doTest(const Input& input, Result& into, const Skip& skip)
{
typedef typename Input::const_iterator It;
It first(input.begin()), last(input.end());
TexDefs<It, Skip> parser;
bool ok = qi::phrase_parse(first, last, parser, skip, into);
if (!ok) std::cerr << "Parse failed at '" << std::string(first, last) << "'" << std::endl;
if (first!=last) std::cerr << "Warning: remaining unparsed input: '" << std::string(first, last) << "'" << std::endl;
return ok;
}
template <typename Input>
bool doTest(const Input& input, Result& into)
{
// allow whitespace characters :)
return doTest(input, into, qi::char_(" \t"));
}
int main(int argc, const char *argv[])
{
const std::string input = // TODO read from file :)
"TEXDEF 1 Resources/Textures/tex2.png\n"
"TEXDEF 0 Resources/Textures/tex.png\n"
"TEXDEF 2 Resources/Textures/tex3.png";
Result result;
if (doTest(input, result))
{
std::cout << "Parse results: " << std::endl;
for (Result::const_iterator it = result.begin(); it!= result.end(); ++it)
std::cout << "Mapped: " << it->first << " to " << it->second << std::endl;
}
}