Заставь дурака богу молиться — он
и лоб расшибет.
Пословица
Меня зовут Дмитpий Кoтepoв. Честно говоря, я пишу статью во внезапном приливе альтруизма и сострадания ко всему живому на факультете ВМиК (если таковое еще осталось). Мне, в общем-то, все равно, будете ли вы следовать указаниям, приведенным в этой статье, или нет. Работаете вы в Far или в Windows Commander — да хоть в командной строке. Меня даже не волнует, прочитаете вы статью до конца, или запустите браузером в окно. Однако, если все же решитесь, прежде, чем импровизировать, пожалуйста, попробуйте все то, что тут описывается, слово в слово. В ЦК все-таки не дураки сидят. А у нас тут не ЦК.
Я также буду предполагать, что вы большую часть своего времени (свободного или как — это уж ваше персональное дело, каждый сходит с ума по-своему) проводите в Windows. Закостенелым пользователям Linux данная статья не адресована (пишите свою, если только сможете нормально настроить кодировку в Gnome).
О чем это я?.. Раз вы все еще тут, вероятно, вам повезло учиться на программистском потоке факультета ВМиК. Для тех, кто до сегодняшнего дня (а сегодня хэллоуин, 31 октября 2002 года) не ходил ни на один семинар по RSL (или вообще в первый раз слышит это магическое и до боли отвратительное сочетание букв), поясняю: RSL — это вот такая штука:
scheme
some
=
class
type
Vertex
= Text,
Edge = Vertex >< Vertex
>< Duration >< Nat,
RoadGraph
= Vertex-set ><
Edge-set,
value
empty:
Database = ( ({}, {}), {}
),
addVertex: Database ><
Vertex -~-> Database
addVertex (db,
newVert) is let ((V, E), sch)=db
in
((V union
{newVert}, E),
sch)
end
pre
let ((V, E), sch) = db in
all
x: Vertex :- x isin V /\ x ~=
newVert
end
/*
и т.д. до бесконечности */
end
Иначе не определишь.
Если вашей реакцией является вопрос: «А как это запустить?», то вот вам минус-балл на экзамене — это никак не запускается, оно просто существует. (По вопросу существования всего сущего просьба обращаться к Dee Mon-у, а то я вас совсем тут запутаю своими теориями.)
Следующий вопрос — где все это должно существовать. Пристегните
ремни, если хотите пережить ответ. Готовы?.. Ну так вот. На шестом этаже, не
доходя буквально самую чуточку (если смотреть сверху) до резиденции проф.
Смелянского, есть такой компьютерный класс. Правда, лично я бы назвал его
калькуляторным... нет, пылесным... или, лучше, керосиново-примусным классом, ибо
то, что там стоит, компьютером называли только с большой натяжкой, да и
то — во времена Архимеда (и только сам Архимед). Ну, в общем, там стоят
Сказать, что в этом самом raise на
По счастью, указанный редактор позволяет не только набирать код RSL внутри
себя, но и подгружать внешний текстовой файл — например, тот, который
приведен выше. Однако коварные разработчики и тут подложили нам, ничего не
подозревающим программистам, свинью: в случае, если файл содержит синтаксическую
ошибку (или если сплошная ошибка, этот ваш файл, содержит чуть-чуть правильного
кода), raise не говорит, на какой же именно строке он «заткнулся».
Таким образом, отладка «спецификаций» на
Тем не менее, если вы хотите сдать свое задание преподавателям, вам обязательно нужно будет впихнуть весь свой код в недра raise, а затем убедить проверяющего, что он (код, а не проверяющий) правилен не только синтаксически, но и логически тоже. (Впрочем, последнее обычно не составляет никакого труда.)
Я предлагаю строить эшелон обороны на двух фронтах. Писать и отлаживать
спецификации удобно Windows (а где ж еще, в примусе керосин закончился), а
запускать — с помощью специального скрипта на
Прежде всего скачайте вот эту программу — rsl2cpp.zip. В архиве один-единственный EXE-шник, который умеет проверять (и довольно неплохо — об этом ниже) синтаксис в исходных файлах. Самое главное, что программа показывает, в какой строке произошла ошибка! Вы должны запускать ее так:
rsl2cpp.exe -s ВашФайл.rsl
В каком редакторе набирать код?.. В общем-то, в любом. Однако учтите, что при использовании Far (который я тоже уважаю, но не настолько же...) вы будете вынуждены постоянно переключаться между окнами для проверки синтаксиса в только что дописанном фрагменте (подчас по 20 раз в минуту). Если вы накачиваете большой и безымянный пальцы (лежащие на Alt+Tab), а также бицепс правой руки (Enter), то на здоровье. Я же предлагаю воспользоваться гораздо более удобным редактором — EditPlus 2 (без комментариев). Вы можете легко настроить его на выполнение проверки синтаксиса по сочетанию Ctrl+1, и все не выходя из редактора:
После этого — редактируйте текст на здоровье, нажимая периодически Ctrl+1 для проверки, все ли вы делаете правильно. Рекомендую, кстати, вносить изменения мелкими порциями, каждый раз проверяя, не закралась ли ошибка.
Ничто не совершенно в этом мире, и ничто не мир в этом совершенстве. В любой программе имеются ошибки, и rsl2cpp.exe отнюдь не является исключением. Единственное, чnо можно сказать наверняка — для корректной спецификации rsl2cpp.exe выдает OK практически всегда. Если же имеются неточности, то программа может повести себя двояко:
Error: char* RSLAnalyzer::getCTOPName(SyntaxNode* op)#default
К счастью, такое сообщение «оно» выдает только в одном случае (определено экспериментально):scheme
some
=
class
type
T
= Text ><
Text
value
f:
T -> Bool
f((a,b)) is true /* ***
*/
end
f(x) is let (a,b)=x in true end
Понятно?.. Ну не любит он скалярные произведения — в скобках путается.
Нужно сказать, что в случае наличия в коде указанной ошибки там могут присутствовать также и ошибки другого типа (например, синтаксические). Вот программа, содержащая синтаксическую ошибку (10a — это не число), но, тем не менее, не ругающаяся на нее:
scheme
some
= class
type
T = Text ><
Text
value
f: T ->
Bool
f((a,b)) is
true,
N: Int = 10a /* тут ошибка!
*/
end
Однако это еще не все. У rsl2cpp.exe есть еще одна небольшая несовместимость с raise (на этот раз в обратную сторону). Она касается следующего кода:
f: Text ->
Bool
f(v) is
exists i:Nat :- i>0
Эта спецификация, прекрасно «работающая» в rsl2cpp.exe, дает ошибку в raise: вероятно, в последнем неправильно реализованы приоритет exists, и требуются скобки:
f: Text ->
Bool
f(v) is (
exists i:Nat :- i>0
)
Естественно, последний вариант работает также и в rsl2cpp.exe.
Наконец, ваш код (похожий на спецификацию, но это вы еще будете доказывать принимающим) проглатывается программой rsl2cpp.exe без ошибок. Пришло время записать его на дискетку, принести ее поближе к кабинету Смелянского (вам придется еще пробурить потолок, если вы захотите зайти в последний, ибо он на седьмом этаже) и залить керосин в примус. Проверьте:
Как видите, довольно много условий. Далее я приведу скрипт, который «чистит» исходники таким вот образом, а пока предположим, что все условия выполнены. Итак, что необходимо сделать, чтобы взять указанный файл с дискеты и запустить его в raise:
Но это еще не конец. Вы когда нибудь видели хакера? И я тоже не видел. И не потому, что «настоящий хакер невидим, как человек-невидимка, и неслышим, как немой человек-невидимка», а потому что...
Сейчас речь пойдет о скрипте, который запускается в Unix и:
Скрипт будет называться run (можно скачать тут) и лежать в вашей домашней директории. Открытие любых RSL-файлов станет предельно простым: ./run имя_файла.rsl.
#!/usr/local/bin/perl
-w
# Read source file at all.
$ARGV[0] or
die "Usage: $0 <file-name>\n";
open(local *F, $ARGV[0]) or die "Could
not open $ARGV[0]!\n";
binmode(F); local $/; $_ = <F>;
# Class name - temporary.
my $cls = "cls".time();
my
$dir = "./tmp"; mkdir($dir,0770);
# Clean
source.
s{\r}{}sg;
s{/\*.*?\*/}{}sg;
s{\S+ (\s* = \s*
class)}{$cls$1}sxi;
# Write the file.
my
$fname = "$dir/$cls.rsl";
open(local *F, ">$fname") or die "Could not
write $fname!\n";
binmode(F); print F $_;
close(F); #
always close before system()!
# Run
RAISE.
system("raise $fname &") or die "$!\n";
Не забудьте поставить атрибут на выполнение для файла:
chmod +x run