Boost Spirit(X3)符号表产生UTF8字符串

Boost Spirit (X3) symbol tables resulting in UTF8 strings

本文关键字:UTF8 字符串 符号 Spirit X3 Boost      更新时间:2023-10-16

我正在尝试将LaTeX转义码(例如alpha)解析为Unicode(数学)字符(即U+1D6FC)。

现在这意味着我正在使用这个symbols解析器(规则):

struct greek_lower_case_letters_ : x3::symbols<char32_t>
{
  greek_lower_case_letters_::greek_lower_case_letters_()
  {
    add("alpha",   U'u03B1');
  }
} greek_lower_case_letter;

这很好,但意味着我得到了一个std::u32string。出于未来自动化和维护的原因,我想要一种优雅的方式来在代码中保留Unicode代码点。有没有办法让这种解析器解析成UTF-8 std::string

我曾想过将symbols结构解析为std::string,但这将是非常低效的(我知道,过早优化bla-bla)。

我希望有一种优雅的方式,而不是经历一堆麻烦来实现这一点(symbols在结果中添加字符串)。

不过,我确实担心使用代码点值并想要UTF8会导致转换的运行时成本(或者是否存在constexpr UTF32->UTF8转换的可能性?)。

cierelabs的JSON解析器示例显示了一种使用语义操作在utf8编码中附加代码点的方法:
  auto push_utf8 = [](auto& ctx)
  {
     typedef std::back_insert_iterator<std::string> insert_iter;
     insert_iter out_iter(_val(ctx));
     boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
     *utf8_iter++ = _attr(ctx);
  };
  // ...
  auto const escape =
         ('u' > hex4)           [push_utf8]
     |   char_(""\/bfnrt")    [push_esc]
     ;

这在他们的中使用

typedef x3::rule<unicode_string_class, std::string> unicode_string_type;

正如您所看到的,它将utf8序列构建为std::string属性。

有关完整代码,请参阅:https://github.com/cierelabs/json_spirit/blob/x3_devel/ciere/json/parser/x3_grammar_def.hpp