Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不能用升压精神X3解析空的C++结构 我试图解析一个头文件中定义的C++结构。我开始定义语法,但我有个问题_C++_Boost_Boost Spirit_Boost Spirit X3 - Fatal编程技术网

不能用升压精神X3解析空的C++结构 我试图解析一个头文件中定义的C++结构。我开始定义语法,但我有个问题

不能用升压精神X3解析空的C++结构 我试图解析一个头文件中定义的C++结构。我开始定义语法,但我有个问题,c++,boost,boost-spirit,boost-spirit-x3,C++,Boost,Boost Spirit,Boost Spirit X3,这是我的代码: #include <boost/spirit/home/x3.hpp> int main() { namespace x3 = boost::spirit::x3; // Parse "#if !defined XXX_X_" or "'#ifndef X_X" auto Ifndef = x3::skip(x3::space)[(x3::lit('#') >> (x3::lit("ifndef") | (x3::lit("if") >

这是我的代码:

#include <boost/spirit/home/x3.hpp>

int main() {
  namespace x3 = boost::spirit::x3;

  // Parse "#if !defined XXX_X_" or "'#ifndef X_X"
  auto Ifndef = x3::skip(x3::space)[(x3::lit('#') >> (x3::lit("ifndef") | (x3::lit("if") >> x3::lit("!defined"))))];
  auto HeaderGuardFirstRow = Ifndef >> +(x3::alnum | '_');

  // Parse "#define XXX_X" or "#  define XXX_X"
  auto Define = x3::skip(x3::space)[(x3::lit('#') >> x3::lit("define"))];
  auto HeaderGuardSecondRow = Define >> +(x3::alnum | '_');

  // Parse
  // "
  //  #if !defined XXX_X_
  //  #define XXX_X
  // "
  auto HeaderGuardBegin = HeaderGuardFirstRow >> HeaderGuardSecondRow;

  // Parse "#endif" or "#  endif"
  auto HeaderGuardEnd = x3::skip(x3::space)[x3::lit('#') >> (x3::lit("endif"))];

  // Parse variable name like "xxx" or "my_var"
  auto VariableName = x3::lexeme[x3::char_("a-zA-Z_") >> *(x3::alnum | x3::lit("_"))];

  // Skipper for C++ comments (nested /* */ are not handled for now)
  auto SingleLineComment = "//" >> *(x3::char_ - x3::eol) >> (x3::eol | x3::eoi);
  auto BlockComment = "/*" >> *(x3::char_ - "*/") >> "*/";
  auto Skipper = SingleLineComment | BlockComment | x3::ascii::space;

  // Parse
  // "
  // typedef struct {
  // } MyStruct;
  // "
  // ERROR: This parse does not work
  auto StructType = -x3::lit("typedef") >> x3::skip(Skipper)[x3::lit("struct") >> x3::lit('{')] >>
  x3::skip(Skipper)[x3::lit('}') >> VariableName >> x3::lit(";")];

  // Header grammar. Should parse
  // "
  // #if !defined XXX_H
  //  #define XXX_H
  //  typedef struct {
  //  } MyStruct;
  //  #endif
  // "
  auto grammar = HeaderGuardBegin >> *(StructType) >> HeaderGuardEnd;

  std::string data01(R"xx(
    #if !defined XXX_H
    #define XXX_H
    #endif
  )xx");

  bool r = phrase_parse(
    data01.begin(),
    data01.end(),
    grammar,
    Skipper
    );

    std::string data02(R"xx(
    #if !defined XXX_H
    // Single line comment
    #define XXX_H
    #endif // !XXX_H
  )xx");

  r = phrase_parse(
    data02.begin(),
    data02.end(),
    grammar,
    Skipper
    );

  std::string data03(R"xx(
    #if !defined XXX_H
    #define XXX_H
    typedef struct {
    } MyStruct;
    #endif
  )xx");

  // r = false: This parsing does not work.
  r = phrase_parse(
    data03.begin(),
    data03.end(),
    grammar,
    Skipper
    );
  return 0;
}
在代码中有三个字符串要解析:一个只有头标识符,第二个像第一个,但是有一些C++注释,第三个是空结构。 这是最后一个无法解析的,我不明白为什么。在我用于structStructType的语法中,我首先检查可选的typedef,然后检查带有{字符(可附加或不可附加)的关键字struct,然后搜索}字符,后跟变量名,后跟

我不明白错误在哪里。解析空结构时我做错了什么?

几件事:

跳过程序由周围的上下文继承 您在标题保护中的标记周围没有lexeme[],因此它将匹配包括typedefstruct的标记,因为空格还包括行尾。 你可以简化事情:


sehe在保存代码方面做得非常出色。但因为我对你有自己的想法,所以我想我会发布。我确实从中了解到,船长可能相当复杂。另一方面,我通常跳过省略

因为你似乎想扔掉所有的起跑线和评论,我把它浓缩了下来。在某个时刻,我确信您将解析到一个属性。因此,我从结构名开始,因此是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

谢谢我想扔掉页眉保护,但我需要定义,因为它们的值可以作为严格意义上的数组大小。但我想一步一步。你是否考虑过使用LBCLCUN来做你需要的而不是重新发明一个著名的复杂的轮子?@ LaKeweb如果我们允许简化的话,你可以考虑使用Advest[]来代替:谢谢你。对于这类工作来说要简洁得多。
#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