我目前正在国际化一个非常大的Perl/Mason web应用程序,作为一个团队(这会使这成为死亡行军吗??)这个应用程序已经有将近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%的工作),或者我应该提交一个艰巨的,烦人的,手动字符串提取过程?
- 首先从源代码中提取每个字符串字面值,并将其放入Gettext PO文件中。 然后,编写一个Mason插件来解析应用程序所提供的每个页面的HTML,目的是记录用户看到的字符串。
- 使用应用程序并尝试覆盖所有用例,建立面向用户的字符串存储。
- 给定用户看到的字符串存储,对目录文件中的字符串进行模糊匹配,并跟踪来自UI的匹配的目录条目。
- 最后,目录文件中没有得到匹配的任何内容都可能不是面向用户的,因此从目录中删除这些内容。
据我所知,没有任何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::Element和PPI::Node。或者您可以检查字符串的内容以确定它是否有效。
我不能再多说了,因为"重要"取决于你。
我们的源代码搜索引擎通常用于有效地搜索大型代码库,使用从它所知道的语言的lexeme 构造的索引。这个语言列表相当广泛,包括Java、c#、COBOL和……Perl。词素提取器是语言精确的(因为它们是从我们的DMS软件再工程工具包中"偷来的",DMS软件再工程工具包是一个语言不可知的程序转换系统,其中精度是基本的)。
给定一个索引的代码库,然后可以输入查询来查找任意的词素序列,尽管有特定于语言的空白;您可以记录这些查询的命中数及其位置。
极短查询:
S
的搜索引擎找到分类为字符串的所有词法元素(关键字,变量名,注释都被忽略;字符串!)。(通常人们使用正则表达式约束编写更复杂的查询,例如S=*Hello来查找以"Hello"结尾的字符串)
这里的相关性是源代码搜索引擎对Perl中字符串的词法语法有精确的了解(包括插值字符串的特定元素和所有古怪的转义序列)。因此上面的查询将在Perl中找到所有字符串;通过登录,您将获得所有字符串及其位置的日志。
这个技巧实际上适用于搜索引擎可以理解的任何语言,因此它是为此类国际化任务提取字符串的一种相当通用的方法。