C++ 这是定义一组递归规则的正确方法吗?

C++ 这是定义一组递归规则的正确方法吗?,c++,parsing,boost,boost-spirit,boost-spirit-x3,C++,Parsing,Boost,Boost Spirit,Boost Spirit X3,前言:我问这个问题是因为出于某种原因,我无法编译我的代码。我只是想知道对spirit::x3的错误理解是否是原因 你好,我只是想核实一下;以下是(至少在技术上)为大量递归解析器定义规则的正确方法吗?因此,对于每个解析器,我执行以下操作: // This is for reference only, it greatly simplifies the process of defining attributes. template <class Tag, class... Bases>

前言:我问这个问题是因为出于某种原因,我无法编译我的代码。我只是想知道对spirit::x3的错误理解是否是原因

你好,我只是想核实一下;以下是(至少在技术上)为大量递归解析器定义规则的正确方法吗?因此,对于每个解析器,我执行以下操作:

// This is for reference only, it greatly simplifies the process of defining attributes.

template <class Tag, class... Bases> // the tag is for uniqueness
struct Access_base_s : Bases... {
    using base = Access_base_s;
    using Bases::Bases..., Bases::operator=...;
};
我组织了不同解析器的声明和定义,使它们分为两部分;它们都是先声明的,然后在所有它们都已声明时定义。通过声明,我的意思是定义了它们的属性结构,并声明了规则,通过定义,我的意思是实现了规则名称定义,并在规则上调用了BOOST_SPIRIT_DEFINE

我尝试了MSVC、G++和clang++的最新版本,所有这些版本:

  • 至少需要3分钟
  • 遇到一些没有正确错误消息的内部编译器错误
  • 中止并让我没有可执行文件
当我试图编译代码时。我已经有两天了,这也是为什么,sehe,如果你正在读这篇文章,你可能正在读,我没有把你对我最后一个精神问题的回答作为答案;我一直忙于编写编译器,还没有机会测试它

编辑:以下是仍然导致相同错误的解析器的简化代码:

DECLARE_RULE(string_literal, "", std::string);
DECLARE_RULE(identifier    , "", std::string);

struct list;
struct dictionary;
struct expression;

DECLARE_RULE(literal       , "", x3::variant<double, int, string_literal, x3::forward_ast<list>, x3::forward_ast<dictionary>>);
DECLARE_RULE(parameter_pack, "", std::vector<expression>);
DECLARE_RULE(invocation    , "", parameter_pack);
DECLARE_RULE(expression    , "", x3::variant<literal, identifier, invocation>);
DECLARE_RULE(list          , "", std::vector<expression>);
DECLARE_RULE(dictionary    , "", std::vector<fusion::vector<expression, expression>>);


struct statement;
struct declaration;

DECLARE_RULE(compound_statement    , "", std::vector<statement>);
DECLARE_RULE(control_block_body    , "", x3::variant<x3::forward_ast<statement>, compound_statement>);
DECLARE_RULE(identifier_sequence   , "", std::vector<identifier>);
DECLARE_RULE(function_definition   , "", fusion::vector<identifier, std::vector<identifier>, control_block_body>);
DECLARE_RULE(structure_definition  , "", fusion::vector<identifier, std::vector<declaration>>);
DECLARE_RULE(enumeration_definition, "", fusion::vector<identifier, std::vector<fusion::vector<identifier, int>>>);
DECLARE_RULE(namespace_scope       , "", std::vector<declaration>);
DECLARE_RULE(namespace_extension   , "", fusion::vector<identifier, namespace_scope>);
DECLARE_RULE(declaration           , "", x3::variant<function_definition, structure_definition, enumeration_definition, namespace_extension>);
DECLARE_RULE(for_loop              , "", fusion::vector<identifier, expression, control_block_body>);
DECLARE_RULE(while_loop            , "", fusion::vector<expression, control_block_body>);
DECLARE_RULE(if_else_statement     , "", fusion::vector<expression, control_block_body, control_block_body>);
DECLARE_RULE(switch_statement      , "", fusion::vector<expression, std::vector<fusion::vector<expression, control_block_body>>>);
DECLARE_RULE(control_statement     , "", x3::variant<for_loop, while_loop, if_else_statement, switch_statement>);
DECLARE_RULE(statement_terminator  , "", std::string);
DECLARE_RULE(statement             , "", fusion::vector<x3::variant<expression, declaration, control_statement>, statement_terminator>);



DEFINE_RULE(string_literal, x3::lexeme['"' > *x3::char_ > '"']); // just a placeholder
DEFINE_RULE(identifier    , x3::lexeme[(x3::alpha | x3::char_('_')) >> *(x3::alnum | x3::char_('_'))]);
DEFINE_RULE(literal       , x3::double_ | x3::int_ | string_literal_ | list_ | dictionary_)
DEFINE_RULE(parameter_pack, +expression_);
DEFINE_RULE(invocation    , '(' > parameter_pack_ > ')');
DEFINE_RULE(expression    , literal_ | identifier_ | invocation_);
DEFINE_RULE(list          , '[' > *expression_ > ']');
DEFINE_RULE(dictionary    , '{' > *(expression_ > ':' > expression_) > '}');


