#!/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);
