gpt4 book ai didi

c++ - Boost Spirit QI 弦乐和跳音问题

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

所以我开始使用 Boost Spirit 库,它绝对令人惊叹!但一路走来,我遇到了很多错误——许多错误是因为我没有完全阅读文档。但在尽可能多地阅读之后,我对属性——关于跳过的字符串感到困惑。

目前我想检测一个类似 ASM 的标签并像这样在控制台中打印它:

    Identifier = qi::lexeme[qi::alpha >> (*qi::alnum | qi::lit("_"))]
Label = Identifier >> ":"
Syntax = Label[phx::bind(&Grammar::print, this, qi::_1)];

其中 phx::bind 调用一个简单的打印字符串函数来 cout。规则定义如下:

    qi::rule<Iterator, std::string(), ascii::space_type> Identifier;
qi::rule<Iterator, std::string(), ascii::space_type> Label;
qi::rule<Iterator, ascii::space_type> Syntax;

这行得通,但问题是,我不希望船长在标识符和“:”文字之间跳过。

我试过:

    Label = qi::lexeme [Identifier >> ":"]
Label = qi::no_skip[.................]
etc

但我收到错误消息,例如转换为参数 4 - 无法将 unused_skipper<..> 转换为 char_class<..>,这是有道理的。我还尝试删除规则定义中的船长类型,但没有用。然后我尝试将它混合起来并制作一些规则属性字符串,而其他规则则没有, - 并使用 as_string 将它们转换为字符串 - 工作,但输出为空。所以我在这里。难倒了。

我对属性传播有什么不了解的地方吗?或者也许是关于属性的一般信息。甚至可能是从非跳过序列返回字符串的方法?

有人能告诉我我的错误吗? &以后有关于属性的提示吗?

非常感谢,亚当。

最佳答案

词素解决方案确实有效。

no_skiplexeme 指令要求包含的解析器不使用 skipper,因此您需要将 Identifier 更改为

qi::rule<Iterator, std::string()> Identifier;

顺便说一下,里面的lexeme就变得多余了:

qi::rule<It, std::string()                > Identifier = qi::alpha >> *(qi::alnum | qi::char_("_"));
qi::rule<It, std::string(), qi::space_type> Label = qi::lexeme [ Identifier >> ':' ];
qi::rule<It, qi::space_type> Syntax = Label [ handle_label_(qi::_1) ];

事实上,您可以进一步减少它(通过在 Syntax 规则中进行预跳过):

static const rule<std::string::const_iterator, std::string()> 
Identifier = alpha >> *(alnum | char_("_")),
Label = Identifier >> ':';

一个完整的测试程序:查看它 Live on Coliru

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/phoenix/function/adapt_function.hpp>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

void handle_label(std::string const& s) { std::cout << "Parsed label '" << s << ":'\n"; }
BOOST_PHOENIX_ADAPT_FUNCTION(void, handle_label_, handle_label, 1)

bool using_lexeme(std::string const& input)
{
using namespace qi;
static const rule<std::string::const_iterator, std::string()>
Identifier = alpha >> *(alnum | char_("_")),
Label = Identifier >> ':';

auto f(input.begin()), l(input.end());
return phrase_parse(f, l, Label [ handle_label_(_1) ], space);
}

int main()
{
assert( using_lexeme("some_id:"));
assert( using_lexeme("some_id: "));
assert( using_lexeme(" some_id:"));
assert(!using_lexeme("some_id :"));
}

另外两个注意事项:

  • no_skip 也不会预先跳过(lexeme 的意思更像是“保持在一起”)。尝试差异,看看第三个测试用例如何失败

  • 您使用 lit('_') 会阻止将下划线附加到字符串属性。

关于c++ - Boost Spirit QI 弦乐和跳音问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20301770/

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