my $p = Parse::RecDescent->new( <<'END_GRAMMAR' ); parse: item(s) { "" . join("", @{$item[1]}) . "" } item: /\w+/ /\([^\)]+\)=/ data { "<$item[1]>$item[3]" } data: aggregate | string | integer aggregate: "(" item(s) ")" { join "", @{$item[2]} } string: /'([^']*)'/ { $1 } integer: /\d+/ { $item[1] } END_GRAMMAR undef $/; print $p->parse();