如何从Boost Spirit X3 lexeme解析器中获取字符串?

约瑟里克

进行从基于的典型标识符解析器中提取字符串的语义动作的最简单方法是什么boost::spirit::x3::lexeme

我认为可能可以绕开需要解压缩属性的过程,而仅在输入流中使用迭代器,但显然x3::_where并没有达到我的想法。

以下产量output为空。我希望它包含“ foobar_hello”。

namespace x3 = boost::spirit::x3;

using x3::_where;
using x3::lexeme;
using x3::alpha;

auto ctx_to_string = [&](auto& ctx) {
    _val(ctx) = std::string(_where(ctx).begin(), _where(ctx).end());
};

x3::rule<class identifier_rule_, std::string> const identifier_rule = "identifier_rule";
auto const identifier_rule_def = lexeme[(x3::alpha | '_') >> *(x3::alnum | '_')][ctx_to_string];
BOOST_SPIRIT_DEFINE(identifier_rule);

int main()
{
    std::string input = "foobar_hello";

    std::string output;
    auto result = x3::parse(input.begin(), input.end(), identifier_rule, output);
}

我是否需要以某种方式从boost :: fusion对象中提取字符串,x3::_attr(ctx)或者我做错了什么?

看到

您可以简单地使用自动属性传播,这意味着您不需要语义动作(1)

Live On Coliru

#include <iostream>
#include <iomanip>
#define BOOST_SPIRIT_X3_DEBUG
#include <boost/spirit/home/x3.hpp>
namespace x3 = boost::spirit::x3;

namespace P {
    x3::rule<class identifier_rule_, std::string> const identifier_rule = "identifier_rule";
    auto const identifier_rule_def = x3::lexeme[(x3::alpha | x3::char_('_')) >> *(x3::alnum | x3::char_('_'))];
    BOOST_SPIRIT_DEFINE(identifier_rule)
}

int main() {
    std::string const input = "foobar_hello";

    std::string output;
    auto result = x3::parse(input.begin(), input.end(), P::identifier_rule, output);
}

版画

<identifier_rule>
  <try>foobar_hello</try>
  <success></success>
  <attributes>[f, o, o, b, a, r, _, h, e, l, l, o]</attributes>
</identifier_rule>

注意我已更改'_'x3::char_('_')捕获下划线(x3::lit不捕获匹配的内容)

如果你坚持语义动作,

  • 考虑使用rule<..., std::string, true>迫使自动attrobute传播
  • 不要以为_where您的希望是指向:http : //coliru.stacked-crooked.com/a/336c057dabc86a84
  • 用于x3::raw[]公开受控的源迭代器范围(http://coliru.stacked-crooked.com/a/80a69ae9b99a4c61

    auto ctx_to_string = [](auto& ctx) {
        std::cout << "\nSA: '" << _attr(ctx) << "'" << std::endl;
        _val(ctx) = std::string(_attr(ctx).begin(), _attr(ctx).end());
    };
    
    x3::rule<class identifier_rule_, std::string> const identifier_rule = "identifier_rule";
    auto const identifier_rule_def = x3::raw[ lexeme[(x3::alpha | '_') >> *(x3::alnum | '_')] ] [ctx_to_string];
    BOOST_SPIRIT_DEFINE(identifier_rule)
    

    请注意,现在char_('_')不再起作用了

  • 考虑使用内置的属性帮助器:http : //coliru.stacked-crooked.com/a/3e3861330494e7c9

    auto ctx_to_string = [](auto& ctx) {
        using x3::traits::move_to;
        move_to(_attr(ctx), _val(ctx));
    };
    

    请注意,这比内置属性传播的方式近似,尽管它比让Spirit管理它的灵活性要差得多

(1)强制链接:Boost Spirit:“语义行为是邪恶的”?

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从Boost Spirit X3解析器返回的向量中的空字符串

Boost Spirit x3:解析定界字符串

boost :: spirit :: x3中的简单字符串解析器不起作用

Boost Spirit X3跳过解析器实现?

boost spirit X3解析器,可将偏移量转换为原始字符串

创建带有转义序列处理功能的带引号的字符串的boost :: spirit :: x3解析器

Boost Spirit x3:解析为结构

使用Boost Spirit X3解析变体列表

使用 Boost Spirit X3 解析变体图

使用Boost Spirit x3解析类似查询的SQL

如何使用boost :: spirit :: x3测试字符串的有效双重内容?

使用Boost Spirit x3在单独的解析器中链接错误

boost :: spirit :: x3中的通用解析器生成器

Boost Spirit x3在直接解析时插入空字符串

使用Boost Spirit x3将数字解析为字符串

如何捕获由boost :: spirit :: x3解析器解析的值以在语义动作的主体内使用?

用Boost Spirit X3编写解析器对未来有多安全?

Boost.Spirit X3解析器“没有类型名为type in(...)”

Boost Spirit x3解析器不适用于多个属性

Boost Spirit X3:跳过无能为力的解析器

无法使用lambda参数编译boost :: spirit :: x3解析器

Boost Spirit x3 - 解析器无法识别行尾

如何在VS2017中的Boost Spirit x3中制定递归规则

如何在Boost Spirit x3中替换左递归?

Boost Spirit x3无法编译

Boost.Spirit:将字符串对从 Qi 移植到 X3

如何使用单独的访问者类制作递归Spirit X3解析器

spirit x3规则无法在序列解析器中合成boost :: iterator_range类型的属性

具有调试输出(BOOST_SPIRIT_X3_DEBUG)的X3解析器段错误