переопределение ctype <wchar_t>

Я пишу интерпретатор лямбда-исчисления для забавы и практики. Я заставил iostreams правильно маркировать идентификаторы путем добавления a ctype фасет, который определяет пунктуацию как пробел:

struct token_ctype : ctype<char> {
 mask t[ table_size ];
 token_ctype()
 : ctype<char>( t ) {
  for ( size_t tx = 0; tx < table_size; ++ tx ) {
   t[tx] = isalnum( tx )? alnum : space;
  }
 }
};

(classic_table() вероятно, было бы более чистым, но это не работает над OS X!)

И затем загрузите фасет, когда я поразил идентификатор:

locale token_loc( in.getloc(), new token_ctype );
…
locale const &oldloc = in.imbue( token_loc );
in.unget() >> token;
in.imbue( oldloc );

В сети, кажется, существует удивительно мало кода лямбда-исчисления. Большая часть того, что я нашел до сих пор, полна unicode λ персонажи. Так я думавший попытаться добавить поддержку Unicode.

Но ctype<wchar_t> работы полностью по-другому по сравнению с ctype<char>. Нет никакой основной таблицы; существует четыре метода do_is x2, do_scan_is, и do_scan_not. Таким образом, я сделал это:

struct token_ctype : ctype< wchar_t > {
 typedef ctype<wchar_t> base;

 bool do_is( mask m, char_type c ) const {
  return base::do_is(m,c)
  || (m&space) && ( base::do_is(punct,c) || c == L'λ' );
 }

 const char_type* do_is
  (const char_type* lo, const char_type* hi, mask* vec) const {
  base::do_is(lo,hi,vec);
  for ( mask *vp = vec; lo != hi; ++ vp, ++ lo ) {
   if ( *vp & punct || *lo == L'λ' ) *vp |= space;
  }
  return hi;
 }

 const char_type *do_scan_is
  (mask m, const char_type* lo, const char_type* hi) const {
  if ( m & space ) m |= punct;
  hi = do_scan_is(m,lo,hi);
  if ( m & space ) hi = find( lo, hi, L'λ' );
  return hi;
 }

 const char_type *do_scan_not
  (mask m, const char_type* lo, const char_type* hi) const {
  if ( m & space ) {
   m |= punct;
   while ( * ( lo = base::do_scan_not(m,lo,hi) ) == L'λ' && lo != hi )
    ++ lo;
   return lo;
  }
  return base::do_scan_not(m,lo,hi);
 }
};

(Извинения за плоское форматирование; предварительный просмотр преобразовал вкладки по-другому.)

Кодом является менее изящный ПУТЬ. Я действительно лучше выражаю понятие, что только пунктуация является дополнительным пробелом, но это было бы прекрасно в оригинале, имел, я имел classic_table.

Существует ли более простой способ сделать это? Мне действительно нужны все те перегрузки? (Тестирование показало do_scan_not является посторонним здесь, но я думаю более широко.) Я злоупотребляю фасетами во-первых? Вышеупомянутое даже корректно? Это был бы лучший стиль для реализации меньшего количества логики?

8
задан Potatoswatter 26 February 2010 в 05:37
поделиться

1 ответ

ИМХО, код, который вы разместили, в порядке. Вы можете реализовать некоторые методы, используя другие, если хотите более простой код (возможно, в ущерб эффективности), но то, как вы это сделали, в порядке.

Несоответствие основано на том факте, что люди не хотят иметь несколько мегабайтных таблиц в своих программах UNICODE.

2
ответ дан 5 December 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: