0

鉴于块不相互嵌套或自身嵌套,我如何在以下语句中匹配多行块:

       if (EXPR) BLOCK
       if (EXPR) BLOCK else BLOCK
       if (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
       unless (EXPR) BLOCK
       unless (EXPR) BLOCK else BLOCK
       unless (EXPR) BLOCK elsif (EXPR) BLOCK ... else BLOCK
       LABEL while (EXPR) BLOCK
       LABEL while (EXPR) BLOCK continue BLOCK
       LABEL until (EXPR) BLOCK
       LABEL until (EXPR) BLOCK continue BLOCK
       LABEL for (EXPR; EXPR; EXPR) BLOCK
       LABEL foreach VAR (LIST) BLOCK
       LABEL foreach VAR (LIST) BLOCK continue BLOCK
       LABEL BLOCK continue BLOCK

如果这不能用正则表达式完成,是否有状态机能够这样做?

4

2 回答 2

9

不要尝试自己解析 perl。如果您确实需要,请使用PPI,它做得不错。

use PPI;
my $source = 'LABEL: { print "block" } continue { print "cont block" }';
my $doc = PPI::Document->new(\$source);
my $blocks = $doc->find("PPI::Structure::Block");
print ":$_:\n" for @$blocks;
于 2012-11-26T01:22:14.420 回答
2

这根本做不到。一般来说,如果你想解析任意 Perl 代码,你也需要能够执行 Perl,因为useBEGIN在解析时运行并且会影响其余代码的解析方式。

例子:

use Some::Module;
foo / 1;
is_this_code();
#/;

如何解析这取决于如何foo声明。如果它是一个普通函数,则使用 regex 的结果调用它/ 1;\nis_this_code();\n#/。如果用 的原型声明(),代码会将 的返回值foo除以 1,然后调用is_this_code()

于 2012-11-26T01:24:08.760 回答