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

问题描述 投票:1回答:1

我需要为自定义语言为加引号的字符串创建一个解析器,该解析器还将正确处理转义序列,其中包括允许在字符串中使用转义引号。这是我当前的字符串解析器:

x3::lexeme[quote > *(x3::char_ - quote) > quote]

其中quote只是'"'的常量表达式。它不进行任何转义序列处理。我知道boost::spirit::classic::lex_escape_ch_p,但是我不知道如何将其与boost::spirit::x3工具一起使用(或一般而言)。我如何创建执行此操作的解析器?解析器必须识别大多数转义序列,例如'\n''\t'等常见的转义序列,以及十六进制,oct和ansi转义序列等更复杂的东西。

我很抱歉,如果这篇文章有什么问题,这是我第一次在SO上发表。

编辑:

这是我最终实现解析器的方式:

x3::lexeme[quote > *(
    ("\\\"" >> &x3::char_) >> x3::attr(quote) | ~x3::char_(quote)
    ) > quote]
[handle_escape_sequences];

其中handle_escape_sequences是lambda:

auto handle_escape_sequences = [&](auto&& context) -> void {
    std::string& str = x3::_val(context);

    uint32_t i{};

    static auto replace = [&](const char replacement) -> void {
        str[i++] = replacement;
    };

    if (!classic::parse(std::begin(str), std::end(str), *classic::lex_escape_ch_p[replace]).full)
        throw Error{ "invalid literal" }; // invalid escape sequence most likely

    str.resize(i);
};

它执行完整的ANSI转义序列解析,这意味着您可以使用它来进行各种精美的终端操作,例如使用它来设置文本颜色,光标位置等。

这里是规则的完整定义以及它所依赖的所有内容(我只是从代码中挑选了与之相关的所有内容,因此结果看起来像适当的意大利面条,以防万一有人需要它:] >

#include <boost\spirit\home\x3.hpp>
#include <boost\spirit\include\classic_utility.hpp>

using namespace boost::spirit;

#define RULE_DECLARATION(rule_name, attribute_type)                            \
inline namespace Tag { class rule_name ## _tag; }                              \
x3::rule<Tag::rule_name ## _tag, attribute_type, true> rule_name = #rule_name; \

#define SIMPLE_RULE_DEFINITION(rule_name, attribute_type, definition) \
RULE_DECLARATION(rule_name, attribute_type)                           \
auto rule_name ## _def = definition;                                  \
BOOST_SPIRIT_DEFINE(rule_name);

constexpr char quote = '"';


template <class Base, class>
struct Access_base_s : Base {
    using Base::Base, Base::operator=;
};

template <class Base, class Tag>
using Unique_alias_for = Access_base_s<Base, Tag>;


using String_literal = Unique_alias_for<std::string, class String_literal_tag>;

SIMPLE_RULE_DEFINITION(string_literal, String_literal,
    x3::lexeme[quote > *(
        ("\\\"" >> &x3::char_) >> x3::attr(quote) | ~x3::char_(quote)
        ) > quote]
    [handle_escape_sequences];
);

我需要为自定义语言为加引号的字符串创建一个解析器,该解析器还将正确处理转义序列,其中包括允许在字符串中使用转义引号。这是我当前的字符串...

c++ parsing boost boost-spirit boost-spirit-x3
1个回答
1
投票

我在此站点上有很多例子,

© www.soinside.com 2019 - 2024. All rights reserved.