Reputation: 29
I am trying to convert a line a, f_1(b, c, f_2(d, e))
to a line with lisp style function call
a (f_1 b c (f_2 d e))
using Text::Balanced
subroutines:
A function call is in the form f(arglist)
, arglist can have one or many function calls within it with heirarchical calls too;
The way i tried -
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.
Tried even the sub extract_tagged with start tag as /^[\w_0-9]+\(/
and end tag as /\)/
, but doesn't work there too.
Parse::RecDescent
is difficult to understand and put to use in a short time.
Upvotes: 1
Views: 123
Reputation: 126722
All that seems to be necessary to transform to the LISP style is to remove the commas and move each opening parenthesis to before the function names that precedes it.
This program works by tokenizing the string into identifiers /\w+/
or parentheses /[()]/
and storing the list in array @tokens
. This array is then scanned, and wherever an identifier is followed by an opening parenthesis the two are switched over.
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";
output
a ( f_1 b c ( f_2 d e ) )
Upvotes: 1