File Coverage

blib/lib/Treex/PML/Backend/CSTS/Csts2fs.pm
Criterion Covered Total %
statement 19 282 6.7
branch 0 196 0.0
condition 0 15 0.0
subroutine 7 26 26.9
pod 0 19 0.0
total 26 538 4.8


line stmt bran cond sub pod time code
1             package Treex::PML::Backend::CSTS::Csts2fs;
2              
3 2     2   15 use vars qw($VERSION);
  2         6  
  2         91  
4             BEGIN {
5 2     2   33 $VERSION='2.24'; # version template
6             }
7 2     2   10 use Treex::PML;
  2         4  
  2         141  
8              
9             #
10             # TR vs AR (vs M)
11             #
12             # $ord = ord (also in TR case)
13             # $gov = ordorig vs govTR (vs govMD)
14             #
15             # "ordorig" := on TR
16             # "govTR" := on AR
17             #
18             # "TR" is @H on TR
19             # @N: ord on AR, dord on TR
20             # sentord is @W on TR
21             # govTR is stored on AR
22             # ordorig is stored on TR
23 2     2   14 use strict;
  2         4  
  2         96  
24 2     2   22 no warnings;
  2         5  
  2         10319  
25              
26             our $gov="ordorig";
27             our $ord="ord";
28             our $sentord="sentord";
29              
30             our $normal_gap='gappost';
31             our $no_node_gap='gappre';
32              
33             our $fill_empty_ord=0;
34              
35             our $fs_tail='(2,3)';
36             our @fs_patterns=('${form}', '${afun}');
37             our $fs_hint="tag:\t".'${tag}';
38              
39             our $next_sentord=0;
40              
41             our %composed_attrs=();
42              
43             sub assign_TRt {
44 0     0 0   my ($s,$data,$machine)=@_;
45 0 0         $machine = $machine ? "M" : "";
46             # hajic 2002/04/02
47             # - moved - to front of [] expressions
48             # - added X to last [] ($9)
49             # - swapped $2 and $3
50             # (based on observations of data only!)
51              
52 0 0         if ($data=~/([-MIFNX])([-123X])([-SPX])([-SPAX])([-PCRX])([-10X])([-IMCX])([-DBHVSPFX])([.!DM?X])/) {
53 0           my $result;
54 0 0         if ($1 eq 'M') { $result = 'ANIM' }
  0 0          
    0          
    0          
    0          
    0          
55 0           elsif ($1 eq 'I') { $result = 'INAN' }
56 0           elsif ($1 eq 'F') { $result = 'FEM' }
57 0           elsif ($1 eq 'N') { $result = 'NEUT' }
58 0           elsif ($1 eq '-') { $result = 'NA' }
59 0           elsif ($1 eq 'X') { $result = '???' }
60 0           to_node_attr($s,$result,'|','gender'.$machine);
61              
62             # hajic 2002/04/02
63             # - swapped $2 <-> $3 in teh following two switch sections:
64 0 0         if ($3 eq 'S') { $result = 'SG' }
  0 0          
    0          
    0          
65 0           elsif ($3 eq 'P') { $result = 'PL' }
66 0           elsif ($3 eq '-') { $result = 'NA' }
67 0           elsif ($3 eq 'X') { $result = '???' }
68 0           to_node_attr($s,$result,'|','number'.$machine);
69              
70 0 0         if ($2 eq '1') { $result = 'POS' }
  0 0          
    0          
    0          
    0          
71 0           elsif ($2 eq '2') { $result = 'COMP' }
72 0           elsif ($2 eq '3') { $result = 'SUP' }
73 0           elsif ($2 eq '-') { $result = 'NA' }
74 0           elsif ($2 eq 'X') { $result = '???' }
75 0           to_node_attr($s,$result,'|','degcmp'.$machine);
76              
77 0 0         if ($4 eq 'S') { $result = 'SIM' }
  0 0          
    0          
    0          
    0          
78 0           elsif ($4 eq 'P') { $result = 'POST' }
79 0           elsif ($4 eq 'A') { $result = 'ANT' }
80 0           elsif ($4 eq '-') { $result = 'NA' }
81 0           elsif ($4 eq 'X') { $result = '???' }
82 0           to_node_attr($s,$result,'|','tense'.$machine);
83              
84 0 0         if ($5 eq 'P') { $result = 'PROC' }
  0 0          
    0          
    0          
    0          
85 0           elsif ($5 eq 'C') { $result = 'CPL' }
86 0           elsif ($5 eq 'R') { $result = 'RES' }
87 0           elsif ($5 eq '-') { $result = 'NA' }
88 0           elsif ($5 eq 'X') { $result = '???' }
89 0           to_node_attr($s,$result,'|','aspect'.$machine);
90              
91 0 0         if ($6 eq '1') { $result = 'IT1' }
  0 0          
    0          
    0          
92 0           elsif ($6 eq '0') { $result = 'IT0' }
93 0           elsif ($6 eq '-') { $result = 'NA' }
94 0           elsif ($6 eq 'X') { $result = '???' }
95 0           to_node_attr($s,$result,'|','iterativeness'.$machine);
96              
97 0 0         if ($7 eq 'I') { $result = 'IND' }
  0 0          
    0          
    0          
    0          
98 0           elsif ($7 eq 'M') { $result = 'IMP' }
99 0           elsif ($7 eq 'C') { $result = 'CDN' }
100 0           elsif ($7 eq '-') { $result = 'NA' }
101 0           elsif ($7 eq 'X') { $result = '???' }
102 0           to_node_attr($s,$result,'|','verbmod'.$machine);
103              
104 0 0         if ($8 eq 'D') { $result = 'DECL' }
  0 0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
105 0           elsif ($8 eq 'B') { $result = 'DEB' }
106 0           elsif ($8 eq 'H') { $result = 'HRT' }
107 0           elsif ($8 eq 'V') { $result = 'VOL' }
108 0           elsif ($8 eq 'S') { $result = 'POSS' }
109 0           elsif ($8 eq 'P') { $result = 'PERM' }
110 0           elsif ($8 eq 'F') { $result = 'FAC' }
111 0           elsif ($8 eq '-') { $result = 'NA' }
112 0           elsif ($8 eq 'X') { $result = '???' }
113 0           to_node_attr($s,$result,'|','deontmod'.$machine);
114              
115 0 0         if ($9 eq '.') { $result = 'ENUNC' }
  0 0          
    0          
    0          
    0          
    0          
    0          
116 0           elsif ($9 eq '!') { $result = 'EXCL' }
117 0           elsif ($9 eq 'D') { $result = 'DESID' }
118 0           elsif ($9 eq 'M') { $result = 'IMPER' }
119 0           elsif ($9 eq '?') { $result = 'INTER' }
120 0           elsif ($9 eq '-') { $result = 'NA' }
121 0           elsif ($9 eq 'X') { $result = '???' }
122 0           to_node_attr($s,$result,'|','sentmod'.$machine);
123             }
124             }
125              
126             sub assign_quot_dsp {
127 0     0 0   my ($s,$data)=@_;
128 0 0         if ($data=~/quot/) {
129 0           to_node_attr($s,'QUOT','|','quoted');
130             } else {
131 0           to_node_attr($s,'NIL','|','quoted');
132             }
133 0 0         if ($data=~/(dspp|dspi|dsp)/) {
134 0           to_node_attr($s,uc($1),'|','dsp');
135             }
136             }
137              
138             my %start_tag = (
139             's' => [sub {
140             my ($s)=@_;
141             &make_new_tree(@_);
142             $s->{treeNo}++;
143             $s->{ID2}=$s->{file};
144             $s->{root}->{form}="#$s->{treeNo}";
145             $s->{root}->{origf}=$s->{root}->{form};
146             $s->{root}->{afun}="AuxS";
147             $s->{root}->{ord}=0;
148             $s->{root}->{sentord}=0;
149             $s->{root}->{dord}=0;
150             $s->{root}->{tag}="Z#-------------";
151             $s->{root}->{lemma}="#";
152             $s->{root}->{trlemma}=$s->{root}->{form};
153             $s->{root}->{TR}="";
154             $s->{root}->{ARhide}='';
155             $s->{root}->{X_hide}='';
156             $s->{root}->{func}="SENT";
157             }],
158             'salt' => [sub {
159             my ($s)=@_;
160             &make_new_tree(@_);
161             $s->{root}->{form}="#$s->{treeNo}.alt";
162             $s->{root}->{origf}=$s->{root}->{form};
163             $s->{root}->{ord}=0;
164             $s->{root}->{dord}=0;
165             $s->{root}->{sentord}=0;
166             $s->{root}->{afun}="AuxS";
167             $s->{root}->{tag}="Z#-------------";
168             $s->{root}->{lemma}="#";
169             $s->{root}->{trlemma}=$s->{root}->{form};
170             $s->{root}->{TR}="";
171             $s->{root}->{ARhide}='';
172             $s->{root}->{X_hide}='';
173             $s->{root}->{func}="SENT";
174             }],
175             'f' => [\&make_new_node,0],
176             'd' => [\&make_new_node,0],
177             'fadd' => [\&make_new_node,1],
178             'TRl' => [sub {
179             my ($s)=@_;
180             # inicialization may be altered to fill
181             # 'hide' here otherwise
182             $s->{node}->{TR}="";
183             }],
184             'MTRl' => [sub {
185             my ($s)=@_;
186             # inicialization may be altered to fill
187             # 'hide' here otherwise (maybe not easy as
188             # these attributes are generated)
189             to_composed_node_attr($s,"","_","","src","MTR");
190             }],
191             # 'D' => [\©_tag_to,'','<','!GAP'],
192             'D' => [sub {
193             my ($s)=@_;
194             if ($s->{node}) {
195             $s->{node}->{nospace}=1;
196             } else {
197             copy_tag_to(@_,'','<','!GAP');
198             # $s->{following}->{$no_node_gap}.="";
199             }
200             }],
201              
202             'mauth' => [sub {
203             my ($s)=@_;
204             if (($s->{elements}->[-3]||'') eq 'h') {
205             copy_tag_to_following_root(@_,'','<','cstsmarkup');
206             } else {
207             copy_tag_to_following_root(@_,'','<','docmarkup');
208             }
209             }],
210             'mdate' => [sub {
211             my ($s)=@_;
212             if (($s->{elements}->[-3]||'') eq 'h') {
213             copy_tag_to_following_root(@_,'','<','cstsmarkup');
214             } else {
215             copy_tag_to_following_root(@_,'','<','docmarkup');
216             }
217             }],
218             'mdesc' => [sub {
219             my ($s)=@_;
220             if (($s->{elements}->[-3]||'') eq 'h') {
221             copy_tag_to_following_root(@_,'','<','cstsmarkup');
222             } else {
223             copy_tag_to_following_root(@_,'','<','docmarkup');
224             }
225             }],
226             'doc' => [sub {
227             my ($s)=@_;
228             my %attributes = map @$_, @{$s->{attributes}[-1]};
229             $s->{following_root}->{doc}=$attributes{'file'};
230             $s->{following_root}->{docid}=$attributes{'id'};
231             }],
232             'mod' => [\©_tag_to_following_root,'','<','docprolog'],
233             'txtype' => [\©_tag_to_following_root,'','<','docprolog'],
234             'genre' => [\©_tag_to_following_root,'','<','docprolog'],
235             'c' => [sub {
236             shift->{following_root}->{chap}='1';
237             }],
238             'verse' => [\©_tag_to_following_root,'','<','docprolog'],
239             'med' => [\©_tag_to_following_root,'','<','docprolog'],
240             'authsex' => [\©_tag_to_following_root,'','<','docprolog'],
241             'lang' => [\©_tag_to_following_root,'','<','docprolog'],
242             'transsex' => [\©_tag_to_following_root,'','<','docprolog'],
243             'srclang' => [\©_tag_to_following_root,'','<','docprolog'],
244             'temp' => [\©_tag_to_following_root,'','<','docprolog'],
245             'firsted' => [\©_tag_to_following_root,'','<','docprolog'],
246             'authname' => [\©_tag_to_following_root,'','<','docprolog'],
247             'transname' => [\©_tag_to_following_root,'','<','docprolog'],
248             'opus' => [\©_tag_to_following_root,'','<','docprolog'],
249             'id' => [\©_tag_to_following_root,'','<','docprolog'],
250             'i' => [\©_tag_to,'','<','!GAP'],
251             'idioms' => [\©_tag_to,'','<','!GAP'],
252             'idiom' => [\©_tag_to,'','<','!GAP'],
253             'iref' => [\©_tag_to,'','<','!GAP'],
254             );
255              
256             my %end_tag = (
257             'csts' => [ \&make_last_tree ],
258             );
259              
260             my %att = (
261             'p n' => [sub { my($s,$data)=@_;
262             $s->{following_root}->{para}=$data;
263             }],
264             'A parallel' => [\&to_node_attr,'|','parallel'],
265             'A paren' => [\&to_node_attr,'|','paren'],
266             'A arabfa' => [\&to_node_attr,'|','arabfa'],
267             'A arabspec' => [\&to_node_attr,'|','arabspec'],
268             'A arabclause' => [\&to_node_attr,'|','arabclause'],
269             'MDt w' => [\&to_composed_node_attr,'_','|','src','wMDt'],
270             'MDl w' => [\&to_composed_node_attr,'_','|','src','wMDl'],
271             'MDA w' => [\&to_composed_node_attr,'_','|','src','wMDA'],
272             'MDA parallel' => [\&to_composed_node_attr,'_','|','src','parallelMD'],
273             'MDA paren' => [\&to_composed_node_attr,'_','|','src','parenMD'],
274             'MDA arabfa' => [\&to_composed_node_attr,'_','|','src','arabfaMD'],
275             'MDA arabspec' => [\&to_composed_node_attr,'_','|','src','arabspecMD'],
276             'MDA arabclause' => [\&to_composed_node_attr,'_','|','src','arabclauseMD'],
277             'MDg w' => [\&to_composed_node_attr,'_','|','src','wMDg'],
278             'wsd s' => [\&to_node_attr,'|','wsds'],
279             'wsd ewn' => [\&to_node_attr,'|','wsdewn'],
280             'wsd ili' => [\&to_node_attr,'|','wsdili'],
281             'wsd iliOffset' => [\&to_node_attr,'|','wsdiliOffset'],
282             's id' => [\&to_attr,'root','|','ID1'],
283             'salt id' => [\&to_attr,'root','|','ID1'],
284             'csts lang' => [\&to_node_attr,'|','cstslang'],
285             'f case' => [\&to_node_attr,'|','formtype'],
286             'f id' => [\&to_node_attr,'','AID'],
287             'd type' => [\&to_node_attr,'|','formtype'],
288             'd id' => [\&to_node_attr,'|','AID'],
289             'w kind' => [\&to_next_node_attr,'|','origfkind'],
290             't w'=> [\&to_node_attr,'|','wt'],
291             'fadd id' => [\&to_node_attr,'','TID'],
292             'fadd del' => [sub {
293             my ($s,$data)=@_;
294             &to_node_attr($s,uc($data),'|','del');
295             &to_node_attr($s,'hide','','ARhide');
296             }],
297             'MTRl quot' => [\&to_composed_node_attr,'_','|','src','quotMTRl'],
298             'TRl quot' => [\&assign_quot_dsp],
299             'coref ref' => [\&to_node_attr,'|','coref'],
300             'coref type' => [\&to_node_attr,'|','cortype'],
301             'TRl status' => [sub {
302             my ($s,$data)=@_;
303             &to_node_attr($s,'hide','','TR')
304             if ($data eq 'hidden');
305             }],
306             'MTRl status' => [sub {
307             my ($s,$data)=@_;
308             &to_composed_node_attr($s,'hide','_','|','src','MTR')
309             if ($data eq 'hidden');
310             }],
311             'TRl origin' => [sub {
312             my ($s,$data)=@_;
313             $data=~s/\s+/|/g;
314             &to_node_attr($s,$data,'','AIDREFS');
315             }],
316             'MTRl origin' => [sub {
317             my ($s,$data)=@_;
318             $data=~s/\s+/|/g;
319             &to_composed_node_attr($s,$data,'_','','src','MAIDREFS');
320             }],
321             'x name' => [sub {
322             my ($s,$data)=@_;
323             $s->{node}->{X_hide}='' if ($data eq 'TNT');
324             }]
325             );
326              
327             my %pcdata = (
328             'source' => [\&to_node_attr,'','cstssource'],
329             'mauth' => [sub {
330             my ($s)=@_;
331             if (($s->{elements}->[-3]||'') eq 'h') {
332             to_attr(@_,'following_root','','cstsmarkup');
333             } else {
334             to_attr(@_,'following_root','','docmarkup');
335             }
336             }],
337             'mdate' => [sub {
338             my ($s)=@_;
339             if (($s->{elements}->[-3]||'') eq 'h') {
340             to_attr(@_,'following_root','','cstsmarkup');
341             } else {
342             to_attr(@_,'following_root','','docmarkup');
343             }
344             }],
345             'mdesc' => [sub {
346             my ($s)=@_;
347             if (($s->{elements}->[-3]||'') eq 'h') {
348             to_attr(@_,'following_root','','cstsmarkup');
349             } else {
350             to_attr(@_,'following_root','','docmarkup');
351             }
352             }],
353             'mod' => [\&to_attr,'following_root','','docprolog'],
354             'txtype' => [\&to_attr,'following_root','','docprolog'],
355             'genre' => [\&to_attr,'following_root','','docprolog'],
356             'verse' => [\&to_attr,'following_root','','docprolog'],
357             'med' => [\&to_attr,'following_root','','docprolog'],
358             'authsex' => [\&to_attr,'following_root','','docprolog'],
359             'lang' => [\&to_attr,'following_root','','docprolog'],
360             'transsex' => [\&to_attr,'following_root','','docprolog'],
361             'srclang' => [\&to_attr,'following_root','','docprolog'],
362             'temp' => [\&to_attr,'following_root','','docprolog'],
363             'firsted' => [\&to_attr,'following_root','','docprolog'],
364             'authname' => [\&to_attr,'following_root','','docprolog'],
365             'transname' => [\&to_attr,'following_root','','docprolog'],
366             'opus' => [\&to_attr,'following_root','','docprolog'],
367             'id' => [\&to_attr,'following_root','','docprolog'],
368             'i' => [\&to_node_attr,'','!GAP'],
369             'iref' => [\&to_node_attr,'','!GAP'],
370             MDt => [\&to_composed_node_attr,'_','|','src','tagMD'],
371             MDl => [\&to_composed_node_attr,'_','|','src','lemmaMD'],
372             MMt => [sub {
373             my ($s,$data) = @_;
374             # dirty hack to have the same number of MMl and MMt values
375             to_composed_node_attr(@_,'_','|','src','tagMM');
376             my $name;
377             for my $a (@{$s->{attributes}[-1]}) {
378             if ($a->[0] eq 'src') {
379             $name='MM_'.$a->[1];
380             last;
381             }
382             }
383             my @l = split /\|/,$s->{node}->{'lemma'.$name};
384             my @t = split /\|/,$s->{node}->{'tag'.$name};
385             $s->{node}->{'lemma'.$name}.='|'.$l[$#l] if (@l == scalar(@t)-1);
386             }],
387             MMl => [\&to_composed_node_attr,'_','|','src','lemmaMM'],
388             MTRl => [\&to_composed_node_attr,'_','|','src','trlemmaM'],
389             MDg => [\&to_composed_node_attr,'_','|','src','govMD'],
390             MDA => [\&to_composed_node_attr,'_','|','src','afunMD'],
391             coref => [\&to_node_attr,'|','corlemma'],
392             f => [sub {
393             my ($s,$data)=@_;
394             &to_node_attr(@_,'|','form');
395             unless (exists($s->{node}->{origf})
396             or
397             $s->{node}->{formtype} =~ /gen$/
398             ) {
399             $s->{node}->{origf}=$data;
400             }
401             }],
402             w => [\&to_next_node_attr,'|','origf'],
403             d => [sub {
404             my ($s,$data)=@_;
405             &to_node_attr(@_,'|','form');
406             unless (exists($s->{node}->{origf})
407             or
408             $s->{node}->{formtype} =~ /gen$/
409             ) {
410             $s->{node}->{origf}=$data;
411             }
412             }],
413             P => [\&to_node_attr,'|','pronunciation'],
414             Ct => [\&to_node_attr,'|','alltags'],
415             l => [\&to_node_attr,'|','lemma'],
416             R => [\&to_node_attr,'|','root'], # should be src-ed by n parent
417             E => [\&to_node_attr,'|','ending'], # should be src-ed by n parent
418             t => [\&to_node_attr,'|','tag'],
419             A => [\&to_node_attr,'|','afun'],
420             TRl => [\&to_node_attr,'|','trlemma'],
421             TRg => [\&to_node_attr,'|','govTR'],
422             T => [\&to_node_attr,'|','func'],
423             Tmo => [\&to_node_attr,'|','memberof'],
424             Tpa => [\&to_node_attr,'|','parenthesis'],
425             Top => [\&to_node_attr,'|','operand'],
426             grm => [\&to_node_attr,'|','gram'],
427             TRt => [\&assign_TRt,0],
428             tfa => [\&to_node_attr,'|','tfa'],
429             tfr => [\&to_node_attr,'|','dord'],
430             fw => [\&to_node_attr,'|','fw'],
431             phr => [\&to_node_attr,'|','phraseme'],
432             Tframeid => [\&to_node_attr,'|','frameid'],
433             Tframere => [\&to_node_attr,'|','framere'],
434             g => [sub{
435             my ($s,$data)=@_;
436             to_node_attr(@_);
437             $s->{node}->{govTR}=$data if $s->{node}->{govTR} eq "";
438             },'|','ordorig'],
439             r => [\&to_node_attr,'|','ord'],
440             x => [sub {
441             my ($s,$data)=@_;
442             to_composed_node_attr($s,$data,"x_","","name","");
443             }],
444             );
445              
446             our (@csts,@misc,@minARheader,@minTRheader,@ARspecial,@ARheader,@PADTattributes,@PADTARheader,@TRheader);
447              
448             my $headers = <<'EOF';
449              
450             @csts = (
451             '@P nospace',
452             '@P root',
453             '@P ending',
454             '@P pronunciation',
455             '@P alltags',
456             '@P wt',
457             '@P origfkind',
458             '@P formtype',
459             "\@P $normal_gap",
460             "\@P $no_node_gap",
461             '@P para',
462             '@P cstslang',
463             '@P cstssource',
464             '@P cstsmarkup',
465             '@P chap',
466             '@P doc',
467             '@P docid',
468             '@P docmarkup',
469             '@P docprolog'
470             );
471              
472             @misc = (
473             '@P1 warning',
474             '@P3 err1',
475             '@P3 err2',
476             '@P reserve1',
477             '@P reserve2',
478             '@P reserve3',
479             '@P reserve4',
480             '@P reserve5'
481             );
482              
483              
484             @minARheader = (
485             '@P lemma',
486             '@O lemma',
487             '@P tag',
488             '@O tag',
489             '@P form',
490             '@O form',
491             '@P afun',
492             '@O afun',
493             '@L1 afun|---|Pred|Pnom|AuxV|Sb|Obj|Atr|Adv|AtrAdv|AdvAtr|Coord|AtrObj|ObjAtr|AtrAtr|AuxT|AuxR|AuxP|Apos|ExD|AuxC|Atv|AtvV|AuxO|AuxZ|AuxY|AuxG|AuxK|AuxX|AuxS|Pred_Co|Pnom_Co|AuxV_Co|Sb_Co|Obj_Co|Atr_Co|Adv_Co|AtrAdv_Co|AdvAtr_Co|Coord_Co|AtrObj_Co|ObjAtr_Co|AtrAtr_Co|AuxT_Co|AuxR_Co|AuxP_Co|Apos_Co|ExD_Co|AuxC_Co|Atv_Co|AtvV_Co|AuxO_Co|AuxZ_Co|AuxY_Co|AuxG_Co|AuxK_Co|AuxX_Co|Pred_Ap|Pnom_Ap|AuxV_Ap|Sb_Ap|Obj_Ap|Atr_Ap|Adv_Ap|AtrAdv_Ap|AdvAtr_Ap|Coord_Ap|AtrObj_Ap|ObjAtr_Ap|AtrAtr_Ap|AuxT_Ap|AuxR_Ap|AuxP_Ap|Apos_Ap|ExD_Ap|AuxC_Ap|Atv_Ap|AtvV_Ap|AuxO_Ap|AuxZ_Ap|AuxY_Ap|AuxG_Ap|AuxK_Ap|AuxX_Ap|Pred_Pa|Pnom_Pa|AuxV_Pa|Sb_Pa|Obj_Pa|Atr_Pa|Adv_Pa|AtrAdv_Pa|AdvAtr_Pa|Coord_Pa|AtrObj_Pa|ObjAtr_Pa|AtrAtr_Pa|AuxT_Pa|AuxR_Pa|AuxP_Pa|Apos_Pa|ExD_Pa|AuxC_Pa|Atv_Pa|AtvV_Pa|AuxO_Pa|AuxZ_Pa|AuxY_Pa|AuxG_Pa|AuxK_Pa|AuxX_Pa|Generated|NA|???',
494             '@P ID1',
495             '@P ID2',
496             '@VA origf',
497             '@P origf',
498             '@P afunprev',
499             '@P semPOS',
500             '@P tagauto',
501             '@P lemauto',
502             '@P AID',
503             '@P AIDREFS',
504             );
505              
506             @minTRheader = (
507             '@P ordtf',
508             '@P trlemma',
509             '@P gender',
510             '@L gender|---|ANIM|INAN|FEM|NEUT|NA|???',
511             '@P number',
512             '@L number|---|SG|PL|NA|???',
513             '@P degcmp',
514             '@L degcmp|---|POS|COMP|SUP|NA|???',
515             '@P tense',
516             '@L tense|---|SIM|ANT|POST|NA|???',
517             '@P aspect',
518             '@L aspect|---|PROC|CPL|RES|NA|???',
519             '@P iterativeness',
520             '@L iterativeness|---|IT1|IT0|NA|???',
521             '@P verbmod',
522             '@L verbmod|---|IND|IMP|CDN|NA|???',
523             '@P deontmod',
524             '@L deontmod|---|DECL|DEB|HRT|VOL|POSS|PERM|FAC|NA|???',
525             '@P sentmod',
526             '@L sentmod|---|ENUNC|EXCL|DESID|IMPER|INTER|NA|???',
527             '@P tfa',
528             '@L tfa|---|T|F|C|NA|???',
529             '@P func',
530             '@L2 func|---|ACT|AUTH|PAT|ADDR|EFF|ORIG|ACMP|ADVS|AIM|APP|APPS|ATT|BEN|CAUS|CNCS|COMPL|CONJ|COND|CONFR|CONTRA|CONTRD|CM|CPHR|CPR|CRIT|CSQ|CTERF|DENOM|DES|DIFF|DIR1|DIR2|DIR3|DISJ|DPHR|ETHD|EXT|FPHR|GRAD|HER|ID|INTF|INTT|LOC|MANN|MAT|MEANS|MOD|NA|NORM|OPER|PAR|PARTL|PREC|PRED|REAS|REG|RESL|RESTR|RHEM|RSTR|SUBS|TFHL|TFRWH|THL|THO|TOWH|TPAR|TSIN|TTILL|TWHEN|VOC|VOCAT|SENT|???',
531             '@P gram',
532             '@L gram|---|0|GNEG|DISTR|APPX|GPART|GMULT|VCT|PNREL|DFR|BEF|AFT|JBEF|INTV|WOUT|AGST|MORE|LESS|MULT|RATIO|ADD|SUBTR|ORDER|NIL|blízko|kolem|mezi.1|mezi.2|mimo|na|nad|naproti|pod|pøed|u|uprostøed|v|vedle|za|pøes|uvnitø|NA|???',
533             '@P memberof',
534             '@L memberof|---|CO|AP|NIL|???',
535             '@P fw',
536             '@P phraseme',
537             '@P del',
538             '@L del|---|ELID|ELEX|EXPN|NIL|???',
539             '@P quoted',
540             '@L quoted|---|QUOT|NIL|???',
541             '@P dsp',
542             '@L dsp|---|DSP|DSPP|DSPI|NIL|???',
543             '@P dispmod',
544             '@L dispmod|---|DISP|NIL|NA|???',
545             '@P coref',
546             '@P cortype',
547             '@L cortype|textual|grammatical|---',
548             '@P corlemma',
549             '@P corinfo',
550             '@P commentA',
551             '@P parenthesis',
552             '@L parenthesis|---|PA|NIL|???',
553             '@P operand',
554             '@L operand|---|OP|NIL|???',
555             '@P funcauto',
556             '@P funcprec',
557             '@P funcaux',
558             '@P TID',
559             '@P frameid',
560             '@P framere',
561             '@P state',
562             '@L state|---|NA|NIL|ST|???',
563             '@P argnum'
564             );
565              
566             @ARspecial = (
567             '@N ord',
568             '@P dord',
569             '@W sentord',
570             '@P TR',
571             '@P govTR',
572             '@H ARhide',
573             );
574              
575             our @ARheader = (
576             @minARheader,
577             @ARspecial,
578             @minTRheader,
579             @csts,
580             @misc
581             );
582              
583             @PADTattributes = (
584             '@P parallel',
585             '@L parallel|Co|Ap|no-parallel',
586             '@P paren',
587             '@L paren|Pa|no-paren',
588             '@P arabfa',
589             '@L arabfa|Ca|Exp|Fi|no-fa',
590             '@P arabspec',
591             '@L arabspec|Ref|Msd|no-spec',
592             '@P arabclause',
593             '@L arabclause|Pred|PredC|PredE|PredP|Pnom|no-claus'
594             );
595              
596             @PADTARheader= (
597             (map { my $x=$_; $x=~s/^(\@L[0-9]?\s*afun\|)(.*)$/$1---|Pred|Pnom|Sb|Obj|Atr|Adv|AtrAdv|AdvAtr|Coord|Ref|AtrObj|ObjAtr|AtrAtr|AuxP|Apos|ExD|Atv|Ante|AuxC|AuxO|AuxE|AuxY|AuxM|AuxG|AuxK|AuxX|AuxS|Generated|NA|???/; $x } @minARheader),
598             @ARspecial,
599             @PADTattributes,
600             @minTRheader,
601             @csts,
602             @misc
603             );
604              
605             @TRheader = (
606             @minARheader,
607             '@P ord',
608             '@N dord',
609             '@W sentord',
610             '@H TR',
611             '@P ordorig',
612             '@P ARhide',
613             @minTRheader,
614             @csts,
615             @misc,
616             );
617              
618             EOF
619              
620             if ($]>=5.008) {
621             require Encode;
622             $headers=Encode::decode('iso-8859-2',$headers);
623 2     2   17 eval('use utf8;'.$headers);
  2         5  
  2         17  
624             } else {
625             eval($headers);
626             }
627              
628             our %initial_root_values = ();
629              
630             our %initial_node_values = (
631             # 'afun' => '???',
632             # 'gender' => '???',
633             # 'number' => '???',
634             # 'degcmp' => '???',
635             # 'tense' => '???',
636             # 'aspect' => '???',
637             # 'iterativeness' => '???',
638             # 'verbmod' => '???',
639             # 'deontmod' => '???',
640             # 'sentmod' => '???',
641             # 'tfa' => '???',
642             # 'func' => '???',
643             # 'gram' => '???',
644             # 'memberof' => '???',
645             # 'del' => 'NIL',
646             # 'quoted' => '???',
647             # 'dsp' => '???',
648             # 'corsnt' => '???',
649             # 'antec' => '???',
650             # 'parenthesis' => '???'
651             );
652              
653             our $header=\@ARheader;
654              
655              
656             sub build_tree {
657 0     0 0   my $root = shift;
658              
659 0           my %ordered=();
660 0           my @unordered=();
661             # fill uninitialized node values
662 0           foreach my $t (keys %initial_root_values) {
663 0 0         $root->{$t} = $initial_root_values{$t} unless exists($root->{$t});
664             }
665 0           foreach (@_) {
666 0 0 0       if ($_->{$ord} ne "" and !exists($ordered{$_->{$ord}})) {
667 0           $ordered{$_->{$ord}}=$_;
668             }
669             }
670 0           foreach (@_) {
671 0 0         next unless $_;
672 0 0 0       if ($_->{$gov} ne "" and exists($ordered{$_->{$gov}})) {
673 0           my $parent=$ordered{$_->{$gov}};
674 0           $_->paste_on($parent, $ord); # paste using $ord as the numbering attribute
675             }
676             }
677 0           foreach (reverse @_) {
678 0 0 0       if (ref($_) and ! $_->parent) {
679 0           $_->paste_on($root, $ord); # paste using $ord as the numbering attribute
680             }
681             }
682 0 0         if ($fill_empty_ord) {
683 0           foreach (@_) {
684 0 0         if ($_->{$ord} eq "") {
685 0           $_->{$ord}=$_->{$sentord};
686             }
687             }
688             }
689 0 0         unless (ref($root)) {
690 0           print STDERR "No root node\n";
691             }
692 0 0         return defined($root) ? $root : ();
693             }
694              
695             sub convert_element_to_string {
696 0     0 0   my ($element_name,$attributes)=@_;
697 0           my $string="<".$element_name;
698 0           foreach my $attr (@$attributes) {
699 0 0         next unless defined $attr->[1];
700 0           $string.=' '.$attr->[0].'="'.$attr->[1].'"';
701             }
702 0           return $string.">";
703             }
704              
705             sub to_attr {
706 0     0 0   my ($s,$data,$node,$concat,$attr)=@_;
707 0 0         if ($attr eq '!GAP') {
708 0 0         $attr = $s->{node} ? $normal_gap : $no_node_gap;
709             }
710             $s->{$node}->{$attr} =
711             exists($s->{$node}->{$attr}) && $s->{$node}->{$attr} ne "" ?
712 0 0 0       $s->{$node}->{$attr}.$concat.$data : $data;
713             }
714              
715             sub to_node_attr {
716 0     0 0   my ($s,$data,$concat,$attr)=@_;
717 0 0         my $node = ref($s->{node}) ? 'node' : 'following';
718 0           to_attr($s,$data,$node,$concat,$attr);
719             }
720              
721             sub to_next_node_attr {
722 0     0 0   my ($s,$data,$concat,$attr)=@_;
723             $s->{following}->{$attr} =
724             exists($s->{following}->{$attr}) && $s->{following}->{$attr} ne "" ?
725 0 0 0       $s->{following}->{$attr}.$concat.$data : $data;
726             }
727              
728             sub to_composed_node_attr {
729 0     0 0   my ($s,$data,$prefix,$concat,$compose,$attr)=@_;
730 0           my $value;
731 0           for (@{$s->{attributes}[-1]}) {
  0            
732 0 0         if ($_->[0] eq $compose) {
733 0           $value = $_->[1]; last;
  0            
734             }
735             }
736 0           $attr.=$prefix.$value;
737 0           to_node_attr($s,$data,$concat,$attr);
738 0           $composed_attrs{$attr}=1;
739             }
740              
741             sub make_new_node {
742 0     0 0   my ($s,$data,$added)=@_;
743             # starting a new node
744 0 0         push @{$s->{nodes}},$s->{node} if ref($s->{node});
  0            
745             #my $sentord=ref($s->{node}) ? $s->{node}->{sentord}+1 : 0;
746 0           $s->{node} = Treex::PML::Factory->createNode();
747 0           foreach (keys %initial_node_values) {
748 0           $s->{node}->{$_} = $initial_node_values{$_};
749             }
750 0 0         if ($added) {
751 0           $s->{node}->{sentord}=999;
752             } else {
753 0           $s->{node}->{sentord}=$next_sentord;
754 0           $next_sentord++;
755             }
756 0           foreach (keys %{$s->{following}}) {
  0            
757 0           $s->{node}->{$_} = $s->{following}->{$_};
758             }
759 0           $s->{following}={};
760             }
761              
762             sub make_new_tree {
763 0     0 0   my ($s)=@_;
764             # starting a new tree
765 0           $next_sentord=0;
766 0           make_new_node(@_);
767 0 0         push @{$s->{trees}}, build_tree(@{$s->{nodes}}) if (@{$s->{nodes}});
  0            
  0            
  0            
768 0           $s->{root}=$s->{node};
769 0           foreach (keys %{$s->{following_root}}) {
  0            
770 0           $s->{root}->{$_} = $s->{following_root}->{$_};
771             }
772 0           $s->{following_root}={};
773 0           @{$s->{nodes}}=();
  0            
774             }
775              
776             sub make_last_tree {
777 0     0 0   my ($s)=@_;
778 0 0         push @{$s->{nodes}},$s->{node} if ref($s->{node});
  0            
779 0 0         push @{$s->{trees}}, build_tree(@{$s->{nodes}}) if (@{$s->{nodes}});
  0            
  0            
  0            
780 0 0         print STDERR "Unstored data for following node\n" if (keys(%{$s->{following}}));
  0            
781 0 0         print STDERR "Unstored data for following root\n" if (keys(%{$s->{following_root}}));
  0            
782 0           @{$s->{nodes}}=();
  0            
783             }
784              
785             sub copy_tag_to_following_root {
786 0     0 0   my ($s,$data,$concat,$tag,$attr)=@_;
787 0 0         if ($tag =~/\
788 0           to_attr($s,convert_element_to_string($s->{elements}->[-1],$s->{attributes}->[1]),"following_root",$concat,$attr);
789             }
790 0 0         if ($tag =~/\>/) {
791 0           to_attr($s,"","following_root",$concat,$attr);
792             }
793             }
794              
795             sub copy_tag_to {
796 0     0 0   my ($s,$data,$concat,$tag,$attr)=@_;
797 0 0         if ($tag =~/\
798 0           to_node_attr($s,convert_element_to_string($s->{elements}->[-1],$s->{attributes}->[-1]),$concat,$attr);
799             }
800 0 0         if ($tag =~/\>/) {
801 0           to_node_attr($s,"",$concat,$attr);
802             }
803             }
804              
805             sub unescape_data {
806 0     0 0   my ($data)=@_;
807 2     2   23 use bytes;
  2         5  
  2         17  
808 0           $data =~ s{\\ ( \| | \\ | n | [0-9]{0-3})}{
809 0           my $case = $1;
810 0 0         if ($case eq '\\') { # escaped backslash
    0          
    0          
811 0           '\\'
812             } elsif ($case eq 'n') { # escaped newline (record end)
813 0           "\n"
814             } elsif ($case eq '|') { # SDATA bracket (ignoring)
815 0           ''
816             } else {
817 0           chr(oct($1))
818             }
819             }gex;
820 0           return $data;
821             }
822              
823             sub read {
824 0     0 0   my ($fh,$fsfile) = @_;
825 0 0         return unless ref($fsfile);
826              
827 0           my (%defs,@attlist,$event,@trees,@header);
828 0           my (@elements, $next_attributes, @attributes);
829 0           $next_attributes=[];
830 0           my $state = {
831             elements => \@elements, # element name stack
832             attributes => \@attributes, # element attribute-list stack
833             file => undef, # fixme
834             event => undef,
835             root => undef,
836             following_root => {},
837             node => undef,
838             following => {},
839             trees => [],
840             nodes => []
841             };
842              
843 0           my $document_is_conforming=0;
844             # we parse the the output of nsgmls
845             # and dispatch as needed
846 0           while (!eof($fh)) {
847 0           my $type = getc($fh);
848 0           my $data = <$fh>;
849 0           chop($data);
850 0 0         if ($type eq '(') { # start element
    0          
    0          
    0          
    0          
851 0           push @elements, $data;
852 0           push @attributes, $next_attributes;
853 0 0         if (exists($start_tag{$data})) {
854 0           my ($cb,@args)=@{ $start_tag{$data} };
  0            
855 0           &$cb($state,$data,@args);
856             }
857 0           for my $attribute (@$next_attributes) {
858 0 0         if (exists $att{"$data $attribute->[0]"}) {
859 0           my ($cb,@args)=@{ $att{"$data $attribute->[0]"} };
  0            
860 0           &$cb($state,$attribute->[1],@args);
861             }
862             }
863 0           $next_attributes=[];
864             } elsif ($type eq ')') { # end element
865 0 0         if (exists($end_tag{$data})) {
866 0           my ($cb,@args)=@{ $end_tag{$data} };
  0            
867 0           &$cb($state,$data,@args);
868             }
869 0           pop @elements;
870 0           pop @attributes;
871             } elsif ($type eq '-') { # character data
872 0           my $element = $elements[-1];
873 0 0         if (exists($pcdata{$element})) {
874 0           my ($cb,@args)=@{ $pcdata{$element} };
  0            
875 0           &$cb($state,unescape_data($data),@args);
876             }
877             } elsif ($type eq 'A') { # attribute of the next element
878 0           my ($name,$value)= $data=~m{^(\S+) (?:IMPLIED$|(?:CDATA|NOTATION|ENTITY|TOKEN|ID) (.*))};
879 0           push @$next_attributes,[$name,unescape_data($value)];
880             } elsif ($type eq 'C') { # document is conforming
881 0           $document_is_conforming=1;
882             }
883             }
884              
885 0           @header=@{$header};
  0            
886 0           foreach (keys %composed_attrs) {
887 0           push @header,"\@P $_";
888             }
889 0           $fsfile->changeFS(Treex::PML::Factory->createFSFormat(\@header));
890 0           $fsfile->changeTail("$fs_tail\n");
891 0           $fsfile->changeTrees(@{$state->{trees}});
  0            
892 0           $fsfile->changePatterns(@fs_patterns);
893 0           $fsfile->changeHint($fs_hint);
894              
895 0           return $document_is_conforming;
896             }
897              
898             sub setupTR {
899 0     0 0   $gov = "govTR";
900 0           $header = \@TRheader;
901 0           $initial_node_values{TR}='hide';
902 0           $initial_root_values{reserve1}='TR_TREE';
903 0           $fs_tail='(2,3)';
904 0           @fs_patterns=(); # proper patterns added by TrEd's hook
905 0           $fs_hint=undef;
906              
907             }
908              
909             sub setupAR {
910 0     0 0   $gov="ordorig";
911 0           $header = \@ARheader;
912 0           delete $initial_node_values{TR};
913 0           delete $initial_root_values{reserve1};
914 0           $fs_tail='(2,3)';
915 0           @fs_patterns=('${form}', '${afun}');
916 0           $fs_hint="tag:\t\${tag}\nlemma:\t\${lemma}";
917             }
918              
919             sub setupPADTAR {
920 0     0 0   setupAR();
921 0           $header = \@PADTARheader;
922 0           @fs_patterns=('${form}',
923             '#{custom1}
924             ' grep { $this->{$_}=~/./ && $this->{$_}!~/^no-/ }'.
925             ' qw(afun parallel paren arabfa arabspec arabclause) ?>');
926 0           $fs_hint="tag:\t\${tag}\nlemma:\t\${lemma}\ngloss:\t\${x_gloss}\ncommentA:\t\${commentA}";
927             }
928              
929             # hackish stuff follows...
930             # people should stop using CSTS |-/
931             sub setupSpec {
932 0     0 0   $gov = $_[0];
933 0 0         if (@_>1) {
934 0           $header = [ @TRheader ];
935 0 0         if ($_[1] ne "") {
936 0           @$header = ((grep !/\@N/,@$header), '@N '.$_[1]);
937             }
938 0 0         if (@_>2) {
939 0 0         if ($_[2] ne "") {
940 0           @$header = ((grep !/\@[H]/,@$header) , '@H '.$_[2]);
941             } else {
942             # backward in-compatibility: empty => use X_hide
943             # old behavior: always use X_hide
944 0           @$header = ((grep !/\@[H]/,@$header) , '@H X_hide');
945 0           $initial_node_values{X_hide}='hide';
946             }
947             }
948             }
949             }
950              
951             1;