Се сделал отличную работу по сохранению вашего кода.Но так как у меня было собственное представление о том, кем ты был после того, как я думал, что опубликую.Из этого я узнал, что шкипер может быть довольно сложным.С другой стороны, я обычно пропускал omit
.
Поскольку кажется, что вы хотите выбросить все #
начальные строки и комментарии, я свел их к минимуму.В какой-то момент я уверен, что вы собираетесь анализировать атрибут.Итак, я начал с имени структуры, отсюда и строка dest
.
Просто еще один способ взглянуть на нее.
#include <iostream>
#define BOOST_SPIRIT_X3_DEBUG
#include <boost/spirit/home/x3.hpp>
using namespace boost::spirit::x3;
// Parse all/skip"#..."
auto const def = lit("#") >> omit[lexeme[*char_("a-zA-Z_! ")]];
// Skipper for C++ comments (nested /* */ are not handled for now)
auto const comment = ("//" >> omit[*(char_ - eol)]) | ("/*" >> omit[*(char_ - "*/")] >> "*/");
auto const skipper = *(def | comment | space);
// Parse variable name like "xxx" or "my_var"
auto const name = rule<struct name, std::string>("name") = *char_("a-zA-Z_");
auto const struct_rule = lit("typedef") >> "struct" >> '{' >> omit[*(char_-'}')] >> '}' >> name >> ';';
auto const final = skipper >> -struct_rule >> skipper;
void parse(char* in)
{
std::string str(in);
auto it = str.begin();
std::string dest;
bool r = phrase_parse(it, str.end(), final, space, dest);// , dest);
std::cout << std::boolalpha << "r: " << r << std::endl
<< std::string(it, str.end()) << std::endl
<< "DEST: " << dest << std::endl;
}
int main()
{
parse(R"xx(
#if !defined XXX_H
#define XXX_H
#endif
)xx");
parse(R"xx(
#if !defined XXX_H
// Single line comment
#define XXX_H
#endif // !XXX_H
)xx");
parse(R"xx(
#if !defined XXX_H
#define XXX_H
typedef struct {
} MyStruct;
#endif
)xx");
return 0;
}
Печать:
r: true
DEST:
r: true
DEST:
<name>
<try> MyStruct;\n\t\t#endif\n</try>
<success>;\n\t\t#endif\n\t </success>
<attributes>[M, y, S, t, r, u, c, t]</attributes>
</name>
r: true
DEST: MyStruct