Как стать автором
Обновить

Комментарии 32

На мой взгляд, стоило бы лучше рассказать про какую-то другую часть библиотеки. Обработка текста посимвольно — достаточно тривиальная и неинтересная задача.
поддерживаю. Очень интересен модуль морфологии…
Я бы сказал, что и морфология — это стандартная и давно решенная задача. Интересен синтаксис, и, конечно, семантика. Ну или морфология, но со снятием омонимии (ну это уже ближе к синтаксису). Кстати, я не увидел в компонентах библиотеки задачу токенизации текста на предложения, а это, во-первых, нетривиальная задача, а во-вторых, от качества ее решения зависит точность работы остальных лингвистических функций библиотеки.
Синтаксис я в Strutext не перенес. У меня есть реализация синтаксического анализатора на основе алгоритма Эрли. Я из него сделал инструмент, примерно аналогичный по функционалу Томита парсеру от Яндекса. Код рабочий, но какие-то вещи надо конечно доработать, что-то в интерфейсе добавить. Самому мне это делать трудно, сейчас времени мало. Если бы были энтузиасты, то я бы выложил код, написал бы про принципы реализации, ну и вместе что-то полезное сделали бы.
Про морфологию напишу. Там есть несколько интересных вещей по аотовской модели. Ну и с технической точки зрения тоже наверное интересно кому-то будет.
Одно интересно, зачем таким образом реализована функция Is, хотелось тупо побольше когда сгенерировать? Вообще нет никакого смысла в шаблонном параметре.
Там же чуть ниже есть примеры использования, например:
return Is<LETTER>(code);
Текст прочитал, а в коде просмотрел inline, мой косяк, но всё равно, тут смысла в шаблонах нет. Можно и обычным аргументом прокинуть, будет Is(LETTER, code).
Думаю, автор посчитал свой вариант записи более красивым/понятным.
Там еще и неконсистентность в static const в том же заголовочном файле. Одна константа объявлена как static, а остальные нет. Хотя static вообще нигде там не нужен.
Но это мелочи :-)
Ваш вариант гоняет на рантайме через стек два параметра, а вариант автора — один.
Почти наверняка функция будет заинлайнена и никаких параметров не будет в принципе.
P.S. Но на мой взгляд шаблон лучше хотя бы тем, что параметр class_name по сути является compile-time параметром и по природе ближе к non-type template parameter.
Поддерживаю мысль по поводу шаблона. В одной из задач столкнулся с подобной дилеммой и после обдумывания тоже пришёл к выводу, что параметр, хоть и шаблонный, даёт больше гибкости, чем часть названия функции. А IsNumber() без шаблонных альтернатив может потом кого-нибудь и на макросы типа Is##type() спровоцировать.
Тут речь шла не о выборе между Is<NUMBER> и IsNumber, а о выборе между Is<NUMBER>(code) и Is(NUMBER, code).
Вообще упоминались в дискуссии и inline-функции автора, в форме IsNumber, о выборе между функциями такой сигнатурой и шаблонной функцией мне и хотелось сказать.
НЛО прилетело и опубликовало эту надпись здесь
Ну, предполагалось, что для более полного представления юникода. Всякие там сурогаты можно класть. Хотя, на самом деле, хотел полной поддержки работы UTF-8 итератора, код которого (в виде синшных функций) я взялс unicode.org. Там есть такой код:
// Go to loop of UTF-8 sequence reading.
    uint32_t decoded_symbol = 0;
    switch (extra_bytes_to_read) {
      case 5:
        symbol_.chain_[0] = *iter_;
        decoded_symbol += static_cast<uint8_t>(*iter_);
        decoded_symbol <<= 6;
        if (not Next()) {
          return;
        }
      case 4:
        symbol_.chain_[extra_bytes_to_read-4] = *iter_;
        decoded_symbol += static_cast<uint8_t>(*iter_);
        decoded_symbol <<= 6;
        if (not Next()) {
          return;
        }
      case 3:
        symbol_.chain_[extra_bytes_to_read-3] = *iter_;
        decoded_symbol += static_cast<uint8_t>(*iter_);
        decoded_symbol <<= 6;
        if (not Next()) {
          return;
        }
      case 2:
        symbol_.chain_[extra_bytes_to_read-2] = *iter_;
        decoded_symbol += static_cast<uint8_t>(*iter_);
        decoded_symbol <<= 6;
        if (not Next()) {
          return;
        }
      case 1:
        symbol_.chain_[extra_bytes_to_read-1] = *iter_;
        decoded_symbol += static_cast<uint8_t>(*iter_);
        decoded_symbol <<= 6;
        if (not Next()) {
          return;
        }
      case 0:
        symbol_.chain_[extra_bytes_to_read] = *iter_;
        decoded_symbol += static_cast<uint8_t>(*iter_);
    }

    // Magic numbers to process decoding.
    static const uint32_t OFFSETS_FROM_UTF8[6] = {
      0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL
    };
    decoded_symbol -= OFFSETS_FROM_UTF8[extra_bytes_to_read];

    symbol_.len_ = extra_bytes_to_read + 1;

    // Is the sequence legal?
    if (IsLegalUtf8((const uint8_t*)symbol_.chain_, symbol_.len_)) {
      // Increase symbol counter only, if correct symbol extracted.
      symbol_.utf32_ = decoded_symbol;
      ++sym_pos_;
    }
