我正在编写一个简单的Perl脚本,它将汇编指令字符串转换为32位二进制代码。
我决定按类型处理翻译分组指令(ADD
和SUB
是R-Type指令等等......)所以在我的代码中我做的是这样的:
my $bin = &r_type($instruction) if $instruction =~ /^(?:add|s(?:ub|lt|gt))\s/;
因为我想以同样的方式处理add
,sub
,slt
和sgt
。
然而我意识到,使用那个正则表达式可能对我应该做的任务来说是“过度杀伤”......可能是模式
/^(?:add|sub|slt|sgt)\s/
表示在这种情况下更好地使用正则表达式?
非常感谢。
答案 0 :(得分:22)
除非您使用的是早于5.10的perl,否则简单的更改无论如何都会表现得更好(请参阅here),因此没有理由尝试对其进行优化。
答案 1 :(得分:5)
不是将助记符放在正则表达式中,而是使用哈希构建调度表。它将至少同样更快,您的代码更容易遵循:
my %emitter = (add => \&r_type,
sub => \&r_type,
slt => \&r_type,
sgt => \&r_type,
...);
if ($instruction =~ /^(\S+)/) {
my $emitter = $emitter{$1} // die "bad instruction $instruction";
$emitter->($1, $istruction);
}
else {
# error?...
}
答案 2 :(得分:5)
我喜欢salva's dispatch table(我在掌握Perl 中展示了很多内容),但如果您有一天需要针对不同问题的答案,我会回答问题的另一个方面
如果你想构建一些替换,其中一些可能是嵌套的,你可以使用类似Regexp::Trie的东西为你构建替换,这样你就不会看到丑陋的正则表达式语法:
use Regexp::Trie;
my $rt = Regexp::Trie->new;
foreach ( qw/add sub slt sgt/ ) {
$rt->add($_);
}
print $rt->regexp, "\n";
这会给你:
(?-xism:(?:add|s(?:gt|lt|ub)))
通过这种方式,您可以列出Jonathan建议的操作码,但也可以进行更改。正如你所指出的,无论如何你现在可以免费使用Perl。
答案 3 :(得分:4)
您的第二个版本更简单,更易读,更易于维护。性能差异将取决于正则表达式的实现,但我怀疑嵌套版本由于其复杂性增加而运行速度较慢。
是的,这太过分了。