user1931598
user1931598

Reputation: 29

Perl : Convert a function call to a lisp style function call

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

Answers (1)

Borodin
Borodin

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

Related Questions