> I've an alternation where some subrules are mandatory but others are > optional (Subrule statement).
This doesnt make much sense to me. An alternation is a rule that can be matched by any _one_ of a selection of rules. So that means you can't say that some of those alternations are _mandatory_ because that would mean you are implying that more than one of the options must be matched, and since that is impossible you have a problem... :-) > $grammar = << 'EOGRAMMAR'; > contact : statement(s) > statement : email | name | phone | fax > email : 'email' '=' value # mandatory > name : 'name' '=' value # mandatory > phone : 'phone' '=' value # optional > fax : 'fax' '=' value # optional > value : /".*?"/ > EOGRAMMAR > > for example email and name will be required and phone or fax are optional. > In the moment I have to deal with action code working with sets. That means > I have an additional layer of grammar in the action code. Hmm, if you mean the "additional layer of grammer" is the logic that ensures that contact is not sucessful unless it contains both an email and a name then I can see what you mean but you have to realize that you _can_ do this with a normal context-free-grammer, but you probably dont want to. contact : email name fax(?) phone(?) | email name phone(?) fax(?) | email phone(?) name fax(?) | phone(?) email name fax(?) | email fax(?) name phone(?) | email fax(?) phone(?) name | email phone(?) fax(?) name | phone(?) email fax(?) name | fax(?) email name phone(?) | fax(?) email phone(?) name | fax(?) phone(?) email name | phone(?) fax(?) email name | name email fax(?) phone(?) | name email phone(?) fax(?) | name phone(?) email fax(?) | phone(?) name email fax(?) | name fax(?) email phone(?) | name fax(?) phone(?) email | name phone(?) fax(?) email | phone(?) name fax(?) email | fax(?) name email phone(?) | fax(?) name phone(?) email | fax(?) phone(?) name email | phone(?) fax(?) name email Since its a permutation (Algorithym::FastPermute rocks!) this probably isnt the optimal way to proceed. To me the core issue that you face is that the general case of what you want is not possible using a context-free grammar without explicitly listing every possible permutation. So since its context sensitive behaviour you want, and no parser can handle such behaviour directly you need to consider that what you want to do should _not_ be part of the grammar anyway. (Consider that this is a relatively common state of affairs. Its not possible for instance using a context-free-grammar to ensure that variables are declared before they are used.) What I would do is create a small utility function that can handle your needs. Anyway heres what I did to your example... use Parse::RecDescent; #use diagnostics; $::RD_AUTOACTION = q { $item[1] }; # this allows check_mandatory to be simplified.... $grammar = << 'EOGRAMMAR'; { sub check_mandatory { my ($mand_array,$item_array)=@_; # make sure we dont overwrite any keys my %counts; # Transform list of mandatory items into hash my %mand=map {($_=>1)} @$mand_array; # We will convert the LOL that we recieve into a hash my %ret; foreach my $elem (@$item_array) { my $name=$elem->[0]; delete $mand{$name} if $mand{$name}; if ($counts{$name}) { $name.=$counts{$name}; } $counts{$name}++; $ret{ $name }=$elem->[1]; } return !(scalar keys %mand) ? \%ret : undef; } } contact : statement(s) { $return=check_mandatory([ 'email','name' ],$item{statement}); $return } statement : mandatory | optional mandatory : email | name optional : phone | fax email : 'email' '=' value { [$item[0],$item{value}]}# mandatory name : 'name' '=' value { [$item[0],$item{value}]}# mandatory phone : 'phone' '=' value { [$item[0],$item{value}]}# optional fax : 'fax' '=' value { [$item[0],$item{value}]}# optional value : /"[^"]*"/ EOGRAMMAR $parser = new Parse::RecDescent ($grammar) or die "Bad grammar!\n";# acquire $text my $ret=$parser->contact(<<'EOTEST') or print "Bad text!\n"; email = "[EMAIL PROTECTED]" name = "Joe Camel" phone = "(555)-555-5555" fax = "(555)-555-1111" EOTEST use Data::Dumper; print Dumper $ret;