Index: src/dgc/Makefile
===================================================================
--- src/dgc/Makefile	(revision e7de6cc88c605c4f810cbc852e843294b4b0e8ac)
+++ src/dgc/Makefile	(revision 3b02b04ff9c7c3446ca477cd84c2bc7f737c38b4)
@@ -7,4 +7,5 @@
 ifdef BIN_DIR
 	install -m 0755 dgc $(BIN_DIR)
+	install -m 0755 l2src $(BIN_DIR)
 endif
 
@@ -13,4 +14,5 @@
 ifdef BIN_DIR
 	rm $(BIN_DIR)/dgc
+	rm $(BIN_DIR)/l2src
 endif
 
Index: src/dgc/dgc
===================================================================
--- src/dgc/dgc	(revision e7de6cc88c605c4f810cbc852e843294b4b0e8ac)
+++ src/dgc/dgc	(revision 3b02b04ff9c7c3446ca477cd84c2bc7f737c38b4)
@@ -9,12 +9,16 @@
 use lib "$ENV{'HOME'}/.local/lib/utt";
 
-use strict;
+#use strict;
 use Getopt::Long;
 use Data::Dumper;
 use attr;
 use File::HomeDir;
+use Parse::RecDescent;
+
+$::RD_HINT=1;
+# use List::MoreUtils;
 
 my $systemconfigfile='/etc/utt/dgc.conf';
-my $userconfigfile=home()."/.utt/dgc.conf";
+my $userconfigfile=0; #home()."/.utt/dgc.conf";
 
 Getopt::Long::Configure('no_ignore_case_always');
