prawie cakiem nowe dgc, due zmiany w dgp, pomniejsze poprawki

This commit is contained in:
Tomasz Obrebski 2013-01-17 20:50:41 +01:00
parent 555c7f814b
commit 3b02b04ff9
20 changed files with 1043 additions and 755 deletions

View File

@ -8,6 +8,7 @@
# ************************************************************
#
# All lines must looks like:
# parameter_name [=] value
# parameter_name=value (BASH SYNTAX!)
#
symbols=LANG_DIR/LANGUAGE/LANGUAGE.sym
dictionary_home=/home/to/dane/pmdbf

View File

@ -11,5 +11,8 @@
# parameter_name [=] value
#
categories = LANG_DIR/LANGUAGE/lem.bin.cats
# categories = /home/to/dane/pmdbf/lem.cats
grammar = LANG_DIR/gram.dgc
# grammar = /home/to/dane/grammar/gram.dgc
outputfile = LANG_DIR/gram.dgp
# outputfile = /home/to/dane/grammar/gram.dgp

View File

@ -12,6 +12,7 @@
#
grammar = LANG_DIR/gram.dgp
# grammar = /home/to/dane/grammar/gram.dgp
process = W
process = BOS
process = EOS

View File

@ -11,5 +11,6 @@
# parameter_name [=] value
#
dictionary = LANG_DIR/LANGUAGE/lem.bin
#dictionary = /home/to/dane/pmdbf/lem.bin
#dictionary-home = LANG_DIR
process = W

View File

@ -10,7 +10,7 @@ our $attr_re = qr/(?:[[:upper:]]+)/;
our $val_re = qr/(?:[[:lower:][:digit:]+?!*-]|<[^>\n]+>)/;
our $av_re = qr/(?:$attr_re$val_re+)/;
our $avlist_re = qr/(?:$av_re+)/;
our $cat_re = qr/(?:$pos_re(?:\/$avlist_re)?)/;
our $cat_re = qr/(?:(?:$pos_re|\*)(?:\/$avlist_re)?)/;
sub match(\@\@)
{

View File

@ -8,7 +8,8 @@ ifdef LANG_DIR
install -m 0644 pl_PL.ISO-8859-2/cor.bin $(LANG_DIR)/pl_PL.ISO-8859-2
install -m 0644 pl_PL.ISO-8859-2/gue.bin $(LANG_DIR)/pl_PL.ISO-8859-2
install -m 0644 pl_PL.ISO-8859-2/lem.bin $(LANG_DIR)/pl_PL.ISO-8859-2
install -m 0644 pl_PL.ISO-8859-2/lem.bin.cats $(LANG_DIR)/pl_PL.ISO-8859-2
install -m 0644 pl_PL.ISO-8859-2/lem.fst $(LANG_DIR)/pl_PL.ISO-8859-2
install -m 0644 pl_PL.ISO-8859-2/lem.cats $(LANG_DIR)/pl_PL.ISO-8859-2
install -m 0644 pl_PL.ISO-8859-2/pl_PL.ISO-8859-2.sym $(LANG_DIR)/pl_PL.ISO-8859-2
install -m 0644 pl_PL.UTF-8/lem.bin $(LANG_DIR)/pl_PL.UTF-8
install -m 0644 gram.dgc $(LANG_DIR)
@ -22,8 +23,9 @@ ifdef LANG_DIR
rm $(LANG_DIR)/gram.dgc
rm $(LANG_DIR)/pl_PL.UTF-8/lem.bin
rm $(LANG_DIR)/pl_PL.ISO-8859-2/pl_PL.ISO-8859-2.sym
rm $(LANG_DIR)/pl_PL.ISO-8859-2/lem.bin.cats
rm $(LANG_DIR)/pl_PL.ISO-8859-2/lem.cats
rm $(LANG_DIR)/pl_PL.ISO-8859-2/lem.bin
rm $(LANG_DIR)/pl_PL.ISO-8859-2/lem.fst
rm $(LANG_DIR)/pl_PL.ISO-8859-2/gue.bin
rm $(LANG_DIR)/pl_PL.ISO-8859-2/cor.bin
rmdir $(LANG_DIR)/pl_PL.ISO-8859-2

View File

@ -1,181 +0,0 @@
no_of_parts=0
while [ $# -gt 2 ]
do
case $1
in
-p)
no_of_parts=$2
shift 2
;;
*)
echo "The arguments to use are"
echo "-p: number of parts"
shift 1
;;
esac
done
if [ $# -lt 2 ]
then
echo "Usage:"
echo " compdic [-p <parts>] <wordlist> <automaton>"
echo "where"
echo " <wordlist> - file containig a list of words, one per line, iso-8859-2 encoded"
echo " <automaton> - a file to which the compiled automaton in openfst format shoul be written"
exit 0
fi
if [ $no_of_parts -eq 0 ]
then
no_of_parts=$(( `cat $1 | wc -l` / 75000 + 1 ))
fi
echo number of parts: $no_of_parts
tempdir=`mktemp -d /tmp/compdic.XXXXXX`
alphabet=`tempfile -d $tempdir`
cat <<EOF > $alphabet
<eps> 0
a 1
A 2
ä 3
± 4
¡ 5
b 6
B 7
c 8
C 9
æ 10
Æ 11
d 12
D 13
e 14
E 15
é 16
ê 17
Ê 18
f 19
F 20
g 21
G 22
h 23
H 24
i 25
I 26
j 27
J 28
k 29
K 30
l 31
L 32
³ 33
£ 34
m 35
M 36
n 37
N 38
ñ 39
Ñ 40
o 41
O 42
ö 43
ó 44
Ó 45
p 46
P 47
q 48
Q 49
r 50
R 51
s 52
S 53
¶ 54
¦ 55
t 56
T 57
u 58
U 59
ü 60
v 61
V 62
w 63
W 64
x 65
X 66
y 67
Y 68
z 69
Z 70
¼ 71
¬ 72
¿ 73
¯ 74
0 75
1 76
2 77
3 78
4 79
5 80
6 81
7 82
8 83
9 84
_ 85
- 86
? 87
! 88
~ 89
; 90
, 91
/ 92
* 93
+ 94
EOF
no_of_lines=$(( (`cat $1 | wc -l` / $no_of_parts) + 1 ))
split -l $no_of_lines $1 $tempdir/part.
automaton=$tempdir/output.fst
cat <<EOF | fstcompile --acceptor --isymbols=$alphabet > $automaton
EOF
n=0
for f in $tempdir/part.*
do
temp1=`tempfile -d $tempdir`
temp2=`tempfile -d $tempdir`
temp3=`tempfile -d $tempdir`
n=$(( $n + 1 ))
echo processing part $n
cat $f |\
lst2fstext |\
fstcompile --acceptor --isymbols=$alphabet |\
fstrmepsilon |\
fstdeterminize > $temp1
fstminimize $temp1 $temp2
fstunion $automaton $temp2 | fstrmepsilon | fstdeterminize > $temp3
fstminimize $temp3 $automaton
done
echo generating binary automaton file ...
cat $automaton | fsttopsort > $2
rm -r $tempdir
#echo generating cats file ...
#cat $1 | cut -d ',' -f 2 | sort -u $1.cats

View File

@ -1,18 +0,0 @@
if [ $# -ne 2 ]
then
echo "Usage:"
echo " compdic-fst-add <automaton1> <automaton2>"
echo "where"
echo " <automaton1> - automaton in openfst format"
echo " <automaton2> - automaton in openfst format containing paths to be removed from <automaton1>"
exit 0
fi
tempdir=`mktemp -d /tmp/compdic.XXXXXX`
automaton=$tempdir/output.fst
fstunion $1 $2 | fstrmepsilon | fstdeterminize | fstminimize | fsttopsort > $automaton
mv $automaton $1
rm -r $tempdir

View File

@ -1,18 +0,0 @@
if [ $# -ne 2 ]
then
echo "Usage:"
echo " compdic-fst-remove <automaton1> <automaton2>"
echo "where"
echo " <automaton1> - automaton in openfst format"
echo " <automaton2> - automaton in openfst format containing paths to be removed from <automaton1>"
exit 0
fi
tempdir=`mktemp -d /tmp/compdic.XXXXXX`
automaton=$tempdir/output.fst
fstdifference $1 $2 | fsttopsort > $automaton
mv $automaton $1
rm -r $tempdir

View File

@ -1,43 +0,0 @@
if [ $# -lt 2 ]
then
echo "Usage:"
echo " compdic-fst-update <dictionary> <difference> <difference> ..."
echo "where"
echo " <dictionary> - file containig a list of words, one per line, iso-8859-2 encoded"
echo " <difference> - a file to which the compiled automaton (cor/kor format) shoul be written"
exit 0
fi
tempdir=`mktemp -d /tmp/compdic.XXXXXX`
dict=$1
shift
dicplus=$tempdir/plus.dic
fstplus=$tempdir/plus.fst
dicminus=$tempdir/minus.dic
fstminus=$tempdir/minus.fst
tmpfst=$tempdir/tmp.fst
touch $dicplus
touch $dicminus
while (($#))
do
echo processing $1 ...
cat $1 | egrep '^>' | sed -r 's/^> *//' >> $dicplus
cat $1 | egrep '^<' | sed -r 's/^< *//' >> $dicminus
shift
done
echo updating $dict ...
compdic-create-fst $dicplus $fstplus
compdic-create-fst $dicminus $fstminus
fstdifference $dict $fstminus | fstdeterminize > $tmpfst
fstunion $tmpfst $fstplus | fstdeterminize | fstminimize > $tmpfst
mv ${dict} ${dict}~
mv $tmpfst ${dict}
rm -r $tempdir

View File

@ -6,12 +6,14 @@ dgc:
install:
ifdef BIN_DIR
install -m 0755 dgc $(BIN_DIR)
install -m 0755 l2src $(BIN_DIR)
endif
.PHONY: uninstall
uninstall:
ifdef BIN_DIR
rm $(BIN_DIR)/dgc
rm $(BIN_DIR)/l2src
endif
clean:

View File

@ -8,14 +8,18 @@
use lib "/usr/local/lib/utt";
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');
@ -30,27 +34,14 @@ my $file;
foreach $file ($systemconfigfile, $userconfigfile){
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; }
}
close CONFIG;
@ -89,141 +80,427 @@ END
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;
our %in; #gramatyka wej¶ciowa
our %idx; #indeks gramatyki wej¶ciowej (niektóre stwierdzenia)
our %out; #gramatyka wyj¶ciowa
our %class; #tablica klas
if(!$outputfile) {
*OUTPUT = *STDOUT;
}
elsif($outputfile eq "-") {
*OUTPUT = *STDOUT;
}
else {
open(OUTPUT, ">$outputfile") or die("Can't open output file: $outputfile!");
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;
extractcats($dicfile) if $dicfile;
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+)$/)
{
push @{$agr{$1}}, $2;
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" }
}
elsif(/^GOV\s+(\S+)\s+(\S+)$/)
# 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}})
{
push @{$gov{$1}}, attr::parse($2);
}
elsif(/^ROLE\s+\S+$/)
if( chk_role($x->{role}, $x) )
{
$roles{$_}=1;
print OUTPUT "$_\n";
}
elsif(/^SGL\s+\S+$/)
for my $atomcat (map{$_->{cat}} @{$x->{cats}})
{
++$nsgl;
print OUTPUT "$_\n";
}
elsif(/^REQ\s+(\S+)\s+(\S+)$/)
{
print OUTPUT "#$_\n";
my $cat = attr::parse $1;
for my $atomcat (keys %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}})
{
++$nleft;
print OUTPUT "$_\n";
}
elsif(/^RIGHT\s+\S+$/)
for my $atomcat (map{$_->{cat}} @{$x->{cats}})
{
++$nright;
print OUTPUT "$_\n";
print_outin("SET $atomcat $x->{flag}", $x);
}
elsif(/^INIT\s+[[:lower:]]\S*$/)
}
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}})
{
++$ninitr;
s/INIT/INITR/;
print OUTPUT "$_\n";
}
elsif(/^FIN\s+[[:lower:]]\S*$/)
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} } )
{
++$nfinr;
s/FIN/FINR/;
print OUTPUT "$_\n";
}
elsif(/^INIT\s+[[:upper:]]+[+-]$/)
DEP:
for my $dep (@deps)
{
++$ninitf;
s/INIT/INITF/;
s/[+-]//g;
print OUTPUT "$_\n";
}
elsif(/^FIN\s+[[:upper:]]+$/)
for my $agr (@agrs)
{
++$nfinf;
s/FIN/FINF/;
s/[+-]//g;
print OUTPUT "$_\n";
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);
}
}
}
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>)
{
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);
}
}
close DICFILE;
}
sub loadcats
{
my $file = shift;
open CATFILE, "$file";
while(<CATFILE>)
{
tr/ \t\n//d;
next if !$_; # || exists $cats{$_};
# print OUTPUT "CAT $_\n";
register("CAT $_", 'cat', {cat=>"$_", catexp=>attr::parse($_)}, $_);
}
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*)$/)
# {
# print OUTPUT "#$_\n";
@ -250,224 +527,3 @@ while(<INPUT>)
# }
# }
# }
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;
}

View File

@ -25,6 +25,7 @@ class Boubble
public:
Boubble(list<Role> u, list<Role> d, LongRel l, int s=-1);
Boubble(const char* pathstr, const char* l, int s=-1);
// Boubble(const Boubble& b) {_src=b._src; _upath=b._upath; _dpath=b._dpath; _rel=b._rel; };
Dir dir();
LongRel rel();
@ -137,7 +138,7 @@ Boubble* Boubble::step(Role r, Dir d)
return newboubble;
}
if(d==DOWN && _upath.empty() && !_dpath.empty())
if(d==DOWN && _upath.empty() && !_dpath.empty() && _dpath.front() == r)
{
Boubble* newboubble = new Boubble(_upath,_dpath,_rel,_src);
newboubble->_dpath.pop_front();

View File

@ -10,6 +10,10 @@ extern bool debug;
list<int> nodelist;
list<int>::iterator processed;
void print_sets(int n);
//====================================================================================================
void set_initial_constraints(int node)
@ -43,7 +47,7 @@ NodeProp compute_head_prop(NodeProp headprop, const Link& link, list<Boubble*> b
ret.required |= (grammar.constr_include(link.role) & ~ret.attached);
ret.forbidden |= grammar.constr_exclude(link.role);
ret.boubbles=bs;
ret.boubbles.merge(bs); //DOBRZE
ret.flags |= ( depflags & grammar.pass_flags(link.role) );
if(link.props[Prop("INIT")]) ret.init_attached=true;
@ -57,7 +61,7 @@ NodeProp compute_head_prop(NodeProp headprop, const Link& link, list<Boubble*> b
NodeProp compute_dep_prop(NodeProp depprop, const Link& link, list<Boubble*> bs)
{
NodeProp ret=depprop;
ret.boubbles=bs;
ret.boubbles.merge(bs); //DOBRZE
return ret;
}
@ -66,9 +70,24 @@ NodeProp compute_dep_prop(NodeProp depprop, const Link& link, list<Boubble*> bs)
int find_existing_node(int mnodeind, NodeProp p, bitset<MAXNODES>& newheadLH, bitset<MAXNODES>& newheadLV)
{
MNode& mnode = mgraph[mnodeind];
int ret=-1;
for(vector<int>::iterator ps=mnode.snodes.begin(); ps!=mnode.snodes.end(); ++ps)
if(sgraph[*ps].prop==p && sgraph[*ps].LH==newheadLH && sgraph[*ps].LV==newheadLV) return *ps;
return -1;
{
if(debug) fprintf(stderr,"#find existing node: checking %d ... \n", *ps);
if(sgraph[*ps].prop==p)
if(sgraph[*ps].LH==newheadLH && sgraph[*ps].LV==newheadLV)
{
ret = *ps;
// fprintf(stderr,"FIND EXISTING NODE SUCCEEDED BEACAUSE OF LH/LV equality ()\n");
}
else
{
// fprintf(stderr,"FIND EXISTING NODE FAILED BEACAUSE OF LH/LV inequality\n");
}
}
if(debug) fprintf(stderr,"\n");
return ret;
}
//====================================================================================================
@ -82,6 +101,7 @@ list<Boubble*> receive_boubbles(int node, Role role, Dir dir)
if(new_boubble)
ret.push_back(new_boubble);
}
return ret;
}
@ -119,174 +139,239 @@ list<Boubble*> collect_dep_boubbles(int head, int dep, Role role)
//====================================================================================================
int create_new_head_node_left(list<int>::iterator h, NodeProp& newheadprop, bitset<MAXNODES>& newheadLH, bitset<MAXNODES>& newheadLD, bitset<MAXNODES>& newheadLV)
void copy_links(int i, int j)
{
int newheadind = sgraph.clone(*h,newheadprop);
list<int>::iterator nextit=h; ++nextit;
nodelist.insert(nextit,newheadind);
sgraph[j].heads = sgraph[i].heads;
sgraph[j].deps = sgraph[i].deps;
}
void create_reverse_links(int n)
{
for(vector<Arc>::iterator a=sgraph[n].heads.begin(); a != sgraph[n].heads.end(); a++)
sgraph[a->dst].deps.push_back(Arc(n,a->role,a->headanc,a->depanc));
for(vector<Arc>::iterator a=sgraph[n].deps.begin(); a != sgraph[n].deps.end(); a++)
sgraph[a->dst].heads.push_back(Arc(n,a->role,a->headanc,a->depanc));
}
//====================================================================================================
int create_new_head_node_left(int h, NodeProp& newheadprop, bitset<MAXNODES>& newheadLH, bitset<MAXNODES>& newheadLD, bitset<MAXNODES>& newheadLV)
{
int newheadind = sgraph.clone(h,newheadprop);
// list<int>::iterator nextit=h; ++nextit;
// nodelist.insert(nextit,newheadind);
nodelist.push_back(newheadind);
sgraph[newheadind].LH=newheadLH;
sgraph[newheadind].LD = newheadLD;
sgraph[newheadind].in_LH=true;
sgraph[newheadind].LV.reset();
if(debug) sgraph.print_node_debug(stderr,"C ",newheadind,*h);
copy_links(h,newheadind);
create_reverse_links(newheadind);
if(debug) sgraph.print_node_debug(stderr,"C ",newheadind,h);
if(debug) print_sets(newheadind);
return newheadind;
}
int create_new_dep_node_left(list<int>::iterator d, NodeProp& prop, bitset<MAXNODES>& LH, bitset<MAXNODES>& LD, bitset<MAXNODES>& LV)
int create_new_dep_node_left(int d, NodeProp& prop, bitset<MAXNODES>& LH, bitset<MAXNODES>& LD, bitset<MAXNODES>& LV)
{
int newind = sgraph.clone(*d,prop);
list<int>::iterator nextit=d; ++nextit;
nodelist.insert(nextit,newind);
int newind = sgraph.clone(d,prop);
// list<int>::iterator nextit=d; ++nextit;
// nodelist.insert(nextit,newind);
nodelist.push_back(newind);
sgraph[newind].LH.reset();
sgraph[newind].LD=LD;
sgraph[newind].in_LH=false; //???????
sgraph[newind].LV.reset();
if(debug) sgraph.print_node_debug(stderr,"C ",newind,*d);
copy_links(d,newind);
create_reverse_links(newind);
if(debug) sgraph.print_node_debug(stderr,"C ",newind,d);
if(debug) print_sets(newind);
return newind;
}
int create_new_head_node_right(list<int>::iterator h, NodeProp& newheadprop, bitset<MAXNODES>& newheadLH, bitset<MAXNODES>& newheadLD, bitset<MAXNODES>& newheadLV)
int create_new_head_node_right(int h, NodeProp& newheadprop, bitset<MAXNODES>& newheadLH, bitset<MAXNODES>& newheadLD, bitset<MAXNODES>& newheadLV)
{
int newheadind = sgraph.clone(*h,newheadprop);
list<int>::iterator nextit=h; ++nextit;
nodelist.insert(nextit,newheadind);
int newheadind = sgraph.clone(h,newheadprop);
// list<int>::iterator nextit=h; ++nextit;
// nodelist.insert(nextit,newheadind);
nodelist.push_back(newheadind);
sgraph[newheadind].LH=newheadLH;
sgraph[newheadind].LD=newheadLD;
sgraph[newheadind].in_LH=false;
sgraph[newheadind].LV=newheadLV;
if(debug) sgraph.print_node_debug(stderr,"C ",newheadind,*h);
copy_links(h,newheadind);
create_reverse_links(newheadind);
if(debug) sgraph.print_node_debug(stderr,"C ",newheadind,h);
if(debug) print_sets(newheadind);
return newheadind;
}
int create_new_dep_node_right(list<int>::iterator d, NodeProp& prop, bitset<MAXNODES>& LH, bitset<MAXNODES>& LD, bitset<MAXNODES>& LV)
int create_new_dep_node_right(int d, NodeProp& prop, bitset<MAXNODES>& LH, bitset<MAXNODES>& LD, bitset<MAXNODES>& LV)
{
int newind = sgraph.clone(*d,prop);
list<int>::iterator nextit=d; ++nextit;
nodelist.insert(nextit,newind);
int newind = sgraph.clone(d,prop);
nodelist.push_back(newind);
sgraph[newind].LH=LH;
sgraph[newind].LD=LD;
sgraph[newind].in_LH=true; //???????
sgraph[newind].LV.reset();
if(debug) sgraph.print_node_debug(stderr,"C ",newind,*d);
copy_links(d,newind);
create_reverse_links(newind);
if(debug) sgraph.print_node_debug(stderr,"C ",newind,d);
if(debug) print_sets(newind);
return newind;
}
//====================================================================================================
void connect_left(list<int>::iterator h, list<int>::iterator d, const Link& l, list<Boubble*>& new_head_boubbles, list<Boubble*>& new_dep_boubbles)
void connect_left(int h, int d, const Link& l, list<Boubble*>& new_head_boubbles, list<Boubble*>& new_dep_boubbles)
{
NodeProp &oldheadprop = sgraph[*h].prop;
NodeProp &olddepprop = sgraph[*d].prop;
NodeProp &oldheadprop = sgraph[h].prop;
NodeProp &olddepprop = sgraph[d].prop;
NodeProp newheadprop = compute_head_prop(oldheadprop,l,new_head_boubbles,olddepprop.flags);
int newheadind;
if(oldheadprop==newheadprop)
newheadind = *h;
newheadind = h;
else
{
bitset<MAXNODES> newheadLH = sgraph[*h].LH;
bitset<MAXNODES> newheadLV = sgraph[*d].LV;
bitset<MAXNODES> newheadLD = sgraph[*h].LD;
bitset<MAXNODES> newheadLH = sgraph[h].LH;
bitset<MAXNODES> newheadLV = sgraph[d].LV;
bitset<MAXNODES> newheadLD = sgraph[h].LD;
newheadind = find_existing_node(sgraph[*h].mnode, newheadprop, newheadLH, newheadLV);
if( newheadind >= 0 )
// vector<int> newedge;
newheadind = find_existing_node(sgraph[h].mnode, newheadprop, newheadLH, newheadLV);
if( newheadind >= 0) // W£¡CZONE
sgraph[newheadind].LD |= newheadLD;
else
{
newheadind = create_new_head_node_left(h,newheadprop,newheadLH,newheadLD,newheadLV);
sgraph[newheadind].edge.clear();
sgraph[newheadind].edge_contains_self = false;
}
}
NodeProp newdepprop = compute_dep_prop(olddepprop,l,new_dep_boubbles);
int newdepind;
if(olddepprop==newdepprop)
newdepind = *d;
newdepind = d;
else
{
bitset<MAXNODES> newdepLH = sgraph[*d].LH;
bitset<MAXNODES> newdepLV = sgraph[*d].LV;
bitset<MAXNODES> newdepLD = sgraph[*d].LD;
bitset<MAXNODES> newdepLH = sgraph[d].LH;
bitset<MAXNODES> newdepLV = sgraph[d].LV;
bitset<MAXNODES> newdepLD = sgraph[d].LD;
newdepind = find_existing_node(sgraph[*d].mnode, newdepprop, newdepLH, newdepLV);
if( newdepind >= 0 )
newdepind = find_existing_node(sgraph[d].mnode, newdepprop, newdepLH, newdepLV);
if( newdepind >= 0) // W£¡CZONE
sgraph[newdepind].LD |= newdepLD; // TYLKO DLA LD
else
{
newdepind = create_new_dep_node_left(d,newdepprop,newdepLH,newdepLD,newdepLV);
sgraph[newdepind].edge.clear();
//sgraph[newdepind].edge.push_back(newdepind); // TO
sgraph[newdepind].edge_contains_self = true; // LUB TO
}
}
sgraph[newheadind].deps.push_back(Arc(newdepind,l.role,*h,*d));
if(sgraph[*d].saturated()) sgraph[newheadind].LV |= sgraph[*d].LV;
sgraph[newheadind].deps.push_back(Arc(newdepind,l.role,h,d));
sgraph[newdepind].heads.push_back(Arc(newheadind,l.role,h,d));
sgraph[newheadind].edge.push_back(newdepind);
sgraph[newheadind].LD.set(*d);
if(sgraph[*d].saturated()) sgraph[newheadind].LD |= sgraph[*d].LD;
if(sgraph[d].saturated()) sgraph[newheadind].LV |= sgraph[d].LV;
if(debug) sgraph.print_arc(stderr,newheadind,*d,l.role,0);
if(debug) sgraph.print_node_debug(stderr,"U ",newheadind,*h);
if(debug) sgraph.print_node_debug(stderr,"U ",*d,*d);
sgraph[newheadind].LD.set(d);
if(sgraph[d].saturated()) sgraph[newheadind].LD |= sgraph[d].LD;
if(debug) sgraph.print_arc(stderr,newheadind,d,l.role,0);
if(debug) sgraph.print_node_debug(stderr,"U ",newheadind,h);
if(debug) print_sets(newheadind);
if(debug) sgraph.print_node_debug(stderr,"U ",newdepind,d);
if(debug) print_sets(newdepind);
}
//----------------------------------------------------------------------------------------------------
void connect_right(list<int>::iterator h, list<int>::iterator d, const Link& l, list<Boubble*>& new_head_boubbles, list<Boubble*>& new_dep_boubbles)
void connect_right(int h, int d, const Link& l, list<Boubble*>& new_head_boubbles, list<Boubble*>& new_dep_boubbles)
{
NodeProp &oldheadprop = sgraph[*h].prop;
NodeProp &oldheadprop = sgraph[h].prop;
NodeProp newheadprop = compute_head_prop(oldheadprop,l,new_head_boubbles, sgraph[*d].prop.flags);
NodeProp newheadprop = compute_head_prop(oldheadprop,l,new_head_boubbles, sgraph[d].prop.flags);
int newheadind;
if(oldheadprop==newheadprop)
newheadind = *h;
newheadind = h;
else
{
bitset<MAXNODES> newheadLH = sgraph[*h].LH;
bitset<MAXNODES> newheadLV = sgraph[*h].LV;
bitset<MAXNODES> newheadLD = sgraph[*h].LD;
bitset<MAXNODES> newheadLH = sgraph[h].LH;
bitset<MAXNODES> newheadLV = sgraph[h].LV;
bitset<MAXNODES> newheadLD = sgraph[h].LD;
newheadind = find_existing_node(sgraph[*h].mnode, newheadprop, newheadLH, newheadLV);
if( newheadind >= 0 )
newheadind = find_existing_node(sgraph[h].mnode, newheadprop, newheadLH, newheadLV);
if(debug) fprintf(stderr,"#HEAD EXISTS %d\n",newheadind);
if( newheadind >= 0) // W£¡CZONE
sgraph[newheadind].LD |= newheadLD; // TYLKO DLA LD
else
{
newheadind = create_new_head_node_right(h,newheadprop,newheadLH,newheadLD,newheadLV);
//if(!sgraph[h].edge.empty()) sgraph[newheadind].edge.push_back(newheadind); // TO
sgraph[newheadind].edge_contains_self = sgraph[h].edge_contains_self; // LUB TO
sgraph[newheadind].visible_as_neighbour = false;
}
}
NodeProp &olddepprop = sgraph[*d].prop;
NodeProp &olddepprop = sgraph[d].prop;
NodeProp newdepprop = compute_dep_prop(olddepprop,l,new_dep_boubbles);
int newdepind;
if(olddepprop==newdepprop)
newdepind = *d;
newdepind = d;
else
{
bitset<MAXNODES> newdepLH = sgraph[*d].LH;
bitset<MAXNODES> newdepLV = sgraph[*d].LV;
bitset<MAXNODES> newdepLD = sgraph[*d].LD;
bitset<MAXNODES> newdepLH = sgraph[d].LH;
bitset<MAXNODES> newdepLV = sgraph[d].LV;
bitset<MAXNODES> newdepLD = sgraph[d].LD;
newdepind = find_existing_node(sgraph[*d].mnode, newdepprop, newdepLH, newdepLV);
if( newdepind >= 0 )
newdepind = find_existing_node(sgraph[d].mnode, newdepprop, newdepLH, newdepLV);
if(debug) fprintf(stderr,"#DEP EXISTS %d\n",newdepind);
if( newdepind >= 0) // W£¡CZONE
sgraph[newdepind].LD |= newdepLD; // TYLKO DLA LD
else
{
newdepind = create_new_dep_node_right(d,newdepprop,newdepLH,newdepLD,newdepLV);
sgraph[newdepind].edge.clear();
sgraph[newdepind].edge_contains_self = false;
}
}
sgraph[newdepind].heads.push_back(Arc(newheadind,l.role,*h,*d));
sgraph[newdepind].heads.push_back(Arc(newheadind,l.role,h,d));
sgraph[newheadind].deps.push_back(Arc(newdepind,l.role,h,d));
//sgraph[newdepind].edge.push_back(newheadind);
sgraph[newdepind].LH.set(newheadind);
@ -295,8 +380,8 @@ void connect_right(list<int>::iterator h, list<int>::iterator d, const Link& l,
if(sgraph[newheadind].saturated()) sgraph[newdepind].LH |= sgraph[newheadind].LH;
if(debug) sgraph.print_arc(stderr,newheadind,newdepind,l.role,1);
if(debug) sgraph.print_node_debug(stderr,"U ",newheadind,*h);
if(debug) sgraph.print_node_debug(stderr,"U ",newdepind,*d);
if(debug) sgraph.print_node_debug(stderr,"U ",newheadind,h);
if(debug) sgraph.print_node_debug(stderr,"U ",newdepind,d);
}
@ -322,37 +407,33 @@ bool check_boubbles_at_target(list<Boubble*>& boubbles, int node)
return true;
}
// bool check_boubbles_at_target(list<Boubble*> boubbles, int node)
// {
// for(list<Boubble*>::iterator b = boubbles.begin(); b != boubbles.end(); ++b )
// if( (*b)->is_at_target() && !grammar.check_longrel(sgraph.cat((*b)->src()), sgraph.cat(node), (*b)->rel()) )
// return false;
// return true;
// }
//====================================================================================================
void try_connect_dependents(list<int>::iterator j)
void try_connect_dependents(int j)
{
for(list<int>::iterator i(j); i!=nodelist.begin(); --i)
if(sgraph.visible(*i,*j) && sgraph.saturated(*i))
// for(list<int>::iterator i(j); i!=nodelist.begin(); --i)
// if(sgraph.visible(*i,*j) && sgraph.saturated(*i))
LViterator lvi(sgraph,j);
int i;
while((i=lvi.next()) >= 0)
if(sgraph.saturated(i))
{
if(debug) {fprintf(stderr,"## %d <-- %d ... ",*i,*j); }
if(debug) {fprintf(stderr,"## %d <-- %d ... ",i,j); }
list<const Link*> ji_links = grammar.connectable2( sgraph.cat(*j), sgraph.cat(*i), sgraph[*j].prop.flags, sgraph[*i].prop.flags); // ref do Roles!!!
list<const Link*> ji_links = grammar.connectable2( sgraph.cat(j), sgraph.cat(i), sgraph[j].prop.flags, sgraph[i].prop.flags); // ref do Roles!!!
list<const Link*>::iterator ri = ji_links.begin();
if(ri == ji_links.end()) { if(debug) fprintf(stderr,"no roles\n"); }
else
{
for(; ri != ji_links.end(); ++ri )
if(!grammar.check_constr2(sgraph[*j].prop,sgraph[*i].prop,0,**ri ))
if(!grammar.check_constr2(sgraph[j].prop,sgraph[i].prop,0,**ri ))
{ if(debug) fprintf(stderr,"constraints failed\n"); }
else
{
list<Boubble*> new_head_boubbles = collect_head_boubbles(*j,*i,(*ri)->role);
list<Boubble*> new_dep_boubbles = collect_dep_boubbles(*j,*i,(*ri)->role);
list<Boubble*> new_head_boubbles = collect_head_boubbles(j,i,(*ri)->role);
list<Boubble*> new_dep_boubbles = collect_dep_boubbles(j,i,(*ri)->role);
if( !(check_boubbles_at_target(new_head_boubbles,*j) && check_boubbles_at_target(new_dep_boubbles,*i)) )
if( !(check_boubbles_at_target(new_head_boubbles,j) && check_boubbles_at_target(new_dep_boubbles,i)) )
{ if(debug) fprintf(stderr,"boubbles failed\n"); }
else
{
@ -367,27 +448,32 @@ void try_connect_dependents(list<int>::iterator j)
//----------------------------------------------------------------------------------------------------
void try_connect_heads(list<int>::iterator j)
void try_connect_heads(int j)
{
for(list<int>::iterator i(j); i!=nodelist.begin(); --i)
if(sgraph.visible(*i,*j))
{
if(debug) fprintf(stderr, "## %d --> %d ... ",*i,*j);
// for(list<int>::iterator i(j); i!=nodelist.begin(); --i)
// if(sgraph.visible(*i,*j) && sgraph.saturated(*j))
list<const Link*> ij_links = grammar.connectable2( sgraph.cat(*i), sgraph.cat(*j), sgraph[*i].prop.flags, sgraph[*j].prop.flags );
LViterator lvi(sgraph,j);
int i;
while((i=lvi.next()) >= 0)
if(sgraph.saturated(j))
{
if(debug) fprintf(stderr, "## %d --> %d ... ",i,j);
list<const Link*> ij_links = grammar.connectable2( sgraph.cat(i), sgraph.cat(j), sgraph[i].prop.flags, sgraph[j].prop.flags );
list<const Link*>::iterator ri = ij_links.begin();
if(ri == ij_links.end()) { if(debug) fprintf(stderr,"no roles\n"); }
else
{
for(; ri != ij_links.end(); ++ri )
if( !grammar.check_constr2( sgraph[*i].prop, sgraph[*j].prop, 1, **ri ) )
if( !grammar.check_constr2( sgraph[i].prop, sgraph[j].prop, 1, **ri ) )
{ if(debug) fprintf(stderr,"constraints failed\n"); }
else
{
list<Boubble*> new_head_boubbles = collect_head_boubbles(*i,*j,(*ri)->role);
list<Boubble*> new_dep_boubbles = collect_dep_boubbles(*i,*j,(*ri)->role);
list<Boubble*> new_head_boubbles = collect_head_boubbles(i,j,(*ri)->role);
list<Boubble*> new_dep_boubbles = collect_dep_boubbles(i,j,(*ri)->role);
if( !(check_boubbles_at_target(new_head_boubbles,*i) && check_boubbles_at_target(new_dep_boubbles,*j)) )
if( !(check_boubbles_at_target(new_head_boubbles,i) && check_boubbles_at_target(new_dep_boubbles,j)) )
{ if(debug) fprintf(stderr,"boubbles failed\n"); }
else
{
@ -401,6 +487,61 @@ void try_connect_heads(list<int>::iterator j)
//====================================================================================================
void update_sets()
{
for(int n=0; n<sgraph.size(); ++n)
{
LViterator lvi(sgraph,n,false);
LHiterator lhi(sgraph,n);
LDiterator ldi(sgraph,n);
int i;
// printf("UPDATING LV[%d]:",n);
while((i=lvi.next())>=0)
{
// printf(" %d",i);
sgraph[n].LV.set(i);
}
// printf("\n");
while((i=lhi.next())>=0) sgraph[n].LH.set(i);
while((i=ldi.next())>=0) sgraph[n].LD.set(i);
}
}
//====================================================================================================
void print_sets(int n)
{
LViterator lvi(sgraph,n);
LHiterator lhi(sgraph,n);
LDiterator ldi(sgraph,n);
int i;
printf("LV[%d]: ",n);
while((i=lvi.next())>=0)
{
printf("%d ",i);
sgraph[n].LV.set(i);
}
printf("LH[%d]: ",n);
while((i=lhi.next())>=0)
{
printf("%d ",i);
sgraph[n].LH.set(i);
}
printf("LD[%d]: ",n);
while((i=ldi.next())>=0)
{
printf("%d ",i);
sgraph[n].LD.set(i);
}
printf("\n");
}
//====================================================================================================
void reverse_links()
{
list<int>::iterator i = nodelist.begin();
@ -429,16 +570,19 @@ void dgp1()
set_initial_constraints(basenode);
nodelist.push_back(basenode);
if(debug) {sgraph.print_node_debug(stderr,"B ",basenode,-1);} // STDOUT!!!
if(debug) sgraph.print_node_debug(stderr,"B ",basenode,-1); // STDOUT!!!
if(debug) print_sets(basenode);
list<int>::iterator cursor=processed;
while(++cursor != nodelist.end())
{
try_connect_dependents(cursor);
try_connect_heads(cursor);
if(debug) sgraph.print_node_debug(stderr,"> ",*cursor,-1);
try_connect_dependents(*cursor);
try_connect_heads(*cursor);
processed=cursor;
}
}
reverse_links();
// reverse_links();
update_sets();
}

View File

@ -297,12 +297,37 @@ bool Grammar::read(FILE* f)
else if(strcmp(key,"LINK")==0 && fields==4)
{
char cat1[MAXLINE],flags1[MAXLINE],cat2[MAXLINE],flags2[MAXLINE],type[MAXLINE],props[MAXLINE];
char* double_slash_position;
// pierwszy argument
// if(sscanf(arg1,"%[^;];%s",cat1,flags1)==1) *flags1='\0';
if((double_slash_position=strstr(arg1,"//")) != NULL) // czy s± flagi
{
int cat_length=double_slash_position-arg1;
strncpy(cat1, arg1, cat_length); cat1[cat_length]='\0';
strcpy(flags1, arg1+cat_length+2);
}
else
{
strcpy(cat1, arg1);
flags1[0]='\0';
}
// drugi argument
// if(sscanf(arg2,"%[^;];%s",cat2,flags2)==1) *flags2='\0';
if((double_slash_position=strstr(arg2,"//")) != NULL) // czy s± flagi
{
int cat_length=double_slash_position-arg2;
strncpy(cat2, arg2, cat_length); cat2[cat_length]='\0';
strcpy(flags2, arg2+cat_length+2);
}
else
{
strcpy(cat2,arg2);
flags2[0]='\0';
}
// trzeci argument
if(sscanf(arg3,"%[^&]%s",type,props)==1) props[0]='\0';
if(sscanf(arg1,"%[^;];%s",cat1,flags1)==1) *flags1='\0';
if(sscanf(arg2,"%[^;];%s",cat2,flags2)==1) *flags2='\0';
if(sscanf(arg3,"%[^&]%s",type,props)==1) *props='\0';
// printf("line=%s\n\tcat1=%s flags1=%s cat2=%s flags2=%s type=%s props=%s\n",line,cat1,flags1,cat2,flags2,type,props);
// printf("line=%s\n\tcat1=<%s> flags1=%s cat2=<%s> flags2=%s type=<%s> props=%s\n",line,cat1,flags1,cat2,flags2,type,props);
if( chk_cat(cat1) && chk_cat(cat2) && chk_type(type) )
set_connect(cat1,parse_flags(flags1,"+"),parse_flags(flags1,"-"),cat2,parse_flags(flags2,"+"),parse_flags(flags2,"-"),type,parse_props(props));

View File

@ -37,11 +37,13 @@ unsigned int info=0U;
bool printtimeinfo=false;
void output();
main(int argc, char* argv[])
{
gengetopt_args_info args;
struct timeval readgrammar_starttime,readgrammar_endtime;
if(cmdline_parser(argc,argv,&args) != 0)
exit(1);
@ -70,13 +72,21 @@ main(int argc, char* argv[])
case 'c': info|=SGraph::CONSTRAINTS; break;
}
gettimeofday(&readgrammar_starttime,NULL);
grammar.read(grammarf);
fclose(grammarf);
gettimeofday(&readgrammar_endtime,NULL);
if(printtimeinfo)
fprintf(stderr,"### START TIME: %10.2fms\n", (float)MICROSECONDSELAPSED(readgrammar_starttime,readgrammar_endtime)/1000 );
////////////////////////////////////////////////////////////////////////////////////////////////////
// TESTOWANIE POPRAWNO¦CI ODCZYTU GRAMATYKI
// grammar.write(cout);
// exit(0);
////////////////////////////////////////////////////////////////////////////////////////////////////
struct timeval starttime,afterinput,afterparse,endtime;
@ -100,7 +110,9 @@ main(int argc, char* argv[])
if(strcmp(segtype,"EOS")==0)
{
gettimeofday(&afterinput,NULL);
dgp1(); // parametry!!! MGraph, SGraph, Grammar
gettimeofday(&afterparse,NULL);
output();
gettimeofday(&endtime,NULL);

View File

@ -27,6 +27,8 @@ int SGraph::add_base_snode(int mnodeind)
newnode.in_LH=true;
newnode.edge.push_back(lastnodeind());
return lastnodeind();
}
@ -55,8 +57,6 @@ int SGraph::clone(int ancind, NodeProp newprop)
SNode &newnode=makenewnode();
SNode &ancnode = nodes[ancind];
newnode.prop=newprop;
newnode.mnode=ancnode.mnode;
mgraph[newnode.mnode].snodes.push_back(lastnodeind());
@ -177,6 +177,11 @@ int SGraph::sprint_node_debug(char* buf, const char* pref, int n, int anc)
buf+=sprintf(buf,"%-16s",form(n));
buf+=sprint_node(buf,n,anc,HEADS|DEPS|SETS|CONSTRAINTS);
buf+=sprintf(buf,"/");
for(vector<int>::iterator e = nodes[n].edge.begin(); e != nodes[n].edge.end(); e++ )
buf += sprintf(buf,"%d ", *e);
buf+=sprintf(buf,"\n");
return buf-buf0;
}

View File

@ -6,6 +6,7 @@
#include <list>
#include <vector>
#include <bitset>
#include <stack>
#include "const.hh"
#include "mgraph.hh"
@ -71,15 +72,11 @@ bool NodeProp::operator==(const NodeProp& p)
if(init_attached != p.init_attached) return false;
if(fin_attached != p.fin_attached) return false;
list<Boubble*>::const_iterator b1 = p.boubbles.begin();
for(list<Boubble*>::const_iterator b = boubbles.begin(); b != boubbles.end(); b++)
{
if(b1 == p.boubbles.end())
return false;
list<Boubble*>::const_iterator b,b1;
for(b=boubbles.begin(), b1=p.boubbles.begin(); b != boubbles.end() && b1 != p.boubbles.end(); b++,b1++)
if(!(**b == **b1))
return false;
}
if(b1 != p.boubbles.end())
if(b != boubbles.end() || b1 != p.boubbles.end())
return false;
return true;
@ -171,10 +168,16 @@ void NodeProp::clear()
struct SNode
{
SNode() { visible_as_neighbour = true; }
int mnode;
NodeProp prop;
vector<int> edge;
bool edge_contains_self;
bool visible_as_neighbour;
bitset<MAXNODES> LV;
bitset<MAXNODES> LH;
bitset<MAXNODES> LD;
@ -230,6 +233,11 @@ public:
int size() {return nodes.size(); }
friend class LViterator;
friend class LHiterator;
friend class LDiterator;
friend class LNiterator;
private:
MGraph& mgraph;
@ -258,5 +266,275 @@ inline bool SGraph::saturated(int node)
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
class XXiterator
{
protected:
bool checked(int i) { return _checked[i]; }
void check(int i) { _checked.set(i); }
void push(stack<int>& s, int i)
{
if(!checked(i))
{
s.push(i);
check(i);
}
}
bitset<MAXNODES> _checked;
};
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
class LViterator : public XXiterator
{
public:
LViterator(SGraph& sg, int n, bool s);
int next();
private:
SGraph& sgraph;
MGraph& mgraph;
stack<int> waydown;
stack<int> wayup;
bool strict;
void push_ld(int i);
void push_lh(int i);
void push_ln(int i);
};
inline LViterator::LViterator(SGraph& sg, int n, bool s=true) : sgraph(sg), mgraph(sg.mgraph), strict(s)
{
if(sg[n].edge_contains_self) // TO DODAÆ PO PRZEJ¦CIU NA EDGE_CONTAINS_SELF
{
push_ld(n);
push_ln(n);
}
for(vector<int>::iterator i=sg[n].edge.begin(); i!=sg[n].edge.end(); ++i)
{
if(*i != n)
{
push_ld(*i);
push_ln(*i);
}
}
// if(!strict)
// {
// push_ld(n);
// push_ln(n);
// }
}
inline int LViterator::next()
{
if(wayup.empty())
{
if(waydown.empty())
return -1; //
else
{
int k = waydown.top();
waydown.pop();
push_ld(k);
push_ln(k);
if(wayup.empty())
return -1; // k NIE MA POPRZEDNIKÓW, NIE MO¯E TE¯ ZATEM MIEÆ LEWOSTRONNYCH PODRZÊDNIKÓW
else
{
int i = wayup.top();
wayup.pop();
push_lh(i);
return i;
}
}
}
else
{
int i = wayup.top();
wayup.pop();
push_lh(i);
return i;
};
}
inline void LViterator::push_ld(int i)
{
vector<Arc>& arcs = sgraph[i].deps;
for(vector<Arc>::iterator a = arcs.begin(); a != arcs.end(); ++a)
if(mgraph[sgraph[a->dst].mnode].pos < mgraph[sgraph[i].mnode].pos)
push(waydown,a->dst);
}
inline void LViterator::push_lh(int i)
{
vector<Arc>& arcs = sgraph[i].heads;
for(vector<Arc>::iterator a = arcs.begin(); a != arcs.end(); ++a)
if(mgraph[sgraph[a->dst].mnode].pos < mgraph[sgraph[i].mnode].pos)
push(wayup,a->dst);
}
inline void LViterator::push_ln(int i)
{
vector<int>& mpredecessors = mgraph[sgraph[i].mnode].pred;
for(vector<int>::iterator mp = mpredecessors.begin(); mp != mpredecessors.end(); ++mp) // poprzedniki w mgraph
{
vector<int>& spredecessors = mgraph[*mp].snodes;
for(vector<int>::iterator sp = spredecessors.begin(); sp != spredecessors.end(); ++sp )
if(sgraph[*sp].visible_as_neighbour || !strict)
push(wayup,*sp);
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
class LNiterator
{
public:
LNiterator(SGraph& sg, int n);
int next();
private:
SGraph& sgraph;
MGraph& mgraph;
int thenode;
stack<int> wayup;
void push_ln(int i);
};
inline LNiterator::LNiterator(SGraph& sg, int n) : sgraph(sg), mgraph(sg.mgraph), thenode(n)
{
push_ln(n);
}
inline int LNiterator::next()
{
if(wayup.empty())
return -1;
else
{
int i = wayup.top();
wayup.pop();
return i;
};
}
inline void LNiterator::push_ln(int i)
{
vector<int>& mpredecessors = mgraph[sgraph[i].mnode].pred;
for(vector<int>::iterator mp = mpredecessors.begin(); mp != mpredecessors.end(); ++mp) // poprzedniki w mgraph
{
vector<int>& spredecessors = mgraph[*mp].snodes;
for(vector<int>::iterator sp = spredecessors.begin(); sp != spredecessors.end(); ++sp )
wayup.push(*sp);
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
class LHiterator
{
public:
LHiterator(SGraph& sg, int n);
int next();
private:
SGraph& sgraph;
MGraph& mgraph;
stack<int> wayup;
void push_lh(int i);
};
inline LHiterator::LHiterator(SGraph& sg, int n) : sgraph(sg), mgraph(sg.mgraph)
{
push_lh(n);
}
inline int LHiterator::next()
{
if(wayup.empty())
return -1;
else
{
int i = wayup.top();
wayup.pop();
push_lh(i);
return i;
};
}
inline void LHiterator::push_lh(int i)
{
vector<Arc>& arcs = sgraph[i].heads;
for(vector<Arc>::iterator a = arcs.begin(); a != arcs.end(); ++a)
if(mgraph[sgraph[a->dst].mnode].pos < mgraph[sgraph[i].mnode].pos)
wayup.push(a->dst);
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
class LDiterator
{
public:
LDiterator(SGraph& sg, int n);
int next();
private:
SGraph& sgraph;
MGraph& mgraph;
int thenode;
stack<int> waydown;
void push_ld(int i);
};
inline LDiterator::LDiterator(SGraph& sg, int n) : sgraph(sg), mgraph(sg.mgraph), thenode(n)
{
push_ld(n);
}
inline int LDiterator::next()
{
if(waydown.empty())
return -1;
else
{
int k = waydown.top();
waydown.pop();
push_ld(k);
return k;
}
}
inline void LDiterator::push_ld(int i)
{
vector<Arc>& arcs = sgraph[i].deps;
for(vector<Arc>::iterator a = arcs.begin(); a != arcs.end(); ++a)
if(mgraph[sgraph[a->dst].mnode].pos < mgraph[sgraph[thenode].mnode].pos)
waydown.push(a->dst);
}
#endif

View File

@ -12,7 +12,7 @@ use File::HomeDir;
# katalog zawierajacy terms.m4
my $LIB_DIR="/usr/local/lib/utt";
my $systemconfigfile="/usr/local/etc/utt/grp.conf";
my $systemconfigfile="/etc/utt/grp.conf";
my $userconfigfile=home()."/.utt/grp.conf";
Getopt::Long::Configure('no_ignore_case_always');

View File

@ -155,7 +155,9 @@ end
def output_trees trees
for t in trees
$count += 1
t1=ground(t)
# t1=ground(t)
t1=t
span = $FOREST ? " span:" + (ground_tree_min(t1).to_s + ","+ground_tree_max(t1).to_s)+";" : ""
case $FORMAT
@ -169,7 +171,7 @@ def output_trees trees
print "\n"
when /h/
print "#\n# tree #{$count}\n# ------\n"
printtree(t1[0],t1[1],0)
printtree_dgp(t1[0],t1[1],0)
end
end
end
@ -177,20 +179,21 @@ end
def nodeinfo(id)
info=""
gphid = $gphid[id]
if $INFO =~ /o/
info += $ord1[id].to_s
info += $ord1[gphid].to_s + '/' + gphid.to_s + '/' + id.to_s
info += '.' if $INFO =~ /[nfm]/
end
if $INFO =~ /n/
info += id.to_s
info += gphid.to_s
info += '.' if $INFO =~ /[fm]/
end
if $INFO =~ /f/
info += $form[id]
info += $form[gphid]
info += ';' if $INFO =~ /m/
end
if $INFO =~ /m/
info += $lem[id]
info += $lem[gphid]
end
info
end
@ -217,6 +220,18 @@ def printtree(root,arcs,o)
end
end
def printtree_dgp(root,arcs,o)
if o==0
print "%-16s" % "root: "
end
print nodeinfo(root),"\n"
for arc in arcs.select{ |a| a[0]==root }.sort{|a,b| a[1]<=>b[1] }
print " "*(o+1)
print "%-16s" % (arc[2]+": ")
printtree_dgp(arc[1],arcs,o+1)
end
end
def printpar(root,arcs)
print nodeinfo(root)
deps = arcs.select{ |a| a[0]==root }.sort{|a,b| a[1]<=>b[1] }
@ -340,7 +355,7 @@ end
def gentrees2 bos, eos
$thetrees=[];
roots = (1...eos).select{|i| $vis.include? [i,eos]}.select{|i| $vis.include? [bos,i]}
roots = (bos..eos).select{|i| $vis.include? [i,eos]}.select{|i| $vis.include? [bos,i]}
if $DEBUG then print "ROOTS: #{roots.inspect}\n" end
for root in roots
@ -362,9 +377,10 @@ end
def buildR(min, max, tree)
if $DEBUG then print "buildR--#{min}--#{max}--#{tree.inspect}\n" end
trees=[]
for a in $arcs.select{|a| a[0]==max && $vis.include?([min,a[1]]) }
if $DEBUG then print "ARC: #{a.inspect}\n" end
for r in buildR(a[4],a[3],tree+[a]) #!!! buildR(a[1],a[3],tree+[a])
for arc in $arcs.select{|a| a[0]==max && $vis.include?([min,a[1]]) }
if $DEBUG then print "ARC: #{arc.inspect}\n" end
for r in buildR(arc[1],arc[0],tree+[arc]) #!!! buildR(a[1],a[3],tree+[a])
# for r in buildR(arc[4],arc[3],tree+[arc]) #!!! buildR(a[1],a[3],tree+[a])
(rmin,rmax,rarcs) = r
for l in buildR(min,rmin,rarcs)
(lmin,lmax,larcs) = l
@ -394,7 +410,8 @@ def buildL(min,max,tree)
trees=[]
for arc in $arcs.select{|a| a[1]==max && $lhs.include?([min,a[0]]) }
if $DEBUG then print "ARC: #{arc.inspect}\n" end
for r in buildR(arc[3],arc[4],tree+[arc]) ### buildR(arc[3],max,tree+[arc])
for r in buildR(arc[0],arc[1],tree+[arc]) ### buildR(arc[3],max,tree+[arc])
#for r in buildR(arc[3],arc[4],tree+[arc]) ### buildR(arc[3],max,tree+[arc])
(rmin,rmax,rarcs) = r
for l in buildL(min,rmin,rarcs)
(lmin,lmax,larcs) = l