Karl Gaissmaier wrote: ....some suggestions for additional features of Parse::RecDescent, specifically the ability to specify "required alternatives" within a repeated subrule:
> statement: A! | B! | C | D and "mutually exclusive alternations": > rule : A ^ B ^ C The problem with these proposed features is that they are not *localized*. That is, the presence of an A! doesn't affect the rule that the A! is in, it affects the rule that calls the rule that the A! is in. And that is difficult to implement in a recursive descent parser. > But I think that P::RD is by far no way just a CFG ParserGenerator, it's a beast. <grin> I should quote you in the documentation. ;-) > I stumbled so many times over these two missing features (mandatory and xor) > and my "feeling" tells me, there must be a gentler(general) solution > than just doing this in action codes. Clearly this has been a problem for you. But I would have solved it like so: $grammar = << 'EOGRAMMAR'; contact : statement(s) { $return = { map %$_ @{$item[-1]} } } <reject: do{!($return->{email} && $return->{name})) > statement : email | name | phone | fax email : 'email' '=' value {{email=>$item[-1]}} name : 'name' '=' value {{name=>$item[-1]}} phone : 'phone' '=' value {{phone=>$item[-1]}} fax : 'fax' '=' value {{fax=>$item[-1]}} value : /".*?"/ EOGRAMMAR Since you needed to collect the data anyway, the actions would have had to be there no matter what. So the overhead for the requirements testing is just the single <reject> directive. Likewise, if (for example) phone and fax were mutually exclusive, you could just extend that to: $grammar = << 'EOGRAMMAR'; contact : statement(s) { $return = { map %$_ @{$item[-1]} } } <reject: do{!($return->{email} && $return->{name})} > <reject: do{ $return->{phone} && $return->{fax} } > statement : email | name | phone | fax email : 'email' '=' value {{email=>$item[-1]}} name : 'name' '=' value {{name=>$item[-1]}} phone : 'phone' '=' value {{phone=>$item[-1]}} fax : 'fax' '=' value {{fax=>$item[-1]}} value : /".*?"/ EOGRAMMAR > Perhaps Damian can bring some light in the darkness. Perhaps. But I doubt it. ;-) However, since you've taken the trouble to mention (and obviously think about) this problem, I will certainly devote some time to it myself and see if I can develop a better solution; one that's consistent with a recursive descent implementation. Damian