НЛО прилетело и опубликовало эту надпись здесь
Не очень понял комментарий. В таблице UnicodeData.txt используются коды, которые в два байта не помещаются. Например:
2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;;
2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;


Старший код это
10FFFD;<Plane 16 Private Use, Last>;Co;0;L;;;;;N;;;;;


Хотелось такие коды представлять естественным образом. Экономить на памяти 12 Мб против 24 Мб в наше время полагаю анахронизмом. Кому это надо, если chromium-browse у меня сейчас жрет 150 Мб, а thunderbird — 250?
Ну в каких-нибудь аналитических базах данных это может иметь весомое значение.
НЛО прилетело и опубликовало эту надпись здесь
Я не знаток JavaScript, просто так было написано в заметке, на которую я дал ссылку.
НЛО прилетело и опубликовало эту надпись здесь
Там пишут про 2 разные вещи: JavaScript строки и Gecko строки. Заметка о том, что представление JavaScript строк изменилось, и как авторы сопрягали новое представление JavaScript строк с двухбайтовыми Gecko строками.

After converting all of SpiderMonkey’s string code, I had to make Gecko work with Latin1 JS strings and unstable string characters. Gecko has its own TwoByte string types and in many cases it used to avoid copying the JS characters by using a nsDependentString.


Так что прежде чем обвинять кого-то что он «не понял» неплохо бы вам самому убедиться, что вы сами поняли.
НЛО прилетело и опубликовало эту надпись здесь
Вы категорически не правы (цитата из стандарта):

8.4
The String Type

The String type is the set of all finite ordered sequences of zero or more 16-bit unsigned integer values (―elements‖). The String type is generally used to represent textual data in a running ECMAScript program, in which case each element in the String is treated as a code unit value (see Clause 6). Each element is regarded as occupying a position within the sequence. These positions are indexed with nonnegative integers. The first element (if any) is at position 0, the next element (if any) at position 1, and so on. The length of a String is the number of elements (i.e., 16-bit values) within it. The empty String has length zero and therefore contains no elements.

When a String contains actual textual data, each element is considered to be a single UTF-16 code unit. Whether or not this is the actual storage format of a String, the characters within a String are numbered by their initial code unit element position as though they were represented using UTF-16. All operations on Strings (except as otherwise stated) treat them as sequences of undifferentiated 16-bit unsigned integers; they do not ensure the resulting String is in normalised form, nor do they ensure language-sensitive results.
НЛО прилетело и опубликовало эту надпись здесь
Если вы дочитаете до конца статью, откуда, возможно, взяли пример до исправления (который на моей системе показывался корректно, то есть проблема не в хабре, скорее всего), то обнаружите:

Conclusion

JavaScript engines are free to use UCS-2 or UTF-16 internally. Most engines that I know of use UTF-16, but whatever choice they made, it’s just an implementation detail that won’t affect the language’s characteristics.

The ECMAScript/JavaScript language itself, however, exposes characters according to UCS-2, not UTF-16.


Что никаким образом не противоречит исходному утверждению, что в Mozilla строки в JavaScript были в UTF-16.
utf-8 является де-факто стандартом для исходников в web-разработке, но не в строковом типе.
НЛО прилетело и опубликовало эту надпись здесь
Тон какой-то выбран излишне агрессивный, что-то личное? По теме, я не специалист по UNICODE, понятное дело, но вроде UTF-8 кодировку от UTF-16 отличить могу. Ниже я приводил код из программы, которая перекодирует UTF-8 последовательности в UTF-32 коды. Из кода видно, что в UTF-8 может использоваться до шести байтов включительно (даже не четыре, бывает и шесть), чтобы закодировать символ UNICODE. Именно для этой цели я и приводил код. Рассчитывал, что человек, который понимает UNICODE, видел и их код на C для перекодирования UTF-8 в UTF-32. Ну, наверное, просто опыта с C++ нет, потому и весь код мимо.

В кодировке UTF-16 для некоторых символов, коды которых не вмещаются в 2^16, используется четыре байта. Для эффективного кодирования классификатора символов на UTF-16 надо сделать нечто более сложное, чем просто обращение к ячейке памяти по коду (как это делается в UTF-32). Наверное, надо сделать сравнение на определенное число, если код больше этого числа, перейти на вектор дополнительных кодов для данного кода и найти соответствующий класс. Это все займет время и будет не так эффективно.

Вообще, в массиве классов хранятся не коды символов, а флаги классов для каждого символа, которые в любом случае занимают 4 байта и, собственно, к коду символа не имеют никакого отношения. А дискуссию относительно преимуществ и недостатков использования UTF-32 для классификации можно прочитать на сайте UNICODE, там приведены соответствующие соображения.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории