c++ - boost 灵气 : Compile error on slight rule change

标签 c++ boost boost-spirit boost-spirit-qi

我正在编写一个小编译器只是为了好玩,我正在使用 Boost Spirit Qi 来描述我的语法。现在我想对语法做一个小改动,以准备一些进一步的补充。不幸的是,这些更改无法编译,我想了解为什么会这样。

这是我要更改的代码片段。我希望提供的信息足以理解这个想法。完整的代码有点大,但如果你想查看甚至测试它(提供了 Makefile 和 Travis CI),请参阅 https://github.com/Kruecke/BFGenerator/blob/8f66aa5/bf/compiler.cpp#L433 .

typedef boost::variant<
    function_call_t,
    variable_declaration_t,
    variable_assignment_t,
    // ...
> instruction_t;

struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
    grammar() : grammar::base_type(program) {
        instruction = function_call
                    | variable_declaration
                    | variable_assignment
                 // | ...
                    ;

        function_call = function_name >> '(' > -(variable_name % ',') > ')' > ';';
        // ...
    }

    qi::rule<iterator, instruction::instruction_t(),   ascii::space_type> instruction;
    qi::rule<iterator, instruction::function_call_t(), ascii::space_type> function_call;
    // ...
};

到目前为止,一切正常。现在我想将尾部分号 (> ';') 的解析从 function_call 规则移动到 instruction 规则。我的代码现在看起来像这样:

struct grammar : qi::grammar<iterator, program_t(), ascii::space_type> {
    grammar() : grammar::base_type(program) {
        instruction = (function_call > ';') // Added trailing semicolon
                    | variable_declaration
                    | variable_assignment
                 // | ...
                    ;

        // Removed trailing semicolon here:
        function_call = function_name >> '(' > -(variable_name % ',') > ')';
        // ...
    }

根据我的理解,规则并没有真正改变,因为字符解析器 ';' 不产生任何属性,所以这个解析器的位置无关紧要。但是,此更改不会编译:

/usr/include/boost/spirit/home/support/container.hpp:278:13: error: no matching function for call to ‘std::basic_string<char>::insert(std::basic_string<char>::iterator, const bf::instruction::function_call_t&)’
             c.insert(c.end(), val);
             ^

(此错误来自 instruction = ... 行。)

为什么这个更改没有编译?我宁愿寻找一种解释来理解正在发生的事情,而不是一种解决方法。

最佳答案

好的,所以在仔细查看之后,您正在尝试将多个字符串插入到您的 function_call_t 类型中,这是一个可以从单个 std::string 转换为的 fusion 序列。但是,您可能会遇到 function_call 规则的问题,因为它的属性实际上是 tuple <std::string, optional <vector <std::string>>> .我想 spirit 在将该结构展平时遇到了问题,这导致了您的问题,但是,我目前没有编译器来测试它。

关于c++ - boost 灵气 : Compile error on slight rule change,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36405637/

相关文章:

c++ - 如何使用boost-spirit将结果放入STL图?

c++ - 使用 boostspirit 将 int 对解析为 vector

python - 将 C++ 类序列化为文件,然后在 Python 中进行基于事件的反序列​​化?

c++ - 在 C++ 中递归执行到你的函数有多远?

c++ - 将枚举转换为成员变量 [问题] C++

c++ - shared_ptr 和 iOS 中的引用计数是同一个思路吗?

c# - 将比特币 Base58 地址解码为字节数组

linux - Boost.Python 快速入门失败

c++ - boost function_input_iterator range 的快捷语法

c++ - Boost::spirit illegal_backtracking 异常