代码之家  ›  专栏  ›  技术社区  ›  jpalecek

如何从Perl中的coderef获取语法树?

  •  2
  • jpalecek  · 技术社区  · 15 年前

    B::Concise ,只是B::concertive在输出时打印代码,但我想以编程方式检查它。

    我想这样用。给定一个coderef F

    $ret = &$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10);
    

    我想创建一个函数 F1 ,圣。

    &$F(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) == 
      &$F1(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)*
      &$C(x2, x3, x4, x5, x6, x7, x8, x9, x10)
    

    也就是说把它分成两部分,第二部分不依赖于 x1 第一个是尽可能简单的(我想

    我想要的应用程序是 Metropolis sampling algorithm p(x1 | x2 = X1, x3 = X3, ...) = f(x1, x2, x3, ...) . 算法本身是不变的。乘法常数因子和其他变量不会通过算法改变,所以部分不依赖于 x1个 (即。 $c

    联合概率可能有如下形式:

      p(x1, x2, x3, x4, x5) = g1(x1, x2)*g2(x2, x3)*g3(x3, x4)*g4(x4, x5)*g5(x4, x1)*g6(x5, x1)
    

    我也考虑建造 p

    3 回复  |  直到 15 年前
        1
  •  9
  •   rafl    15 年前

    对于optrees的内省 B

    给定代码引用 $cv ,首先创建

    my $b_cv = B::svref_2object($cv);
    

    现在您可以调用 B 从操作树中检索各种东西。

    DBIx::Perlish 一个非常先进的例子。

    碰巧还有一个 B::Generate 模块,它允许构建新的操作树,以执行您想要的任何操作,或操作现有的操作树。然而, B: :生成 并不像人们希望的那样成熟,还有很多功能缺失和一些bug。

    实际的操作树创建和操作通常最好使用perl的C api完成,如 perlapi perlguts perlhack XS 同样,为了公开您写回perl空间的操作树操作函数,这确实是最简单的部分。

    构建optrees(不一定基于正在进行内省的其他现有optrees)最近似乎变得有些流行,特别是在 Syntax Plugins Scope::Escape::Sugar 关于cpan。

    B::Deparse->new->coderef2text($cv)

    你可能想退一步,解释一下你要解决的实际问题。也许有一个简单得多的解决方案,根本不涉及操作树。

        2
  •  1
  •   hobbs    15 年前

    考虑到你重申的问题——我认为你应该在这里做的,而不是试图咀嚼代码参考,是尽可能拖延拥有代码参考。

    1. 创建表示计算实例的对象。
    2. 在此对象上编写计算值所需的方法。没有编码,只要慢一点就行了。这只是为了给你一个下一步的代码基线,这些代码很容易被测试,并且希望很容易被理解。
    3. 通过编写方法将计算对象转换为表示相同计算的更优化形式的新对象,实现您在本问题中提出的问题。使用您的测试确保优化后计算仍能给出正确的结果。
    4. 编写接受计算对象的代码,并生成子对象(无论是否按字符串 eval B )进行计算。使用您的测试确保计算在编译后仍能给出正确的结果。

    插入2到5之间任意位置的可选步骤:

    • 写一些语法糖(可能用 overload ,但也可以使用其他工具)让您使用与计算本身相似的漂亮表达式来构造“计算对象”,而不是大量的对象构造函数。
        3
  •  0
  •   Chas. Owens    15 年前

    Perl5不允许您像那样动态地操作字节码,但是您可以创建匿名函数。如果我正确地理解了您的示例,并且我怀疑我理解了,那么您已经有两个被引用的函数 $f1 $c $f 它将前两个结果相乘。这很简单:

    my $f = sub { $f1->(@_) * $c->(@_[1 .. 9]) };
    
    $f->(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    

    & 取消引用代码引用。这种风格更为常见(在我看来更具可读性)。