Perl:将函数调用转换为lisp样式函数调用

时间:2013-01-05 16:56:44

标签: perl

我正在尝试将行a, f_1(b, c, f_2(d, e))转换为带有lisp样式函数调用的行  a (f_1 b c (f_2 d e))使用Text::Balanced子例程:

函数调用的形式为f(arglist),arglist也可以在其中包含一个或多个函数调用,也可以使用层次调用;

我尝试的方式 -

my $text = q|a, f_1(a, b, f_2(c, d))|;

my ($match, $remainder) = extract_bracketed($text); # defaults to '()' 
# $match is not containing the text i want which is : a, b, f_2(c,d) because "(" is preceded by a string;

my ($d_match, $d_remainder) = extract_delimited($remainder,",");
# $d_match doesnt contain the the first string
# planning to use remainder texts from the bracketed and delimited operations in a loop to translate.

尝试使用开始标记的子extract_tagged为/^[\w_0-9]+\(/,结束标记为/\)/,但也不在那里工作。 Parse::RecDescent很难理解并在短时间内投入使用。

1 个答案:

答案 0 :(得分:1)

转换为LISP样式似乎所需的一切就是删除逗号并将每个左括号移到它前面的函数名之前。

此程序通过将字符串标记为标识符/\w+/或括号/[()]/并将列表存储在数组@tokens中来工作。然后扫描该阵列,并且只要标识符后跟一个左括号,就会切换两个。

use strict;
use warnings;

my $str = 'a, f_1(b, c, f_2(d, e))';

my @tokens = $str =~ /\w+|[()]/g;

for my $i (0 .. $#tokens-1) {
  @tokens[$i,$i+1] = @tokens[$i+1,$i] if "@tokens[$i,$i+1]" =~ /\w \(/;
}

print "@tokens\n";

<强>输出

a ( f_1 b c ( f_2 d e ) )