Я пытаюсь разобрать escape-коды 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
, но это было бы крайне неэффективно (я знаю, преждевременная оптимизация, бла-бла).
Я надеялся, что есть какой-то элегантный способ вместо того, чтобы пройти через несколько обручей, чтобы это сработало (symbols
добавление строк к результату).
Однако я опасаюсь, что использование значений кодовой точки и отсутствие UTF8 повлечет за собой затраты времени на конвертацию (или есть constexpr
UTF32-> UTF8 возможна конвертация?).
Пример парсера JSON в cierelabs демонстрирует подход, который использует семантические действия для добавления кодовых точек в кодировке 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
Других решений пока нет …