gudleifr писал(а):
ТРЕТЬЕ ПРАВИЛО INCUBASIC:
Избыточность однотипных вторичных машин может быть локализована в виде одинакового набора слов в СЛОВАРЕ
Иллюстрация - попытка написать на Perl семейство автоматов, читающих тексты одного и того же формата, но обрабатывающего их по-разному. Добавляя разные массивы "p" к заранее размеченному словарю "состояние.символ", надеюсь реализовать все необходимые операции.
Код:
#!/usr/bin/perl
# МАШИНА: СОСТОЯНИЕ => [[СИМВОЛ, СОСТОЯНИЕ, СДВИГ], ...]
%stats = (Garbage => [["^\\\\", "Path", 0], [0, 0, 1]],
Path => [["^\$", "Param", 1], ["^. ", "Param", 0],
["^\\\\", 0, 1], ["^ТЕКСТ", "Text", 1],
["^ТАБЛИЦА", "Header", 1], ["^ЗАПИСИ", "Header", 1],
[0, "Garbage", 0]],
Header => [["^\$", "Text", 1], [0, 0, 1]],
Text => [["^\$", "Param", 1], [0, 0, 1]],
Param => [["^. ", 0, 1], ["^\\\\", "Path", 0],
["^\$", "Garbage", 1], [0, "Garbage", 0]]);
# СЧИТЫВАНИЕ СИМВОЛА, ЕСЛИ ОН ЕЩЕ НЕ БЫЛ СЧИТАН
sub ready {
$reading = <FI> unless $reading;
return 0 unless $reading;
$reading =~ s/\s*\r?\n//;
return 1
}
# ОДИН ТАКТ РАБОТЫ
sub step {
my $l = $stats{$state}; # СОСТОЯНИЕ
foreach (@$l) {
my $s = $_->[0]; # СИМВОЛ
if (!$s or $reading =~ /$s/) {
$p->{$state . $s}() if exists $p->{$state . $s}; # ВЫВОД
$state = $_->[1] if $_->[1]; # НОВОЕ СОСТОЯНИЕ
$reading = 0 if $_->[2]; # СДВИГ
return
}
}
}
# ФУНКЦИИ ВЫВОДА: СОСТОЯНИЕ.СИМВОЛ
$p1 = {"Garbage^\\\\", sub {
print "Garbage-Path:", $reading, "\n"
},
"Param^\\\\", sub {
print "Param-Path:", $reading, "\n"
},
"Garbage0", sub {
print "Garbage:", $reading, "\n"
}};
# СЧИТЫВАЕМ ЛЕНТУ (ФАЙЛ)
$s = shift @ARGV;
$s .= ".txt";
$p = $p1;
open FI, $s;
$reading = 0;
$state = "Garbage";
step() while ready();
close FI