提升灵气属性传播

2024-02-12

我的 Boost Spirit Qi 语法有问题,该语法发出不需要的类型,导致此编译错误:

error C2664: 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::insert(unsigned int,const std::basic_string<_Elem,_Traits,_Ax> &)' : cannot convert parameter 1 from 'std::_String_iterator<_Elem,_Traits,_Alloc>' to 'unsigned int'

这是导致问题的语法:

    qi::rule<Iterator, qi::unused_type()> gr_newline;

            // asmast::label() just contains an identifier struct that is properly emitted from gr_identifier
    qi::rule<Iterator, asmast::label(), skipper<Iterator> > gr_label;

    gr_newline = +( char_('\r')
                   |char_('\n')
                  );

这失败了:

gr_label = gr_identifier
           >> ':'
           > gr_newline;

但以下 所有工作:

// This parses OK
gr_label = gr_identifier
           > gr_newline;

// This also parses OK
gr_label = gr_identifier
           > ':'
           > gr_newline;

    // This also parses OK
    // **Why does this work when parenthesized?**
    gr_label = gr_identifier
           >> (':'
                > skip_grammar.gr_newline
              );

// This also parses OK
gr_label = gr_identifier
           >> omit[':'
                    > gr_newline];

我不明白为什么删除字符文字或省略它“修复”问题,但我不希望语​​法因此而混乱。

根据>>和>的复合属性规则发现here http://www.boost.org/doc/libs/1_43_0/libs/spirit/doc/html/spirit/qi/quick_reference/compound_attribute_rules.html#spirit.qi.quick_reference.compound_attribute_rules.notation和字符解析器属性here http://www.boost.org/doc/libs/1_51_0/libs/spirit/doc/html/spirit/qi/reference/char/char.html, gr_label 应该只发出 asmast::label

a: A, b: B --> (a >> b): tuple<A, B>
a: A, b: Unused --> (a >> b): A  <---- This one here is the one that should match so far as I understand
a: Unused, b: B --> (a >> b): B
a: Unused, b: Unused --> (a >> b): Unused


 Expression Attribute
 c          unused or if c is a Lazy Argument, the character type returned by invoking it. 

然而,不知何故,某些东西污染了预期的属性,并导致编译器错误。

所以我的问题是这个语法在哪里发出了不需要的属性,以及如何摆脱它。


问题似乎是因为你混合搭配> and >> here.

尽管您正确地遵守了记录的属性生成规则,但什么really似乎发生的是Unused侧面更像是fusion::vector1<qi::unused_type>(代替qi::unused_type).

边注:
这也解释了“为什么带括号时会起作用?" -
您正在改变表达式求值的顺序(推翻运算符优先级)
并得到另一种类型。

您可以使用诸如以下技术来确定我的预感是否正确:检测 Spirit 语义动作中的参数类型 https://stackoverflow.com/questions/9404189/detecting-the-parameter-types-in-a-spirit-semantic-action.

So, the 简短的回答是:这就是它的工作原理。无论这是一个错误、文档中的遗漏还是只是一个功能,在 SO 上讨论确实没有建设性。我参考了 [spirit-general] 邮件列表(注意他们也有一个活跃的 #IRC 频道)。


The 稍长一点答案是:我认为还有更多你没有展示的内容.

两件事情:

  1. 错误消息非常清楚地表明它正在尝试insert a string iterator*需要一个字符(或可转换)的地方。尽管我可以猜测,但我没有看到与您发布的任何代码有任何联系

    • 在某处使用 qi::raw[] (很可能)
    • 在你的 ast 结构之一中使用 iterator_pair (不太可能)
  2. 我可以编译你的“有问题的”规则样本,很好地嵌入到我的“模型”语法中,我根据你在你的代码中暴露的一点点进行猜测。上一个问题 https://stackoverflow.com/questions/18399896/boost-spirit-qi-expectation.

    • 请参阅下面我使用的完整程序或查看它在 Coliru 上实时运行 http://coliru.stacked-crooked.com/view?id=d710fc2b063fb28c79f15b9c87906b9e-e4c1374605e7ee935e94e8e1e68651e5(我还在本地使用 GCC 4.7.3 和 boost 1.53 编译了这个)

我想也许你应该尝试发布另一个问题,同时展示简短的独立正确示例 http://sscce.org/这表明了你的问题really having.

请务必提及所使用的编译器版本和 boost 版本。

完全工作的 SSCCE 示例

#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>

namespace qi    = boost::spirit::qi;

namespace asmast
{
    typedef std::string label;
}

template <typename It, typename Skipper = qi::blank_type>
    struct parser : qi::grammar<It, Skipper>
{
    parser() : parser::base_type(start)
    {
        using namespace qi;

        start = lexeme["Func" >> !(alnum | '_')] > function;
        function = gr_identifier
                    >> "{"
                    >> -(
                              gr_instruction
                            | gr_label
                          //| gr_vardecl
                          //| gr_paramdecl
                        ) % eol
                    > "}";

        gr_instruction_names.add("Mov", unused);
        gr_instruction_names.add("Push", unused);
        gr_instruction_names.add("Exit", unused);

        gr_instruction = lexeme [ gr_instruction_names >> !(alnum|"_") ] > gr_operands;
        gr_operands = -(gr_operand % ',');

        gr_identifier = lexeme [ alpha >> *(alnum | '_') ];
        gr_operand    = gr_identifier | gr_string;
        gr_string     = lexeme [ '"' >> *("\"\"" | ~char_("\"")) >> '"' ];

        gr_newline = +( char_('\r')
                       |char_('\n')
                      );

        gr_label = gr_identifier >> ':' > gr_newline;

        BOOST_SPIRIT_DEBUG_NODES((start)(function)(gr_instruction)(gr_operands)(gr_identifier)(gr_operand)(gr_string));
    }

  private:
    qi::symbols<char, qi::unused_type> gr_instruction_names;
    qi::rule<It, Skipper> start, function, gr_instruction, gr_operands, gr_operand, gr_string;
    qi::rule<It, qi::unused_type()> gr_newline;
    qi::rule<It, asmast::label(), Skipper> gr_label, gr_identifier;
};

int main()
{
    typedef boost::spirit::istream_iterator It;
    std::cin.unsetf(std::ios::skipws);
    It f(std::cin), l;

    parser<It, qi::blank_type> p;

    try
    {
        bool ok = qi::phrase_parse(f,l,p,qi::blank);
        if (ok)   std::cout << "parse success\n";
        else      std::cerr << "parse failed: '" << std::string(f,l) << "'\n";

        if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
        return ok;
    } catch(const qi::expectation_failure<It>& e)
    {
        std::string frag(e.first, e.last);
        std::cerr << e.what() << "'" << frag << "'\n";
    }

    return false;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

提升灵气属性传播 的相关文章

随机推荐