use strict; use warnings; use Data::Dumper (); use Parse::RecDescent (); { my $grammar = <<'__EOI__'; { use strict; use warnings; } # --- Tokens --- EOF : /^\Z/ IDENTIFIER : /[A-Za-z]\w*/ LITERAL : /\d+/ REL_OP : />=?|<=?|==/ EQUAL : '=' # --- Keywords --- IF_KEYWORD : IDENTIFIER { $item[1] eq 'if' ? $item[1] : undef } # --- Rules --- parse : stmt(s?) EOF { $item[1] } stmt : IF_KEYWORD if_rest { [ $item[1], @{$item[3]} ] } | label { $item[1] } | assign ';' { $item[1] } | call ';' { $item[1] } | if_rest : '(' compare ')' '{' stmt(s?) '}' { [ @item[2, 5] ] } label : IDENTIFIER ':' { [ @item[0, 1] ] } assign : IDENTIFIER EQUAL term { [ @item[2, 1, 3] ] } call : IDENTIFIER { [ @item[0, 1] ] } compare : term REL_OP term { [ @item[2, 1, 3] ] } term : IDENTIFIER { [ 'identifier', $item[1] ] } | LITERAL { [ 'literal', $item[1] ] } __EOI__ $::RD_HINT = 1; # $::RD_TRACE = 1; # Parse::RecDescent::Hack->Precompile($grammar, "Module"); my $parser = Parse::RecDescent->new($grammar); die("Bad grammar.\n") unless defined($parser); my $text = <<'__EOI__'; test: a=4;b =5 ; c = 9; if (b > a) { c = 100; } Camel: Camel = 5; hippo: ilovetoswim; ifthen1: if ( ABC > 500 ){XYZ = 10;} ifthen2: if ( ABC < 500 ){sdfsdf;} ifthen4: if ( ABC == 500 ){sdfsdf;} ifthen7: if ( ABC <= 500 ){sdfsdf;} ifthen8: if ( ABC >= 500 ){sdfsdf;} __EOI__ my $result = $parser->parse(\$text); die("Bad text.\n") unless (defined($result)); print("Parse Tree\n"); print("==========\n"); print Data::Dumper::Dumper($result); }