DEFINE_RULE(compound_statement, '{' > *statement_ > '}');
DEFINE_RULE(control_block_body, (':' > statement_) | compound_statement_);
DEFINE_RULE(identifier_sequence, +identifier_);
DEFINE_RULE(function_definition, x3::lit("") > '(' > identifier_ > *identifier_ > ')' > control_block_body_);
DEFINE_RULE(structure_definition, "" > identifier_ > namespace_scope_);
DEFINE_RULE(enumeration_definition, "" > identifier_ > '{' > *(identifier_ > '=' > x3::int_) > '}');
DEFINE_RULE(namespace_scope, '{' > *declaration_ > '}');
DEFINE_RULE(namespace_extension, "" > identifier_ > namespace_scope_);
DEFINE_RULE(declaration, function_definition_ | structure_definition_ | enumeration_definition_ | namespace_extension_);
DEFINE_RULE(for_loop, "" > identifier_ > "" > expression_ > control_block_body_);
DEFINE_RULE(while_loop, "" > expression_ > control_block_body_);
DEFINE_RULE(if_else_statement, "" > expression_ > control_block_body_ > "" > control_block_body_);
DEFINE_RULE(switch_statement, "" > expression_ > '{' > *("" > expression_ > control_block_body_) > '}');
DEFINE_RULE(control_statement, for_loop_ | while_loop_ | if_else_statement_ | switch_statement_);
DEFINE_RULE(statement_terminator, x3::string("") | x3::string("") | x3::string(""));
DEFINE_RULE(statement, (expression_ | declaration_ | control_statement_) > statement_terminator_);
我使宏变量化,以便有点作弊;它允许我传入模板类型,而不必担心预处理器的愚蠢。例如,
x3::variant
将计为两个独立的宏参数,而
\uuuu VA\uu ARGS\uuuu
修复了这一问题。无论您在哪里看到它,它总是只是属性的基本类型。宏的结果是属性类型为名称本身,解析器为名称本身,但其末尾附加了下划线,以符合
x3
之类的
x3::int

以下是驾驶员代码:

