0

我喜欢从单词 'module' 到单词 'endmodule' 中捕获文本。verilog 文件可能包含多个模块,所以我喜欢指出一个特定的模块。

我也想忽略任何评论块中的任何“endmodule”字。

Verilog 文件示例:

module whatever
//endmodule
// endmodule
// asadsadadsa endmodule
// enasaa endmodule asas
/* endmodule */
endmodule // whatever
module nonsense
//
// bla bla
//
endmodule // nonsense

假设我想从上面捕获模块。我正在使用 Perl 单行模式。

到目前为止,我到了这一点:

if ($content =~ m/(module\s+whatever[\s(#]?.*?endmodule(?:\s*\/\/\s*whatever)?)/s)
{
    print $1;
}
else
{
    print "NOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!!!!!!!!!!\n";
}

到目前为止,这与“ //endmodule ”的第一次出现匹配

任何帮助或提示将不胜感激。

4

2 回答 2

3

这个有点棘手。这个想法通常是区分你想要匹配的所有可能的东西,将它们交替放置并重复。

那么我们要匹配什么?

  • 单行注释://到字符串的末尾,无论如何。
  • 一个块评论:/*直到下一个*/,无论如何。
  • 别的什么,只要它不开始endmodule

最后一部分可以通过在重复中的每个位置使用负前瞻来完成。

所以让我们把它放在一起:

$content =~ m~
  module\s+whatever      # marks the start of the module
  (?:                    # each instance of this alternation matches one kind of
                         # module "token"
    //.*+                # match a single-line comment
  |                      # or
    /[*]                 # open a block comment
    (?:(?![*]/)[\s\S])*+ # match anything as long as it doesn't close the comment
    [*]/                 # close the block comment
  |                      # or
    (?!endmodule)[\s\S]  # match anything as long as it doesn't close the module
  )*+                    # repeat
  endmodule
  ~x

诀窍是前两个选项会跳过评论,因此您只关注评论endmodule之外的内容。

是所有格量词*+。它们(在大多数情况下)是一种优化,但是在 the 之后的和在交替周围的是绝对必要的(否则回溯可能会给您带来误报)。//

工作演示。

但是,由于您正在处理标准化的文件格式,您最好寻找这种文件的解析器。

于 2013-06-29T00:23:09.630 回答
1

不要将整个文件放入一个正则表达式中,而是一次读取一行。

#!/usr/bin/perl
use strict;
my ($file,$module) = qw(verilog.v whatever);

open(VERILOG_FILE, $file) or die "cannot read $!";
my $start=0;
my $store = "";
foreach my $line (<VERILOG_FILE>) {
    die "nested module inside module:'${module}'" if $start && $line =~ m/^\s*module\W/;
    $start|= $line =~ m/^\s*module ${module}\W/;
    $store.=$line if $start;
    if ($start and $line =~ m/^\s*endmodule/) {
        print $store;
        exit 0;
    }
}
die "cannot file module '$module' in file '$file'" if ($start==0);
die "missing endmodule for '$module'"

使用问题中给定的 Verilog 文件示例并假设名称为 verilog.v,则输出将是:

module whatever
//endmodule
// endmodule
// asadsadadsa endmodule
// enasaa endmodule asas
/* endmodule */
endmodule // whatever
于 2013-06-29T01:28:17.503 回答