【问题标题】:Boost Spirit Qi: Compile error on slight rule change提升精神气:轻微规则更改编译错误
【发布时间】:2016-04-04 14:36:40
【问题描述】:

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

这是我要更改的代码中的一个 sn-p。我希望提供的信息足以理解这个想法。完整的代码有点大,但是如果你想看一下甚至测试一下(提供了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;
    // ...
};

到目前为止,一切正常。现在我想将结尾分号 (&gt; ';') 的解析从 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 = ... 行。)

为什么此更改无法编译?我宁愿寻找解释以了解发生了什么,而不是解决方法。

【问题讨论】:

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


    【解决方案1】:

    好的,所以仔细研究后,您正尝试将多个字符串插入您的 function_call_t 类型,这是一个可以从单个 std::string 转换为的融合序列。但是,您可能会遇到您的 function_call 规则的问题,因为它的属性实际上是 tuple &lt;std::string, optional &lt;vector &lt;std::string&gt;&gt;&gt;。我想精神在使结构变平时遇到问题,这导致了你的问题,但是,我目前没有编译器来测试它。

    【讨论】:

    • 你完全正确!在function_call_t 中只有一个std::string 从来都不是我想要的,所以我很惊讶我以前的代码首先运行!我在结构中添加了 std::vector&lt;std::string&gt; variable_names 并立即解决了问题。非常感谢!
    猜你喜欢
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    相关资源
    最近更新 更多