Автоматизированный способ извлечения строк для Perl / Mason i18n? - PullRequest
4 голосов
/ 04 октября 2011

В настоящее время я работаю над интернационализацией очень большого веб-приложения на Perl / Mason , как одной команды (делает ли это марш смерти ??).Приложению около 20 лет, и оно написано в относительно старомодном стиле Perl;он не использует Moose или другой модуль OO.В настоящее время я планирую использовать Locale :: Maketext :: Gettext для поиска сообщений и использовать файлы каталога GNU Gettext.

Я пытался разработать некоторые инструменты для помощи визвлечение строк из нашей большой кодовой базы.В настоящее время все, что у меня есть, - это относительно простой Perl-скрипт для анализа исходного кода в поисках строковых литералов, запроса пользователю некоторого контекста и того, должна ли строка быть помечена для перевода, и отметьте его, если так.

Слишком много шума с точки зрения строк, которые нужно пометить, по сравнению со строками, которые я могу игнорировать. Многие строки в источнике не ориентированы на пользователя, такие как хэш-ключи или сравнения типов, такие как

if (ref($db_obj) eq 'A::Type::Of::Db::Module')

Я применяю некоторую эвристику к каждой предложенной строке, чтобы увидеть, могу ли я игнорировать ее с нуля (например, я игнорирую строки, которые используются для поиска хеша, поскольку в нашей кодовой базе 99% времени это не так.не сталкивается с пользователем).Однако, несмотря на все это, около 90% строк, которые моя программа показывает мне, это те, которые меня не волнуют.

Есть ли лучший способ, которым я мог бы помочь автоматизировать мою задачу извлечения строк (то есть что-то более интеллектуальноечем захватить каждый строковый литерал из источника)?Существуют ли какие-либо коммерческие программы, которые делают это, которые могут работать как с Perl, так и с источником Mason?

ТАКЖЕ , у меня была (довольно глупая) идея для превосходного инструмента, рабочий процесс которого я изложил ниже.Стоит ли пытаться реализовать что-то подобное (что, вероятно, очень быстро позаботится о 80% работы), или я должен просто подчиниться трудному, надоедливому, ручному процессу извлечения строк?

  1. Начните с извлечения КАЖДОГО строкового литерала из источника и поместите его в PO-файл Gettext.
  2. Затем напишите плагин Mason для анализа HTML-кода для каждой страницы, обслуживаемой приложением, с целью отметить строки, которые видит пользователь.
  3. Используйте чертовски приложение и постарайтесь охватить все варианты использования, создав хранилище строк, обращенных к пользователю.
  4. Учитывая это хранилище строк, которое видел пользователь, проводите нечеткие сопоставления со строкамив файле каталога и отслеживайте записи каталога, которые совпадают с пользовательским интерфейсом.
  5. В конце концов, все, что не найдено в файле каталога, скорее всего, не предназначено для пользователя, поэтому удалите его из каталога.

Ответы [ 2 ]

4 голосов
/ 05 октября 2011

Нет известных мне инструментов Perl, которые бы интеллектуально извлекали строки, которые могут нуждаться в интернационализации, по сравнению с теми, которые не нужны. Вы должны пометить их в коде по мере их написания, но, как вы сказали, это не было сделано.

Вы можете использовать PPI для интеллектуального извлечения строки.

#!/usr/bin/env perl

use strict;
use warnings;

use Carp;
use PPI;

my $doc = PPI::Document->new(shift);

# See PPI::Node for docs on find
my $strings = $doc->find(sub {
    my($top, $element) = @_;
    print ref $element, "\n";

    # Look for any quoted string or here doc.
    # Does not pick up unquoted hash keys.
    return $element->isa("PPI::Token::Quote")   ||
           $element->isa("PPI::Token::HereDoc");
});

# Display the content and location.
for my $string (@$strings) {
    my($line, $row, $col) = @{ $string->location };
    print  "Found string at line $line starting at character $col.\n";
    printf "String content: '%s'\n", string_content($string);
}


# *sigh* PPI::Token::HereDoc doesn't have a string method
sub string_content {
    my $string = shift;
    return $string->isa("PPI::Token::Quote")   ? $string->string :
           $string->isa("PPI::Token::HereDoc") ? $string->heredoc :
           croak "$string is neither a here-doc nor a quote";
}

Вы можете провести более сложный анализ токенов, окружающих строки, чтобы определить, является ли это чем-то значимым. См. PPI :: Элемент и PPI :: Node для получения более подробной информации. Или вы можете проверить содержимое строки, чтобы определить, является ли она существенной.

Я не могу идти намного дальше, потому что "значительный" зависит от вас.

0 голосов
/ 08 октября 2011

Наша Система поиска исходного кода обычно используется для эффективного поиска больших баз кода с использованием индексов, составленных из лексем известных ей языков.Этот список языков довольно широк, включая Java, C #, COBOL и ... Perl.Экстракторы лексем точны в языке (потому что они «украдены» из нашего набора реинжиниринга программного обеспечения DMS , системы преобразования программ, не зависящей от языка, где точность является фундаментальной).

Учитывая индексированную кодовую базу, можно затем вводить запросы, чтобы найти произвольные последовательности лексем, несмотря на языковой пробел;можно регистрировать совпадения таких запросов и их местоположения.

Чрезвычайно короткий запрос:

S

к поисковой системе находит все лексические элементы, которые классифицируются как строки (ключевые слова, имена переменныхвсе комментарии игнорируются; просто строки!).(Обычно люди пишут более сложные запросы с ограничениями регулярных выражений, например, S = * Hello, чтобы найти строки, заканчивающиеся на «Hello»)

Релевантность здесь заключается в том, что поисковая система исходного кода точно знает лексический синтаксисстрок в Perl (включая, в частности, элементы интерполированных строк и все дурацкие escape-последовательности).Таким образом, запрос выше найдет все строки в Perl;при входе в систему вы регистрируете все строки и их расположение.

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

...