0

我正在尝试使用子例程将一行转换为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.

甚至尝试了 sub extract_tagged with start tag as/^[\w_0-9]+\(/和 end tag as /\)/,但在那里也不起作用。 Parse::RecDescent很难在短时间内理解和使用。

4

1 回答 1

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 ) )
于 2013-01-05T19:48:59.000 回答