# Shorten the grammar by lifting modification # # Test case: # # A:OB -> B:OB C:OB D:OB # A:OB -> E:OP F:OB G:OB # A:OB -> H:OP I:OB J:OP # # becomes # # A:OB -> B:OB C:OB D:OB # A:OB -> F:OB G:OB # A:OB => A:OB E:OP # A:OB -> I:OB # A:OB => A:OB H:OP # A:OB => A:OB J:OP # # where OP is optional and OB is obligatory # # (the => arrow insulates a rule from order generalization) while (<>) { @oplist = (); @oblist = (); ($lhs, $rhs) = m/(.*) -> (.*)/; @rhslist = split(" ", $rhs); foreach $item (@rhslist) { if ($item =~ m/:AMS|:APP|:CC|:DM|:GR|:MNR|:MO|:NG|:PG|:RC|:SBP|:VO|AA:NK|AP:NK|AVP:NK|CAP:NK|CAVP:NK|MTA:NK|CPP:NK|PP:NK/) { push @oplist, $item; } else { push @oblist, $item; } } $newrhs = join " ", @oblist; print "$lhs -> $newrhs\n"; foreach $item (@oplist) { print "$lhs => $item $lhs\n"; } }