尝试理解perl脚本背后的C代码。例如,以下设计代码:
$name = "john";
$greeting = "hi $name, how old are you?";
if ($greeting =~ /hi (\S+)/) {
$b = $1;
print "got $b as expected\n";
}
想知道如何在$ greeting字符串中替换变量$ name,也想知道用于正则表达式匹配的c API。
我听说像perl -MO=Bytecode,-H test.pl
这样的地方,其中test.pl具有上述内容,但输出是bindary。
答案 0 :(得分:2)
没有将Perl代码直接映射到C代码。相反,Perl是一个字节码编译器。你能得到的是字节码,操作码树。有几个模块可以用人类可读的形式来实现,一个是B::Concise。
perl -MO=Concise test.pl
制作此...
w <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 test.plx:1) v:{ ->3
5 <2> sassign vKS/2 ->6
3 <$> const[PV "john"] s ->4
- <1> ex-rv2sv sKRM*/1 ->5
4 <#> gvsv[*name] s ->5
6 <;> nextstate(main 1 test.plx:2) v:{ ->7
d <2> sassign vKS/2 ->e
- <1> ex-stringify sK/1 ->c
- <0> ex-pushmark s ->7
b <2> concat[t5] sKS/2 ->c
9 <2> concat[t4] sK/2 ->a
7 <$> const[PV "hi "] s ->8
- <1> ex-rv2sv sK/1 ->9
8 <#> gvsv[*name] s ->9
a <$> const[PV ", how old are you?"] s ->b
- <1> ex-rv2sv sKRM*/1 ->d
c <#> gvsv[*greeting] s ->d
B :: Concise的文档解释了所有这些。这将告诉您操作符序列,类型,名称,标志以及序列中的下一个操作。例如......
7 <$> const[PV "hi "] s ->8
这是运算符7,它是一个SVOP(它适用于标量),它的名称是“const”,它是标量字符串(PV)“hi”,它在标量上下文中,下一个运算符是8。
可以从perlguts和Illustrated Perl Guts以及poking around in the Perl source code了解有关运营商的更多信息。每个运算符都有一个与之关联的C函数pp_OPNAME
,因此找到{const}运算符查找pp_const
。
Perl正则表达式引擎是完全自定义的,并且有自己的perlreguts文档。