CAR(agg)=( ID(str)='12345' TITLE(agg)=( TITLE(text 5)='Prius' ) RATING(text 4)='Good' CAT(agg)=( LABEL(text 6)='Hybrid' REL(int)=8 ) CAT(agg)=( LABEL(text 6)='Family' REL(int)=10 ) ) CAR(agg)=( ID(str)='22222' TITLE(agg)=( TITLE(text 7)='Voyager' ) RATING(text 3)='Bad' CAT(agg)=( LABEL(text 6)='Family' REL(int)=10 ) CAT(agg)=( LABEL(text 3)='Van' REL(int)=9 ) ) #### #!/usr/bin/perl use Parse::RecDescent; $grammar = q{ startrule: root(s) root: object { print "root\n"; } object: name "(agg)=(" body(s?) closeobject { print "object <$item{name}>\n"; } name: /\w+/ body: /\s+/ | object | property { print "property $item{property}\n"; } property: name /\(\w+\s*\d*\)=/ value { "<$item{name}>$item{value}" } value: value1 | value2 value1: /\w+/ value2: /'.+'/ { substr $item[1], 1, (length $item[1]) - 2 } closeobject: ")" { print "close\n"; } }; $parser = Parse::RecDescent->new($grammar); undef $/; $text = <>; print "\n"; $parser->startrule($text); print "\n"; #### 12345 Prius Good 8 10 22222 Voyager Bad 10 9