#!/usr/local/bin/perl #-d # чтение шаблонов open (WORDS, "words.sbl") || die "Can't open file words.sbl"; my ($num ) = 0; # Количество переменных my ($count) = 0; # Счетчик для @expr my ($rules) = 0; # Количество правил my ($curr ); # Текущая строка для разбора my (@enter); # Точки входа в правила my (@expr ); # Правила while (<WORDS>) { $curr = $_; @enter [$rules++] = $count; tr /АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ/абвгдеёжзийклмнопрстуфхцчшщъыьэюя/; s /[\r\n]//g; while (/.*(\"(.*)\").*/) # Строки в кавычках { @expr [$count++] = 'w'; @expr [$count++] = $2; s /$1/<$num>/imx; $num++; } while (/([абвгдеёжзийклмнопрстуфхцчшщъыьэюя]+)/) # Слова { @expr [$count++] = 'w'; @expr [$count++] = $1; s /$1/<$num>/imx; $num++; } s/[\s\t]//g; next if length == 0; while ($_ !~ /^<(\d+)>$/) # Пока строка не свернется в число { if (/\(<(\d+)>\)/) # Если число в скобках { $tmp = $1; s/\(<$tmp>\)/<$tmp>/imx; } elsif (/!<(\d+)>/) # Если инверсия { @expr [$count++] = 'n'; @expr [$count++] = $1; s/!<$1>/<$num>/imx; $num++; } elsif (/(<(\d+)>&?<(\d+)>)/) # Если операция "И" { @expr [$count++] = 'a'; @expr [$count++] = $2; @expr [$count++] = $3; s/$1/<$num>/imx; $num++; } elsif (/<(\d+)>\|<(\d+)>/) # Если операция "ИЛИ" { @expr [$count++] = 'o'; @expr [$count++] = $1; @expr [$count++] = $2; s/<$1>\|<$2>/<$num>/imx; $num++; } else { printf "Error in expression $curr\n\n"; exit (1); } } @expr [$count++] = 'e'; # Конец правила @expr [$count++] = $num - 1; } close (WORDS); printf "\n\n"; #******************************************************************** # Здесь задается файл с текстом. Все абзацы написаны в одну строку. open (FILE, "Bushkov.txt") || die "Can't open file"; while (<FILE>) { $string = $_; my (@rules); $num = 0; tr /АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ/абвгдеёжзийклмнопрстуфхцчшщъыьэюя/; foreach $i (0..$rules - 1) { $curr = @enter [$i]; while (true) { $command = @expr [$curr++]; if ($command eq 'e') # Рассшифровка команд { printf " $string\n" if (@rules [@expr [$curr]]); last; } elsif ($command eq 'w') { $word = @expr [$curr++]; if (/$word/imx) { @rules [$num++] = 1; } else { @rules [$num++] = 0; } } elsif ($command eq 'n') { @rules [$num++] = !@rules [@expr [$curr++]]; } elsif ($command eq 'a') { $first = @rules [@expr [$curr++]]; $second = @rules [@expr [$curr++]]; @rules [$num++] = $first && $second; } elsif ($command eq 'o') { $first = @rules [@expr [$curr++]]; $second = @rules [@expr [$curr++]]; @rules [$num++] = $first || $second; } else { printf "Critical error in code"; exit 2; } } } } close (FILE); exit (0);