#!perl -w use strict; use Parse::RecDescent; $::RD_AUTOACTION = q { [@item[0..$#item]] }; my $grammar = q{ Document : Element(s) Element : Header Body Header : Element_Type Options(?) Element_Type: 'Q::' | 'T::' Options : '(' Arg(s) ')' Arg : /\b(\w+)\s*=\s*(\w+)\s*/xms Open_body : '{' Close_body : '}' Body : Open_body Line(s) Close_body Line : Element | Text | Text Line Text : /[\s\w]*[^\}]/xms }; my $survey_parser = Parse::RecDescent->new($grammar); undef $/; my $doc = ; my $tree = $survey_parser->Document($doc); die "no trees" if ! $tree; use Data::Dumper; print Dumper($tree); __DATA__ Q:: (arg1=val arg2=val) { Some text here T:: (arg=value) { Text here } Q:: (argn=etc) { T:: { optional args not included } } }