4

作为一个团队,我目前正在致力于国际化一个非常大的 Perl/ Mason Web 应用程序(这是否使这成为死亡行军??)。该应用程序已接近 20 年,并且是用相对老式的 Perl 风格编写的;它不使用 Moose 或其他 OO 模块。我目前正计划使用Locale::Maketext::Gettext进行消息查找,并使用 GNU Gettext 目录文件。

我一直在尝试开发一些工具来帮助从我们的 bigass 代码库中提取字符串。目前,我所拥有的只是一个相对简单的 Perl 脚本,用于通过源代码解析以查找字符串文字,提示用户一些上下文以及是否应将字符串标记为翻译,如果是则标记它。

我需要标记的字符串与我可以忽略的字符串相比,噪音太大了。源中的许多字符串不是面向用户的,例如哈希键,或类型比较,例如

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

我确实对每个提议的字符串应用了一些启发式方法,看看我是否可以立即忽略它(例如,我忽略了用于哈希查找的字符串,因为在我们的代码库中,99% 的时间这些字符串不是面向用户的)。然而,尽管如此,我的程序显示给我的大约 90% 的字符串是我不关心的。

有没有更好的方法可以帮助自动化我的字符串提取任务(即比从源代码中获取每个字符串文字更智能的方法)?是否有任何商业程序可以同时处理 Perl 和 Mason 源代码?

另外,我有一个(相当愚蠢的)关于一个优秀工具的想法,我把它的工作流程放在下面。是否值得付出努力来实现这样的事情(这可能会很快处理 80% 的工作),还是我应该接受一个费力、烦人的手动字符串提取过程?

  1. 首先从源中提取每个字符串文字,并将其放入 Gettext PO 文件中。
  2. 然后,编写一个 Mason 插件来解析应用程序所服务的每个页面的 HTML,目的是记录用户正在查看的字符串。
  3. 使用该应用程序并尝试涵盖所有用例,建立一个面向用户的字符串存储。
  4. 给定用户看到的字符串存储,对目录文件中的字符串进行模糊匹配,并跟踪与 UI 匹配的目录条目。
  5. 最后,目录文件中未匹配的任何内容都可能不是面向用户的,因此请从目录中删除这些内容。
4

2 回答 2

4

我知道没有 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::ElementPPI::Node。或者您可以检查字符串的内容以确定它是否重要。

我不能走得更远,因为“重要”取决于你。

于 2011-10-04T20:21:55.180 回答
0

我们的源代码搜索引擎通常用于有效地搜索大型代码库,使用从它所知道的语言的词位构建的索引。语言列表非常广泛,包括 Java、C#、COBOL 和 ... Perl。词位提取器是语言精确的(因为它们是从我们的DMS Software Reengineering Toolkit中“偷来的”,这是一个与语言无关的程序转换系统,其中精度是基础)。

给定一个索引代码库,然后可以输入查询以查找任意的词位序列,而不管语言特定的空白;可以记录此类查询的命中及其位置。

极短的查询:

S

到搜索引擎查找所有分类为字符串的词法元素(关键字、变量名、注释都被忽略;只是字符串!)。(通常人们用正则表达式约束编写更复杂的查询,例如 S=*Hello 来查找以“Hello”结尾的字符串)

这里的相关性是源代码搜索引擎对 Perl 中字符串的词法语法有精确的了解(特别包括插值字符串的元素和所有古怪的转义序列)。所以上面的查询会找到 Perl 中的所有字符串;登录后,您将记录所有字符串及其位置。

这个特技实际上适用于搜索引擎理解的任何语言,因此它是一种为此类国际化任务提取字符串的相当通用的方法。

于 2011-10-08T17:10:06.910 回答