gpt4 book ai didi

c++ - 促进灵气属性传播

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:49:09 25 4
gpt4 key购买 nike

我遇到了一个 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 , 和字符解析器属性 here , 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.

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

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

最佳答案

问题似乎是因为你混搭了>>>在这里。

虽然您正确地观察了记录的属性生成规则,但真正似乎发生的是 Unused边更像是fusion::vector1<qi::unused_type> (而不是 qi::unused_type )。

Side note:
This also explains "Why does this work when parenthesized?" -
you are altering the order of expression evaluation (overruling operator precedence)
and getting another type.

您可以使用诸如Detecting the parameter types in a Spirit semantic action .

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


稍长的答案是:我认为您没有展示的内容更多

两件事:

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

    • 在某处使用 qi::raw[](很有可能)
    • 在你的一个 ast 结构中使用 iterator_pair(不太可能)
  2. 我可以编译你的“有问题的”规则样本,正好嵌入到我的“模型”语法中.

    • 查看我在下面使用的完整程序或查看它 previous question (我也是使用 GCC 4.7.3 和 boost 1.53 在本地编译的)

I think maybe you should try to post another question, while showing a Short Self Contained Correct Example that exhibits the problem you are 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;
}

关于c++ - 促进灵气属性传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18440896/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com