source: app/src/mar/mar @ d33e555

help
Last change on this file since d33e555 was 6b3be72, checked in by pawelk <pawelk@…>, 16 years ago

Pierwsza przymiarka do umieszczenia plikow w ~/.local/utt. Obsługa nowych opcji domyslnych. Nieskonczona dystrybucja tarball.

git-svn-id: svn://atos.wmid.amu.edu.pl/utt@41 e293616e-ec6a-49c2-aa92-f4a8b91c5d16

  • Property mode set to 100755
File size: 7.5 KB
Line 
1#!/usr/bin/perl
2
3#package:       UAM Text Tools
4#component:     mar
5#version:       1.0
6#author:        Marcin Walas
7
8#this program tags the tokenized file with given tags
9#tags can be given in any order and configuration through the expression
10#which is one of the parametres of the script
11#contact: d287572@atos.wmid.amu.edu.pl, walasiek@gmail.com
12
13use lib "/usr/local/lib/utt";
14use lib "ENV{HOME}/.local/lib/utt";
15
16use strict;
17use Getopt::Long;
18use File::HomeDir;
19
20use attr;
21
22
23my $LIB_DIR="/usr/local/lib/utt";
24my $systemconfigfile='/usr/local/etc/utt/mar.conf';
25my $userconfigfile=home()."/.utt/mar.conf";
26
27Getopt::Long::Configure('no_ignore_case_always');
28
29my $help=0;
30my $pattern=0;
31my $macrofile=0;
32my $define=0;
33my $command=0;
34my $action="pgP";
35my $eos="seg(EOS)";
36my $explicit_space=0;
37my $morfield='lem';
38my $tags=0;
39
40#read configuration files###########################
41my $file;
42foreach $file ($systemconfigfile, $userconfigfile){
43  if(open(CONFIG, $file)){
44        while (<CONFIG>) {
45                chomp;                 
46                s/#.*//;               
47                s/^\s+//;               
48                s/\s+$//;               
49                next unless length;     
50                my ($name, $value) = split(/\s*=\s*/, $_, 2);
51                if(($name eq "pattern")or($name eq "e")){
52                        $pattern=$value;
53                }
54                elsif($name eq "eos"){
55                        $eos=$value;
56                }
57                elsif($name eq "macros"){
58                        $macrofile=$value;
59                }
60                elsif($name eq "tags"){
61                        $tags=$value;
62                }
63                elsif($name eq "morph"){
64                        $morfield=$value;
65                }
66                elsif($name eq "command"){
67                        $command=1;
68                }
69                elsif($name eq "action"){
70                        $action=$value;
71                }
72                elsif($name eq "space"){
73                        $explicit_space=1;
74                }
75                elsif(($name eq "help")or($name eq "h")){
76                        $help=1;
77                }
78       
79        } 
80        close CONFIG;
81  }
82}
83#########################################################
84
85GetOptions("pattern|e=s" => \$pattern,
86           "eos|E=s" => \$eos,
87           "macros=s" => \$macrofile,
88           "define=s" => \$macrofile,
89           "command" => \$command,
90           "action=s" => \$action,
91           "help|h" => \$help,
92           "space|s" => \$explicit_space
93   );
94
95
96
97
98if($help)
99{
100    print <<'END'
101Usage: mar [OPTIONS] [file ..]
102
103Options:
104   --pattern -e PATTERN         Pattern.
105   --bos -E PATTERN             Segment serving as sentence beginning marker. [TODO]
106   --macros=FILE                Read macrodefinitions from FILE. [TODO]
107   --define=FILE                Add macrodefinitions from FILE. [TODO]
108   --action -a [p][s][P]        Perform only indicated actions.
109                                    p - preprocess
110                                    s - search
111                                    P - postprocess
112                                (default pgP)
113   --command                    Print generated shell command and exit.
114   --help -h                    Print help.
115
116In patern you can put any tag. Tags should begin with the @ character.
117They don't have to be closed.
118They can't contain white spaces!
119
120Note: If you don't define any custom tags, whole pattern will be taged with
121      default tags (begining of match and end of match)
122
123Tags examples:
124
125mar -e '@BEG cat(<ADJ>) @END'
126  it will find any adjectives in the text and tag them with surrounding tags
127mar -e 'cat(<ADJ>) @MYTAG cat(<ADJ>)'
128  this will find two neighbouring adjectives and parcel them with tag MYTAG
129
130Some example patterns:
131'word(domu)'  - form of the word domu
132'lexeme(dom)' - any form of lexeme dom
133'space'       - space
134'cat(<ADJ>)'  - adjective
135
136You can use * in patterns to make zero or more counts of word.
137
138END
139;
140    exit 0;
141}
142
143die("$0: no pattern given. Run with -h to get help.\n") unless $pattern || $action !~ /g/;
144
145die("$0: macro file not found") unless
146    $macrofile or
147    -e "$LIB_DIR/terms.m4" and $macrofile="$LIB_DIR/terms.m4";
148
149my $preproc    = ($action =~ /p/) ? ' fla  | '  : '';
150
151my $postproc   = ($action =~ /P/) ? ' | unfla '  : '';
152
153
154#this is our help function to  cut the re to get another tag
155#it takes only one argument which is our patern (after m4 processing)
156#returns: the first root-level brace with content
157sub cutRe
158{
159 my $i = 0;
160 my $level = 0;
161 my $text = $_[0];
162 my $temp;
163 for( $i =0; $i < (length $text);$i++)
164 {
165         $temp = substr($text, $i,1);
166         if( $temp eq "(")
167         {#we have an opening
168                 $level++;
169         }
170         elsif ( $temp eq ")")
171         {#we close
172                 $level--;
173         }
174         if ( $level == 0)
175         { 
176                $temp  = substr($text,0,$i+1);
177                last;
178         }
179 }
180 $temp;
181}
182
183#the same function as above althought it returns everything after the
184#first root level brace
185sub restRe
186{
187 my $i = 0;
188 my $level = 0;
189 my $text = $_[0];
190 my $temp;
191 for( $i =0; $i < (length $text);$i++)
192 {
193         $temp = substr($text, $i,1);
194         if( $temp eq "(")
195         {#we have an opening
196                 $level++;
197         }
198         elsif ( $temp eq ")")
199         {#we close
200                 $level--;
201         }
202         if ( $level == 0)
203         { #we cut everything in the begining
204                $temp  = substr($text,$i+1);
205                last;
206         }
207 }
208 $temp;
209}
210
211
212#here we are preparing re for extended matching
213my @tags;
214
215#we must find what our the tags
216#some pattern adjustment
217my $end = 0;
218my $temp = " ".$pattern." ";
219$temp =~ s/(\@[^ ]*) (\@[^ ]* )/\1  \2/g;
220$pattern = $temp;
221
222while ($end != 1)
223{
224        #we seek for the first tag in pattern
225 if ($temp =~ /^.*?\@(.*?) /)
226 {
227         #we add this to tags array
228         push (@tags, $1);
229         #and cut the pattern
230         $temp =~ s/^.*?\@(.*?) / /;
231         #print $temp."\n";
232 }
233 else
234 {
235         #if we dont find any tags we end
236         $end = 1;
237 }
238}
239
240#here we have our patern with tags removed (we set sections of ()) between tags
241my $patternmod = "( ".$pattern." )";
242$patternmod =~ s/\s@.*?\s/\)\(/g;
243
244#discarding spaces
245$patternmod =~ s/\s+/\\`'/g; #`
246# quoting escaped commas
247$patternmod =~ s/\\,/\\`\\`\\,''/g;
248# quoting commas in {m,n} r.e. operator
249$patternmod =~ s/(\{\d*),(\d*\})/\1\\`\\`,''\2/g;
250#print "After m4:".$re."\n";
251
252my $re = `echo \"$patternmod\" | m4 --define=ENDOFSEGMENT='[[:cntrl:]]' --define=MORFIELD=$morfield $macrofile - 2>/dev/null`;
253
254die("Incorrect pattern (m4).") if $? >> 8;
255
256
257chomp $re;
258
259# <> expansion
260
261$re =~ s/<([^>]+)>/`echo $1 | $tags.tag2re`/ge;
262
263# Perl-like special sequences
264$re =~ s/\./[^ [:cntrl:]]/g;
265$re =~ s/\\s/[ ]/g;
266$re =~ s/\\S/[^ [:cntrl:]]/g;
267$re =~ s/\\d/[0-9]/g;
268$re =~ s/\\D/[^0-9 [:cntrl:]]/g;
269$re =~ s/\\w/[a-z±æê³ñ󶌿A-Z¡ÆÊ£ÑÓŠ¬¯0-9_]/g;
270$re =~ s/\\W/[^a-z±æê³ñ󶌿A-Z¡ÆÊ£ÑÓŠ¬¯0-9_ [:cntrl:]]/g;
271# extensions
272$re =~ s/\\l/[a-z±æê³ñ󶌿]/g; #lowercase letter
273$re =~ s/\\L/[A-Z¡ÆÊ£ÑÓŠ¬¯]/g; #upercase letter
274
275my $sedcommand;
276my $grepcommand;
277
278#now we must built a sed script from our re
279#we do this by cuting our re each tag until we cut them all
280#if an user dint input any tags we do our default
281my $defBOM = "BOM";
282my $defEOM = "EOM";
283my $defTempTagBeg = "####TempTAGBEG####";
284my $defTempTagEnd = "####TempTAGEND####";
285
286if (@tags == 0)
287{
288        $sedcommand = "sed -r 's/($re)/\\500 $defBOM *\\f\\1###EOM###/g; s/###EOM###([0-9]+)/\\1 00 $defEOM *\\f\\1/g'";
289}
290else #we have custom tags
291{
292        #first tag is easy to tag :)
293        my $sedscript="sed -r 's/($re)/\\600 $defTempTagBeg *\\f\\1###EOM###/g;s/###EOM###([0-9]+)/\\1 00 $defTempTagEnd *\\f\\1/g;";
294    #after first step we have temp tagged parts of input matching re
295    #now we need to insert our custom tags
296    #we will find temp tags and process our input
297   
298        my $i = 0;
299        #copy of re which will be cut
300        my $rec = $re;
301        my $restre = $re;
302       
303        for ($i = 0 ; $i < @tags ; $i++)
304        {
305         #re cutting
306         $rec = cutRe($restre);
307         $restre = restRe($restre);
308         if ($rec =~ / *\( *\) */)
309         {
310            $sedscript = $sedscript."s/([0-9]+) 00 $defTempTagBeg \\*\\f([0-9]+)/\\2 00 $tags[$i] *\\f\\2 00 $defTempTagBeg *\\f\\2/g;";
311         }
312         else
313         {
314            $sedscript = $sedscript."s/[0-9]+ 00 $defTempTagBeg \\*\\f($rec)/\\1###EOM###/g;s/###EOM###([0-9]+)/\\1 00 $tags[$i] *\\f\\1 00 $defTempTagBeg *\\f\\1/g;";
315         }
316
317        }
318       
319        $sedcommand = $sedscript."s/[0-9]+ 00 $defTempTagBeg \\*\\f//g;s/[0-9]+ 00 $defTempTagEnd \\*\\f//g'";
320}
321
322if($command)
323{
324    print $sedcommand."\n";
325    exit 0;
326}
327exec $preproc.$sedcommand.$postproc;
Note: See TracBrowser for help on using the repository browser.