@@ -31,25 +35,12 @@
   if(open(CONFIG, $file)){
         while (<CONFIG>) {
-                chomp;
-                s/#.*//;
-                s/^\s+//;
-                s/\s+$//;
+                chomp; s/#.*//; s/^\s+//; s/\s+$//;
                 next unless length;
                 my ($name, $value) = split(/\s*=\s*/, $_, 2);
-                if(($name eq "categories")or($name eq "c")){
-                        $catfile=$value;
-                }
-                elsif(($name eq "dictionary")or($name eq "d")){
-                        $dicfile=$value;
-                }
-                elsif(($name eq "grammar")or($name eq "g")){
-                        $gramfile=$value;
-                }
-                elsif(($name eq "outputfile")or($name eq "o")){
-                        $outputfile=$value;
-                }
-                elsif(($name eq "help")or($name eq "h")){
-                        $help=1;
-                }
+                if(($name eq "categories")or($name eq "c"))      { $catfile=$value; }
+                elsif(($name eq "dictionary")or($name eq "d"))   { $dicfile=$value; }
+                elsif(($name eq "grammar")or($name eq "g"))      { $gramfile=$value; }
+                elsif(($name eq "outputfile")or($name eq "o"))   { $outputfile=$value; }
+                elsif(($name eq "help")or($name eq "h"))         { $help=1; }
 
         }
@@ -90,39 +81,118 @@
 die("At least one of --cats and --dic must be given.\n") if !$catfile && !$dicfile;
 
-my $ncat=0;
-my $nrole=0;
-my $nsgl=0;
-my $nleft=0;
-my $nright=0;
-my $ninitr=0;
-my $nfinr=0;
-my $ninitf=0;
-my $nfinf=0;
-my $ninitc=0;
-my $nfinc=0;
-my $nreq=0;
-my $nlink=0;
-my $nflag=0;
-my $nset=0;
-my $npass=0;
-my $nlong=0;
-my $nconstr=0;
-my $nclass=0;
-
-my %cats;
-my %roles;
-my %agr;
-my %gov;
-
-if(!$outputfile) {
-	*OUTPUT = *STDOUT;
-}
-elsif($outputfile eq "-") {
-    *OUTPUT = *STDOUT;
-}
-else {
-	open(OUTPUT, ">$outputfile") or die("Can't open output file: $outputfile!");
-}
-
+
+our %in;      #gramatyka wej¶ciowa
+our %idx;     #indeks gramatyki wej¶ciowej (niektóre stwierdzenia)
+our %out;     #gramatyka wyj¶ciowa
+our %class;   #tablica klas
+
+our $attr_re       = $attr::attr_re;
+our $cat_re        = $attr::cat_re;
+our $cats_re       = qr/(?:$attr::cat_re\s*(?:,\s*$attr::cat_re)*)/;
+our $class_re      = qr/(?:\@\w+)/;
+our $av_re         = $attr::av_re;
+our $avlist_re     = $attr::avlist_re;
+our $role_re       = qr/(?:[[:lower:][:digit:]_]+)/;
+our $prop_re       = qr/(?:[[:upper:]]+)/;
+our $proplist_re   = qr/(?:(?:\&$prop_re)+)/;
+
+my $inputlineno=0;
+
+our $statementgrammar = q(
+
+statement : statement1 ";" { $item[1] }
+
+statement1: /cat/i     acat              { ['cat',     { cat=>$item{acat}, catexp=>attr::parse($item{acat}) },       $item{acat}] }
+          | /flag/i    flag              { ['flag',    { flag=>$item{flag} },                                        $item{flag}] }
+          | /role/i    role              { ['role',    { role=>$item{role} },                                        $item{role}] }
+          | /left/i    role              { ['left',    { role=>$item{role} },                                                  0] }
+          | /right/i   role              { ['right',   { role=>$item{role} },                                                  0] }
+          | /sgl/i     role              { ['sgl',     { role=>$item{role} },                                                  0] }
+          | /req/i     xcat role         { ['req',     { cats=>$item{xcat}, role=>$item{role} },                               0] }
+          | /agr/i     role attr         { ['agr',     { role=>$item{role}, attr=>$item{attr} },                     $item{role}] }
+          | /gov/i     role xcat         { ['gov',     { role=>$item{role}, cats=>$item{xcat} },                     $item{role}] }
+          | /init/i    flagconstr        { ['initf',   { flag=>$item{flagconstr} },                                            0] }
+          | /fin/i     flagconstr        { ['finf',    { flag=>$item{flagconstr} },                                            0] }
+          | /init/i    role              { ['initr',   { role=>$item{role} },                                                  0] }
+          | /fin/i     role              { ['finr',    { role=>$item{role} },                                                  0] }
+          | /set/i     xcat flag         { ['set',     { cats=>$item{xcat}, flag=>$item{flag} },                               0] }
+          | /pass/i    role flag         { ['pass',    { role=>$item{role}, flag=>$item{flag} },                               0] }
+          | /constre/i role role         { ['constre', { role1=>$item[2], role2=>$item[3] },                                   0] }
+          | /constri/i role role         { ['constri', { role1=>$item[2], role2=>$item[3] },                                   0] }
+
+          | /link/i    xcat optflags(?) xcat optflags(?) role prop(s?)
+                                         { ['link', { hcats=>$item[2], hflagconstr=>$item[3], 
+                                                      dcats=>$item[4], dflagconstr=>$item[5],
+                                                      role=>$item[6], props=>$item[7] },                                       0] }
+
+          | /long/i role role(s? /,/) '^' role(s? /,/)
+                                         { ['long', { rel=>$item[2], up=>$item[3], down=>$item[5] },                           0] }
+
+          | /class/i classname '=' xcat  { ['class', { name=>$item{classname}, cats=>$item{xcat} },             $item{classname}] }
+
+acat:       /$attr::cat_re/
+
+attr:       /$attr::attr_re/
+
+xcat:       classexpr
+
+role:       /\w+/
+
+flag:       /\w+/
+
+optflags:   "//" flagconstr { $item[2] }
+
+flagconstr: /\w+[+-]/
+
+prop:       '&' /\w+/ { $item[2] }
+
+classname:  /\$\w+[+-]/
+
+classexpr  : classexpr1 '|' classexpr   { main::union($item[1],$item[3]) }
+           | classexpr1 '~' classexpr   { main::intersection( $item[1], main::complement($item[3]) ) }
+           | classexpr1
+
+classexpr1 : classexpr2 '&' classexpr1  { main::intersection($item[1],$item[3]) }
+           | classexpr2
+
+classexpr2 : '~' classexpr2            { main::complement($item[2]) }
+           | classexpr3
+
+classexpr3 : classexpr4 '/' /$attr::avlist_re/  { main::intersection($item[1], [main::extension('*/' . $item[3])] ) }
+           | classexpr4
+
+classexpr4 : class
+           | cat
+           | '(' classexpr ')'          { $item[2] }
+
+class :    classname                    { $main::class{$item[1]} or @{[]} }
+
+cat :      /$main::cat_re/              { [main::extension($item[1])] }
+
+);
+
+our $statementparser = Parse::RecDescent->new($statementgrammar);
+
+sub register
+{
+    my ($src, $statement, $data, $index) = @_ ;
+    $data->{line} = $inputlineno;
+    $data->{src} = $src;
+    push @{$in{$statement}}, $data;
+    push @{$idx{$statement}{$index}}, $data if($index);
+
+    if ($statement eq 'class') { $class{ $data->{name} } = $data->{cats} }
+}
+
+
+if(!$outputfile)          { *OUTPUT = *STDOUT; }
+elsif($outputfile eq "-") { *OUTPUT = *STDOUT; }
+else                      { open(OUTPUT, ">$outputfile") or die("Can't open output file: $outputfile!"); }
+
+if(!$gramfile)            { *INPUT = *STDIN; }
+elsif($gramfile eq "-")   { *INPUT = *STDIN; }
+else                      { open(INPUT, "cat $gramfile | m4 |") or die("Unable to open: $gramfile!"); }
+
+# *INPUT = *STDIN; ############### TYMCZASOWO
 
 loadcats($catfile) if $catfile;
@@ -130,99 +200,306 @@
 
 
-my $cats_re = qr/(?:$attr::cat_re\s*(?:,\s*$attr::cat_re)*)/;
-my $class_re = qr/(?:\@\w+)/;
-
-my $avlist_re = $attr::avlist_re;
-
-my $role_re     = qr/(?:[[:lower:][:digit:]_]+)/;
-my $prop_re     = qr/(?:\&[[:upper:]]+)/;
-my $proplist_re = qr/(?:$prop_re+)/;
-
-# class parse_class:
-# /$attr::cat_re/g;
-
-
-if(!$gramfile) { 
-	*INPUT = *STDIN;
-}
-elsif($gramfile eq "-"){
-    *INPUT = *STDIN;
-}
-else {
-	open(INPUT, $gramfile) or die("Unable to open: $gramfile!");
-}
+# CZYTANIE GRAMATYKI DGC
 
 while(<INPUT>)
 {
+    $inputlineno++;
     s/#.*//;
     s/^\s+//;
     s/\s+$//;
-    if(/^AGR\s+(\S+)\s+(\S+)$/)
+    s/\s+/ /g;
+    next unless $_;
+    my $result = $statementparser->statement("$_;");
+
+    # print "#input line $inputlineno\n";
+    # print Dumper($result);
+
+    if($result) { register($_, @{$result}) } else { print STDERR "ERROR at line $inputlineno\n" }
+}
+    
+
+# GENEROWANIE GRAMATYKI DGP
+
+my $inline = 0;
+my $outline = 0;
+
+
+# print Dumper($idx{gov}->{subj});
+
+
+for my $x (@{$in{cat}})    { print_outin("CAT $x->{cat}", $x); }
+
+for my $x (@{$in{flag}})   { print_outin("FLAG $x->{flag}", $x); }
+
+for my $x (@{$in{role}})   { print_outin("ROLE $x->{role}", $x); }
+
+for my $x (@{$in{long}})    { print_outin("LONG $x->{rel} " . join(",",@{$x->{up}}) . "^" . join(",",@{$x->{down}}), $x) }
+
+for my $x (@{$in{left}})   { print_outin("LEFT $x->{role}", $x)  if chk_role($x->{role}, $x) }
+
+for my $x (@{$in{right}})  { print_outin("RIGHT $x->{role}", $x) if chk_role($x->{role}, $x) }
+
+for my $x (@{$in{sgl}})    { print_outin("SGL $x->{role}", $x)   if chk_role($x->{role}, $x) }
+
+for my $x (@{$in{req}})
+{
+    if( chk_role($x->{role}, $x) )
     {
-	push @{$agr{$1}}, $2;
-    }
-    elsif(/^GOV\s+(\S+)\s+(\S+)$/)
-    {
-	push @{$gov{$1}}, attr::parse($2);
-    }
-    elsif(/^ROLE\s+\S+$/)
-    {
-	$roles{$_}=1;
-	print OUTPUT "$_\n";
-    }
-    elsif(/^SGL\s+\S+$/)
-    {
-	++$nsgl;
-	print OUTPUT "$_\n";
-    }
-    elsif(/^REQ\s+(\S+)\s+(\S+)$/)
-    {
-	print OUTPUT "#$_\n";
-	my $cat = attr::parse $1;
-	for my $atomcat (keys %cats)
+	for my $atomcat (map{$_->{cat}} @{$x->{cats}})
 	{
-	    if(attr::match @$cat, @{$cats{$atomcat}})
-	    {
-		print OUTPUT "REQ ".$atomcat." $2\n";
-		++$nreq;
-	    }
+	    print_outin("REQ $atomcat $x->{role}", $x);
 	}
     }
-    elsif(/^LEFT\s+\S+$/)
+}
+
+for my $x (@{$in{initr}}) { print_outin("INITR $x->{role}", $x)    if chk_role($x->{role}, $x) }
+
+for my $x (@{$in{finr}}) { print_outin("FINR $x->{role}", $x)      if chk_role($x->{role}, $x) }
+
+for my $x (@{$in{initf}}) { print_outin("INITF $x->{flag}", $x) } # SPRAWDZIÆ CZY FLAGA JEST ZADEKLAROWANA
+
+for my $x (@{$in{finf}}) { print_outin("FINF $x->{flag}", $x); } # SPRAWDZIÆ CZY FLAGA JEST ZADEKLAROWANA
+
+for my $x (@{$in{set}})
+{
+    for my $atomcat (map{$_->{cat}} @{$x->{cats}})
     {
-	++$nleft;
-	print OUTPUT "$_\n";
+	print_outin("SET $atomcat $x->{flag}", $x);
+    }	
+}
+
+for my $x (@{$in{pass}})    { print_outin("PASS $x->{role} $x->{flag}", $x); }
+
+for my $x (@{$in{constre}}) { print_outin("CONSTRE $x->{role1} $x->{role2}", $x) if chk_role($x->{role1}, $x) & chk_role($x->{role2}, $x) }
+
+for my $x (@{$in{constri}}) { print_outin("CONSTRI $x->{role1} $x->{role2}", $x) if chk_role($x->{role1}, $x) & chk_role($x->{role2}, $x) }
+
+for my $x (@{$in{link}})
+{
+    my @agrs = @{ $idx{agr}->{$x->{role} } or [] };
+    my @govs = @{ $idx{gov}->{$x->{role} } or [] };
+
+    my @deps = (@govs > 0) ? @{ intersection( $x->{dcats}, map { $_->{cats} } @govs ) } : @{ $x->{dcats} } ;
+
+    for my $head ( @{ $x->{hcats} } )
+    {
+      DEP:
+	for my $dep (@deps)
+	{
+	    for my $agr (@agrs)
+	    {
+		next DEP unless attr::agree(@{$head->{catexp}},@{$dep->{catexp}},$agr->{attr});
+	    }
+	    my $hflagconstr = @{$x->{hflagconstr}} ? "//@{$x->{hflagconstr}}" : "";
+	    my $dflagconstr = @{$x->{dflagconstr}} ? "//@{$x->{dflagconstr}}" : "";
+	    my $props = join(map { "\&$_" } $x->{props});
+	    print_outin("LINK $head->{cat}$hflagconstr $dep->{cat}$dflagconstr $x->{role}$props",$x, @agrs, @govs);
+	}
     }
-    elsif(/^RIGHT\s+\S+$/)
+}
+
+
+sub chk_role
+{
+    ($role, $statement_details) = @_;
+    if($idx{role}{$role}) { 1; } else { print_error("undefined role", $statement_details); 0; }
+}
+
+sub print_outin
+{
+    my ($out,@in) = (shift, @_);
+    print OUTPUT "$out\t\t#";
+    printf OUTPUT " %04d@\"%s\"", $_->{line}, $_->{src} foreach @in;
+    print OUTPUT "\n";
+}
+
+sub print_error
+{
+    my ($message,@in) = (shift,@_);
+    print STDERR "ERROR: $message in statement ";
+    printf STDERR " %04d@\"%s\"", $_->{line}, $_->{src} foreach @in;
+    print STDERR "\n";
+}
+
+
+sub extractcats
+{
+    my $file = shift;
+    open DICFILE, "$file";
+    while(<DICFILE>)
     {
-	++$nright;
-	print OUTPUT "$_\n";
+	while(/,([^[:space:];]+)/g)
+	{
+	    my $cat=$1;
+	    next if !$cat; # || exists $cats{$cat};
+#	    print OUTPUT "CAT $1\n";
+	    register('cat',     {src=>"CAT $cat", cat=>"$cat", catexp=>attr::parse($cat)},                 $cat);
+	}
     }
-    elsif(/^INIT\s+[[:lower:]]\S*$/)
+    close DICFILE;
+}
+
+
+sub loadcats
+{
+    my $file = shift;
+    open CATFILE, "$file";
+    while(<CATFILE>)
     {
-	++$ninitr;
-	s/INIT/INITR/;
-	print OUTPUT "$_\n";
+	tr/ \t\n//d;
+	next if !$_; # || exists $cats{$_};
+#	print OUTPUT "CAT $_\n";
+	register("CAT $_", 'cat',     {cat=>"$_", catexp=>attr::parse($_)},                 $_);
     }
-    elsif(/^FIN\s+[[:lower:]]\S*$/)
-    {
-	++$nfinr;
-	s/FIN/FINR/;
-	print OUTPUT "$_\n";
-    }
-    elsif(/^INIT\s+[[:upper:]]+[+-]$/)
-    {
-	++$ninitf;
-	s/INIT/INITF/;
-	s/[+-]//g;
-	print OUTPUT "$_\n";
-    }
-    elsif(/^FIN\s+[[:upper:]]+$/)
-    {
-	++$nfinf;
-	s/FIN/FINF/;
-	s/[+-]//g;
-	print OUTPUT "$_\n";
-    }
+    close CATFILE;
+}
+
+sub extension
+{
+    my $cat = shift;
+    my $catexp = attr::parse($cat);
+    grep { attr::match(@{$_->{catexp}},@{$catexp}) } @{$in{cat}};
+}
+
+sub uniq  { my %seen; grep { ! $seen{$_}++ } @_ }
+sub union { [ uniq( map { @{$_} } @_ ) ] }
+sub intersection { my $n=@_; my %seen; [ grep { ++$seen{$_} == $n } map { @{$_} } @_ ] }
+sub complement   { my %exclude;   for $c (@{shift()}) { $exclude{$c}++ };   [ grep { ! $exclude{$_} } @{$in{cat}} ] }
+
+# printf STDERR "%6d CAT   statements\n", 0+keys(%cats);
+# printf STDERR "%6d ROLE  statements\n", 0+keys(%role);
+# printf STDERR "%6d SGL   statements\n", @sgl+0;
+# printf STDERR "%6d REQ   statements\n", @req+0;
+# printf STDERR "%6d LEFT  statements\n", $nleft;
+# printf STDERR "%6d RIGHT statements\n", $nright;
+# printf STDERR "%6d INITR statements\n", $ninitr;
+# printf STDERR "%6d FINR  statements\n", $nfinr;
+# printf STDERR "%6d INITF statements\n", $ninitf;
+# printf STDERR "%6d FINF  statements\n", $nfinf;
+# printf STDERR "%6d INITC statements\n", $ninitc;
+# printf STDERR "%6d FINC  statements\n", $nfinc;
+# printf STDERR "%6d LINK  statements\n", $nlink;
+# printf STDERR "%6d CLASS statements\n", $nclass;
+# printf STDERR "%6d FLAG  statements\n", $nflag;
+# printf STDERR "%6d SET   statements\n", $nset;
+# printf STDERR "%6d PASS  statements\n", $npass;
+
+
+##################################################################################
+
+# while(<INPUT>)
+# {
+#     $inputlineno++;
+#     s/#.*//;
+#     s/^\s+//;
+#     s/\s+$//;
+#     s/\s+/ /g;
+#     if   (/^CAT ($cat_re)$/)         { register('cat',     {src=>$&, cat=>attr::parse($1)},                 $1); }
+#     elsif(/^FLAG (\S+)$/)            { register('flag',    {src=>$&, flag=>$1},                             $1); }
+#     elsif(/^ROLE (\S+)$/)            { register('role',    {src=>$&, role=>$1},                             $1); }
+#     elsif(/^LEFT (\S+)$/)            { register('left',    {src=>$&, role=>$1},                              0); }
+#     elsif(/^RIGHT (\S+)$/)           { register('right',   {src=>$&, role=>$1},                              0); }
+#     elsif(/^SGL (\S+)$/)             { register('sgl',     {src=>$&, role=>$1},                              0); }
+#     elsif(/^REQ (\S+) (\S+)$/)       { register('req',     {src=>$&, cat=>$1, role=>$2},                     0); }
+#     elsif(/^AGR (\S+) (\S+)$/)       { register('agr',     {src=>$&, role=>$1, attr=>$2},                   $1); }
+#     elsif(/^GOV (\S+) (\S+)$/)       { register('gov',     {src=>$&, role=>$1, cat=>$2, catexp=>attr::parse($2)},       $1); }
+#     elsif(/^INIT ($role_re)$/)       { register('initr',   {src=>$&, role=>$1},                              0); }
+#     elsif(/^FIN ($role_re)$/)        { register('finr',    {src=>$&, role=>$1},                              0); }
+#     elsif(/^INIT ($av_re)$/)         { register('initf',   {src=>$&, flag=>$1},                              0); }
+#     elsif(/^FIN ($av_re)$/)          { register('finf',    {src=>$&, flag=>$1},                              0); }
+#     elsif(/^SET ($cat_re)\s+(\S+)$/) { register('set',     {src=>$&, cat=>$1, flag=>$2},                     0); }
+#     elsif(/^PASS (\S+)\s+(\S+)$/)    { register('pass',    {src=>$&, role=>$1, flag=>$2},                    0); }
+#     elsif(/^CONSTRE (\S+)\s+(\S+)$/) { register('constre', {src=>$&, role1=>$1, role2=>$2},                  0); }
+#     elsif(/^CONSTRI (\S+)\s+(\S+)$/) { register('constri', {src=>$&, role1=>$1, role2=>$2},                  0); }
+
+#     elsif(my ($hs,$hfs,$ds,$dfs,$r,$rprops) = /^LINK\s+($cats_re)((?:;$avlist_re)?)\s+($cats_re)((?:;$avlist_re)?)\s+($role_re)((?:$proplist_re)?)$/)
+#                                        { register('link', {src=>$&, hs=>$hs, hfs=>$hfs, ds=>$ds, dfs=>$dfs, r=>$r, props=>$rprops},0) }
+#     elsif(/^LONG\s+(\S+)((\s+<\S+)*)((\s+\S+>)*)$/)
+#     {
+# 	my $rel = $1;
+# 	my $ups = $2;
+# 	my $downs = $4;
+
+# 	$ups =~ s/<//g;
+# 	$ups =~ s/^\s+//;
+# 	my @up = split(/\s+/,$ups) or ();
+
+# 	$downs =~ s/>//g;
+# 	$downs =~ s/^\s+//;
+# 	my @down = split(/\s+/,$downs) or ();
+
+# 	register('long', {src=>$&, rel=>$rel, up=>\@up, down=>\@down},0);
+
+# 	print OUTPUT "LONG $rel " . join(",",@up) . "^" . join(",",@down) . "\n";
+#     }
+#     elsif(my ($cl,$cs) = /^CLASS\s+(\S+)\s*\=(.*)$/)
+#     {
+# 	$class{$1} = $classparser->classexpr($2);
+#     }
+#     elsif(/^$/)
+#     {
+# 	# pomijamy puste linie oraz komentarze
+#     }
+#     else
+#     {
+# 	print STDERR "Illegal format: $_\n";
+#     }
+# }
+
+
+
+# sub is_cat  { shift =~ /$attr::cat_re/; }
+# sub is_role { $role{shift}; }
+# sub is_flag { $flag{shift}; }
+
+
+# sub print_in
+# {
+#     my $data = shift();
+#     printf "in@%04d ", $data->{line};
+#     print $data->{src};
+# }
+
+# sub print_out
+# {
+#     printf "out@%08d ", $outline++;
+#     print @_;
+# }
+
+# sub addlinks
+# {
+#     my ($l, $h,$hfs,$d,$dfs,$r,$rprops) = @_;
+
+#     my @heads = extension($h);
+#     my @deps = extension($d);
+
+#     my @deps_gov;
+#   DEP_GOV:
+#     for my $dep (@deps)
+#     {
+# 	for my $gov (@govs)
+# 	{
+# 	    next DEP_GOV unless attr::match(@{$dep->{catexp}},@{$gov->{catexp}});
+# 	}
+# 	push @deps_gov, $dep;
+#     }
+    
+#     for my $head (@heads)
+#     {
+#       DEP:
+# 	for my $dep (@deps_gov)
+# 	{
+# 	    for my $agr (@agrs)
+# 	    {
+# 		next DEP unless attr::agree(@{$head->{catexp}},@{$dep->{catexp}},$agr->{attr});
+# 	    }
+# 	    print_outin("LINK $head->{cat}$hfs $dep->{cat}$dfs $r$rprops",$l, @agrs,@govs);
+# 	}
+#     }
+# }
+
+
+
+
     # elsif(/^INIT\s+([[:upper:]]\S*)$/)
     # {
@@ -251,223 +528,2 @@
     # 	}
     # }
-    elsif(my ($hs,$hfs,$ds,$dfs,$r,$rprops) = /^LINK\s+($cats_re)((?:;$avlist_re)?)\s+($cats_re)((?:;$avlist_re)?)\s+($role_re)((?:$proplist_re)?)$/)
-    {
-    	print OUTPUT "#$_\n";
-    	for my $h ($hs =~ /$attr::cat_re/g)
-    	{
-    	    for my $d ($ds =~ /$attr::cat_re/g)
-    	    {
-    		addlinks($h,$hfs,$d,$dfs,$r,$rprops);
-    	    }
-    	}
-    }
-    # elsif(my ($hs,$ds,$fs,$r) = /^LINK\s+($cats_re)\s+($cats_re)\s+(\S+)\s+(\S+)$/)
-    # {
-    # 	print OUTPUT "#$_\n";
-    # 	for my $h ($hs =~ /$attr::cat_re/g)
-    # 	{
-    # 	    for my $d ($ds =~ /$attr::cat_re/g)
-    # 	    {
-    # 		addlinks1($h,$d,$fs,$r);
-    # 	    }
-    # 	}
-    # }
-    elsif(/^FLAG\s+\S+$/)
-    {
-	++$nflag;
-	print OUTPUT "$_\n"
-    }
-    elsif(/^SET\s+(\S+)\s+(\S+)$/)
-    {
-	print OUTPUT "#$_\n";
-	my $cat = attr::parse $1;
-	my $flag = $2;
-	for my $atomcat (keys %cats)
-	{
-	    if(attr::match @$cat, @{$cats{$atomcat}})
-	    {
-		print OUTPUT "SET ".$atomcat." $flag\n";
-		++$nset;
-	    }
-	}
-    }
-    elsif(/^PASS\s+\S+\s+\S+$/)
-    {
-	++$npass;
-	print OUTPUT "$_\n"
-    }
-    elsif(/^CONSTR[IE]\s+\S+\s+\S+$/)
-    {
-	++$nconstr;
-	print OUTPUT "$_\n"
-    }
-    elsif(/^LONG\s+(\S+)((\s+<\S+)*)((\s+\S+>)*)$/)
-    {
-	++$nlong;
-	my $rel = $1;
-	my $ups = $2;
-	my $downs = $4;
-
-	$ups =~ s/<//g;
-	$ups =~ s/^\s+//;
-	my @up = split(/\s+/,$ups);
-
-	$downs =~ s/>//g;
-	$downs =~ s/^\s+//;
-	my @down = split(/\s+/,$downs);
-	print OUTPUT "LONG $rel " . join(",",@up) . "^" . join(",",@down) . "\n";
-    }
-    elsif(my ($cl,$cs) = /^CLASS\s+(\S+)\s*\:\s*(.*)/)
-    {
-	print OUTPUT "#$_\n";
-	for my $c ($cs =~ /\S+/g)
-	{
-	    my $cat = attr::parse $c;
-	
-	    for my $atomcat (sort(keys %cats))
-	    {
-		if(attr::match @$cat, @{$cats{$atomcat}})
-		{
-		    print OUTPUT "CLASS $cl $atomcat\n";
-		    ++$nclass;
-		}
-	    }
-	}
-    }
-    elsif(/^$/) {
-	# pomijamy puste linie oraz komentarze
-	}
-	else
-    {
-	print STDERR "Illegal format: $_\n";
-    }
-}
-
-
-sub addlinks
-{
-    my ($h,$hfs,$d,$dfs,$r,$rprops) = @_;
-
-    for my $a (@{$agr{$r}}) { print OUTPUT "#AGR $r $a\n"; }
-    for my $c (@{$gov{$r}}) { print OUTPUT "#GOV $r ".attr::unparse(@$c)."\n"; }
-    my $head = attr::parse $h;
-    my $dep = attr::parse $d;
-    
-    for my $atomhead (keys %cats)
-    {
-	if(attr::match @$head, @{$cats{$atomhead}})
-	{
-	  DEP:
-	    for my $atomdep (keys %cats)
-	    {
-		next DEP if ! attr::match @$dep, @{$cats{$atomdep}};
-		
-		for my $a (@{$agr{$r}})
-		{
-		    next DEP if ! attr::agree(@{$cats{$atomhead}},@{$cats{$atomdep}},$a);
-		}
-		
-		for my $c (@{$gov{$r}})
-		{
-		    next DEP if ! attr::match(@$c,@{$cats{$atomdep}});
-		}
-		
-		print OUTPUT "LINK $atomhead$hfs $atomdep$dfs $r$rprops\n";
-		++$nlink;
-		
-	    }
-	}
-    }
-}
-
-
-sub addlinks1
-{
-    my ($h,$d,$fs,$r) = @_;
-
-    for my $a (@{$agr{$r}}) { print OUTPUT "#AGR $r $a\n"; }
-    for my $c (@{$gov{$r}}) { print OUTPUT "#GOV $r ".attr::unparse(@$c)."\n"; }
-    my $head = attr::parse $h;
-    my $dep = attr::parse $d;
-    
-    for my $atomhead (keys %cats)
-    {
-	if(attr::match @$head, @{$cats{$atomhead}})
-	{
-	  DEP:
-	    for my $atomdep (keys %cats)
-	    {
-		next DEP if ! attr::match @$dep, @{$cats{$atomdep}};
-		
-		for my $a (@{$agr{$r}})
-		{
-		    next DEP if ! attr::agree(@{$cats{$atomhead}},@{$cats{$atomdep}},$a);
-		}
-		
-		for my $c (@{$gov{$r}})
-		{
-		    next DEP if ! attr::match(@$c,@{$cats{$atomdep}});
-		}
-		
-		print OUTPUT "LINK $atomhead $atomdep $fs $r\n";
-		++$nlink;
-		
-	    }
-	}
-    }
-}
-
-
-printf STDERR "%6d CAT   statements\n", 0+keys(%cats);
-printf STDERR "%6d ROLE  statements\n", 0+keys(%roles);
-printf STDERR "%6d SGL   statements\n", $nsgl;
-printf STDERR "%6d REQ   statements\n", $nreq;
-printf STDERR "%6d LEFT  statements\n", $nleft;
-printf STDERR "%6d RIGHT statements\n", $nright;
-printf STDERR "%6d INITR statements\n", $ninitr;
-printf STDERR "%6d FINR  statements\n", $nfinr;
-printf STDERR "%6d INITF statements\n", $ninitf;
-printf STDERR "%6d FINF  statements\n", $nfinf;
-printf STDERR "%6d INITC statements\n", $ninitc;
-printf STDERR "%6d FINC  statements\n", $nfinc;
-printf STDERR "%6d LINK  statements\n", $nlink;
-printf STDERR "%6d CLASS statements\n", $nclass;
-printf STDERR "%6d FLAG  statements\n", $nflag;
-printf STDERR "%6d SET   statements\n", $nset;
-printf STDERR "%6d PASS  statements\n", $npass;
-
-
-sub extractcats
-{
-    my $file = shift;
-    open DICFILE, "$file";
-    while(<DICFILE>)
-    {
-	while(/,([^[:space:];]+)/g)
-	{
-	    my $cat=$1;
-	    next if !$cat || exists $cats{$cat};
-	    $ncat++;
-	    print OUTPUT "CAT $1\n";
-	    $cats{$cat}=attr::parse($cat);
-	}
-    }
-    close DICFILE;
-}
-
-
-sub loadcats
-{
-    my $file = shift;
-    open CATFILE, "$file";
-    while(<CATFILE>)
-    {
-	tr/ \t\n//d;
-	next if !$_ || exists $cats{$_};
-	print OUTPUT "CAT $_\n";
-	++$ncat;
-	$cats{$_}=attr::parse($_);
-    }
-    close CATFILE;
-}
-