int main() {
    std::string str = read_file("filename");
    auto begin = std::begin(str), end = std::end(str);
    std::cout << std::boolalpha << x3::phrase_parse(begin, end, statement_, x3::ascii::space);
}
intmain(){
std::string str=read_文件(“文件名”);
自动开始=标准::开始(str),结束=标准::结束(str);

std::cout这是一个精神上的错误;修复者;修复将在1.76版本中。

这是一个精神上的错误;修复者;修复将在1.76版本中。

是的。这很有趣。但是没有你的代码就没什么可说的了。因为我们看不到它。我可能可以用你的片段编写我自己的代码,但99美元没有问题唯一“特别”的是你的
属性
强类型定义模式,但这并不令人担忧(我在某些属性上使用它)@sehe我将尝试从我的代码中分离出导致问题的解析器,并将其添加到明天的帖子中。此外,如果您以前在x3的上下文中遇到过它,我忘了特别提到MSVC,而不是仅仅崩溃实际上说“编译器的堆空间不足”.这可能意味着什么具体的事情吗?是的。有些事情发生了。我的酒鬼意识表明与更换队长有关(我以前见过),但我们会的see@sehe更改跳过程序是指更改跳过程序还是自行更改的跳过程序?使用例如
x3::skip()[]
是的。这很有趣。但是没有你的代码就没什么可说的了。因为我们看不到它。我可能可以用你的片段编写我自己的代码,但是99美元没有你描述的问题。唯一“特别”的是你的
属性
强类型定义模式,但这并不令人担忧(我在某些属性上使用它)@sehe我将尝试从我的代码中分离出导致问题的解析器,并将其添加到明天的帖子中。此外,如果您以前在x3的上下文中遇到过它,我忘了特别提到MSVC,而不是仅仅崩溃实际上说“编译器超出了堆空间”.这可能意味着什么具体的事情吗?是的。有些事情发生了。我的酒鬼意识表明与更换队长有关(我以前见过),但我们会的see@sehe更改跳过程序是指更改跳过程序或自行更改的跳过程序的行为?使用例如
x3::skip()[]
DECLARE_RULE(string_literal, "", std::string);
DECLARE_RULE(identifier    , "", std::string);

struct list;
struct dictionary;
struct expression;

DECLARE_RULE(literal       , "", x3::variant<double, int, string_literal, x3::forward_ast<list>, x3::forward_ast<dictionary>>);
DECLARE_RULE(parameter_pack, "", std::vector<expression>);
DECLARE_RULE(invocation    , "", parameter_pack);
DECLARE_RULE(expression    , "", x3::variant<literal, identifier, invocation>);
DECLARE_RULE(list          , "", std::vector<expression>);
DECLARE_RULE(dictionary    , "", std::vector<fusion::vector<expression, expression>>);


struct statement;
struct declaration;

DECLARE_RULE(compound_statement    , "", std::vector<statement>);
DECLARE_RULE(control_block_body    , "", x3::variant<x3::forward_ast<statement>, compound_statement>);
DECLARE_RULE(identifier_sequence   , "", std::vector<identifier>);
DECLARE_RULE(function_definition   , "", fusion::vector<identifier, std::vector<identifier>, control_block_body>);
DECLARE_RULE(structure_definition  , "", fusion::vector<identifier, std::vector<declaration>>);
DECLARE_RULE(enumeration_definition, "", fusion::vector<identifier, std::vector<fusion::vector<identifier, int>>>);
DECLARE_RULE(namespace_scope       , "", std::vector<declaration>);
DECLARE_RULE(namespace_extension   , "", fusion::vector<identifier, namespace_scope>);
DECLARE_RULE(declaration           , "", x3::variant<function_definition, structure_definition, enumeration_definition, namespace_extension>);
DECLARE_RULE(for_loop              , "", fusion::vector<identifier, expression, control_block_body>);
DECLARE_RULE(while_loop            , "", fusion::vector<expression, control_block_body>);
DECLARE_RULE(if_else_statement     , "", fusion::vector<expression, control_block_body, control_block_body>);
DECLARE_RULE(switch_statement      , "", fusion::vector<expression, std::vector<fusion::vector<expression, control_block_body>>>);
DECLARE_RULE(control_statement     , "", x3::variant<for_loop, while_loop, if_else_statement, switch_statement>);
DECLARE_RULE(statement_terminator  , "", std::string);
DECLARE_RULE(statement             , "", fusion::vector<x3::variant<expression, declaration, control_statement>, statement_terminator>);



DEFINE_RULE(string_literal, x3::lexeme['"' > *x3::char_ > '"']); // just a placeholder
DEFINE_RULE(identifier    , x3::lexeme[(x3::alpha | x3::char_('_')) >> *(x3::alnum | x3::char_('_'))]);
DEFINE_RULE(literal       , x3::double_ | x3::int_ | string_literal_ | list_ | dictionary_)
DEFINE_RULE(parameter_pack, +expression_);
DEFINE_RULE(invocation    , '(' > parameter_pack_ > ')');
DEFINE_RULE(expression    , literal_ | identifier_ | invocation_);
DEFINE_RULE(list          , '[' > *expression_ > ']');
DEFINE_RULE(dictionary    , '{' > *(expression_ > ':' > expression_) > '}');


DEFINE_RULE(compound_statement, '{' > *statement_ > '}');
DEFINE_RULE(control_block_body, (':' > statement_) | compound_statement_);
DEFINE_RULE(identifier_sequence, +identifier_);
DEFINE_RULE(function_definition, x3::lit("") > '(' > identifier_ > *identifier_ > ')' > control_block_body_);
DEFINE_RULE(structure_definition, "" > identifier_ > namespace_scope_);
DEFINE_RULE(enumeration_definition, "" > identifier_ > '{' > *(identifier_ > '=' > x3::int_) > '}');
DEFINE_RULE(namespace_scope, '{' > *declaration_ > '}');
DEFINE_RULE(namespace_extension, "" > identifier_ > namespace_scope_);
DEFINE_RULE(declaration, function_definition_ | structure_definition_ | enumeration_definition_ | namespace_extension_);
DEFINE_RULE(for_loop, "" > identifier_ > "" > expression_ > control_block_body_);
DEFINE_RULE(while_loop, "" > expression_ > control_block_body_);
DEFINE_RULE(if_else_statement, "" > expression_ > control_block_body_ > "" > control_block_body_);
DEFINE_RULE(switch_statement, "" > expression_ > '{' > *("" > expression_ > control_block_body_) > '}');
DEFINE_RULE(control_statement, for_loop_ | while_loop_ | if_else_statement_ | switch_statement_);
DEFINE_RULE(statement_terminator, x3::string("") | x3::string("") | x3::string(""));
DEFINE_RULE(statement, (expression_ | declaration_ | control_statement_) > statement_terminator_);
class empty_t {};

#define DEFINE_ATTRIBUTE(name, ...)                                                                                                                                                \
struct name : Access_base_s<class name ## _base_access_tag, std::conditional_t<!std::is_base_of_v<x3::position_tagged, __VA_ARGS__>, x3::position_tagged, empty_t>, __VA_ARGS__> { \
    using base::base, base::operator=;                                                                                                                                             \
} // the conditional is there to make sure each attribute inherits from position_tagged no more than once.

#define DECLARE_RULE(name, text, ...) \
DEFINE_ATTRIBUTE(name, __VA_ARGS__);  \
x3::rule<class name ## _tag, name, true> name ## _ = text

#define DEFINE_RULE(name, definition) \
auto name ## __def = definition;      \
BOOST_SPIRIT_DEFINE(name ## _)
int main() {
    std::string str = read_file("filename");
    auto begin = std::begin(str), end = std::end(str);
    std::cout << std::boolalpha << x3::phrase_parse(begin, end, statement_, x3::ascii::space);
}