ПЕРЕВОД ДОКУМЕНТАЦИИ БИБЛИОТЕКИ ЧИСЛЕННОГО АНАЛИЗА НИВЦ МГУ

ДЛЯ ЯЗЫКА ФОРТРАН В ДОКУМЕНТАЦИЮ ДЛЯ ЯЗЫКА СИ

 

 

Постановка задачи.

В Библиотеке Численного Анализа НИВЦ МГУ (www.srcc.msu.su/num_anal/) помещены описания библиотечных программ на языке ФОРТРАН. В связи с переводом программ на язык Си, возникла необходимость сделать подобные описания для языка Си, причем исходя из существующего описания на языке ФОРТРАН. Документ, описывающий программу, состоит из нескольких разделов: 'Программа: <имя п/п>', 'Назначение', 'Математическое описание', 'Использование', 'Параметры'. 'Версии', 'Вызываемые программы', 'Замечания по использованию', 'Пример использования', структуру и особенности которых при переводе документации надо учитывать. Кроме этого следует учесть, что документация предназначена для просмотра в Интернете и написана с использованием тегов языка HTML. В результате этих особенностей задача перевода документации включила в себя следующие основные пункты:

 

-

перевод всех идентификаторов (кроме раздела 'Математическое описание') и имен всех встречаемых программ на нижний регистр, причем задача усложняется тем, что часть букв верхнего регистра, совпадающая по написанию с русскими, имеет русскую кодировку;

-

добавление к именам программ окончаний для имен версии Си:  c_  ; например, имя AM01R заменяется на имя am01r_c ;

-

поиск и замена в разделе 'Использование' первого оператора обращения к программе на языке ФОРТРАН на оператор, который ищется контекстным поиском и выделяется из текста программы на языке Си;

-

поиск и замена в разделе 'Пример использования' теста к программе на языке ФОРТРАН на соответствующий тест на языке Си; при этом операторы теста в разделе могут быть обрамлены произвольными пояснительными строками, которые при поиске должны быть разграничены с тестом;

-

в тексте может быть приведен вид первого оператора обращения к версии программы или к подпрограмме, приложенной к тесту, на языке ФОРТРАН, который заменяется на соответствующий оператор языка Си, найденный в каталоге программ на Си;

-

операторы и тесты программ на языке Си представлены в каталогах в виде заархивированных zip-файлов, поэтому перед началом работы с файлом документации все файлы надо разархивировать;

-

в силу особенностей определенных разделов должен существовать механизм, обеспечивающий контекстные преобразования только в указанном разделе или группе разделов.

 

 

Способ реализации.

Для выполнения этой задачи создан сценарий, основные пункты которого описываются ниже с приведением подробных комментариев:

 

1. Запись в первую ячейку общего архива  {{1}} тега  <pre>

 

2. Запись во вторую ячейку общего архива {{2}} тега  </pre>

 

Цикл по основным каталогам поиска (цикл охватывает пункты 3 – 22):

#ЦИКЛ:1?d:\docci\listcat.txt

 

Вся исходная документация разбита на серию подкаталогов: am, pa, sf и др., определяющих отдельные разделы документации. Имена подкаталогов соответствуют начальным символам имен программ, находящимся в этом подкаталоге и содержат пять символов, последний из которых определяет версию программы (например, AM02D, SF60R). Файл цикла d:\docci\listcat.txt состоит из строк с именами этих подкаталогов и участвует в организации цикла 1. Соответствующие этим подкаталогам программы на языке Си находятся в подкаталогах с именами am_c, pa_c, sf_c и др., а тесты - в подкаталогах с именами tam_c, tpa_c, tsf_c и др.

 

3. Создание левого списка по файлам каталога цикла (например, из подкаталога am) c расширением .htm

 

4. Добавление в левый список файлов из подкаталога Библиотеки  d:\num_anal\lib_na\cat\&1 _c\ (например, из подкаталога am_c). В этом подкаталоге находятся zip-файлы программ на Си из раздела, имя которого формируется после подстановки первой лексемы &1  текущей строки файла  d:\docci\listcat.txt, организующего цикл 1.

 

5. Добавление в левый список файлов из подкаталога Библиотеки  d:\num_anal\lib_na\cat\t&1 _c\ ( например, из подкаталога tam_c ). В этом подкаталоге находятся zip-файлы тестов на Си из раздела, имя которого формируется после подстановки первой лексемы &1  из текущей строки файла  d:\docci\listcat.txt, организующем цикл 1.

 

6. Создание рабочего каталога files_&1 . В этот каталог в дальнейшем соберем все распакованные файлы, которые будут использоваться для перекодировки соответствующего раздела документации.

 

7. Перепись файлов левого списка в каталог files_&1 .

 

8. Создание правого списка zip-файлов из каталога files_&1 ( например, files_am ) и запись этого списка в файл d:\docci\tmp\listzip.txt. Этот файл будет использован для организации внутреннего цикла распаковки zip-файлов.

 

9. Цикл распаковки zip-файлов через запуск внешнего процесса:

#ЦИКЛ:2?d:\docci\tmp\listzip.txt

 

Завершение цикла 2:

#КОНЕЦ:2

 

10. Удаление zip-файлов правого списка из каталога files_&1  после распаковки.

 

11.Создание правого списка htm-файлов из каталога files_&1  и запись списка в файл d:\docci\tmp\listhtm_&1 .txt (например, создали файл listhtm_am.txt, содержащий файлы Am00r.htm, Am01r.htm и др.).

 

12. Редактирование файла listhtm_&1 .txt, используя таблицу контекстов:

 

Контекст поиска:

Контекст замены:

Комментарий:

{?*~[.]}{.htm}

#[{1} & {2} & " " & {1} & "_c.c t" &

    {1} & "_c.c"//{0}]

Формирование строк вида (f - имя файла):

f.htm  f_c.c  tf_c.c

 

Цикл 3 по созданному на предыдущем этапе файлу (цикл охватывает пункты 13 – 18):

#ЦИКЛ:3?d:\docci\tmp\listhtm_&1|1 .txt

 

13. Запись в третью ячейку общего архива {{3}} обращения к п/п с параметрами на Си из файла d:\docci\files_&1|1 \&2 . Здесь каталог определяется первой лексемой файла цикла 1, а имя файла - второй лексемой текущего цикла 3. Это действие выполняет контекстное преобразование:

 

Контекст поиска:

Контекст замены:

Комментарий:

%%{&1|1 ???_c(}|{&1|1 ????_c(}

 

Начало блока:  имя п/п, начинающееся с имени каталога, плюс 3 или 4 произвольных символа (дополнение до 5 символов исходного имени) плюс стандартное окончание имени _c.

$${%@{}

 

Конец блока: { в начале строки.

%$

#[BlockOper(save,{10},

   {{3}},1..-2)]

Запись блока без последней строки { в третью ячейку архива.

 

14. Запись в четвертую ячейку архива {{4}} теста на языке Си из файла d:\docci\files_&1|1 \&3 . Здесь каталог определяется первой лексемой файла цикла 1, а имя теста - третьей лексемой текущего цикла 3. Это действие выполняет контекстное преобразование:

 

Контекст поиска:

Контекст замены:

Комментарий:

%%{main(void)}

 

Начало блока: заданный контекст.

$$$

 

Конец блока: конец файла.

%$

#[BlockOper(save,{10},

   {{4}},1..-1)]

Запись блока в четвертую ячейку архива.

 

15. Изменение прописных букв на строчные в именах программ и идентификаторах, включая замену русских букв, одинакового с латинскими написания, на латинские. Контекстные преобразования разделены на блоки, относящиеся к определенным разделам документации (приводится фрагмент):

 

Контекст поиска:

Контекст замены:

Комментарий:

|1|%%<hr>

 

Начало блока 1

|1|{[АВЕКМНОРСТХУ

    A-Z]+[АВЕКМНОРС

    ТХУA-Z0-9]*[ |,|.|;|:|&|

   (|)|=|@+|@-|*|<|!|@}|^]}

#[BlockEdit(selcn,sysfile1,

   _{1}..{1}_)]

Формирование системного файла sysfile1 с диапазонами имен п/п и идентификаторов, подлежащих переводу (поиск проводится по списку возможных прописных русских букв и диапазону латинских букв), последний перечень символов определяет допустимые символы, ограничивающие имена и идентификаторы.

|1|$${<h3> *

        Математическое

        описание}

 

Конец блока 1

|1|%$

#[BlockConv({10},,sysfile1,

eneq,dn)]

Функция перевода символов с использованием созданного в блоке системного файла sysfile1 .

|1|%$

#[BlockOper(retn)]

Сдвиг по входному файлу на одну строку вверх (чтобы повторить чтение конечной строки этого блока).

|2|%%{<h3> *

           Математическое

           описание}

 

Начало блока 2

|2|{[АВЕКМНОРСТХ

      A-Z][АВЕКМНОРСТХ

      A-Z][АВЕКМНОРСТХ

      A-Z0-9][АВЕКМНОРС

      ТХA-Z0-9][СCRD]}

#[BlockEdit(selcn,sysfile1,

   _{1}..{1}_)]

Формирование системного файла sysfile1 с диапазонами имен п/п.

|2|$${<h3> *

         Использование}

 

Конец блока 2.

|2|%$

#[BlockConv({10},,sysfile1,

  eneq,dn)]

Функция перевода символов с использованием созданного в блоке системного файла sysfile1 .

 

16. Добавление к именам п/п окончания _c . Контекстные преобразования разделены на блоки, относящиеся к определенным разделам документации (приводится фрагмент):

 

Контекст поиска:

Контекст замены:

Комментарий:

|1|%%<hr>

 

Начало блока 1

|1|{[a-z][a-z][a-z0-9]

     [a-z0-9][rdci][ |.|)|,|(]}

#[{1}|1..-2 & "_c" &

   {1}|-1..-1 //{1}]

Выделение из найденной группы символов имени п/п (последний символ группы не включается) и присоединение к нему _c и конечного символа группы ( например, из имени Am01r формируется имя Am01r_c ).

|1|$${<h3> *

    Использование}

 

Конец блока 1

|1|%$

#[BlockOper(repl,{10},

  {10})]

Запись отредактированного блока  в выходной файл.

|2|%%{<h3> *Параметры}

 

Начало блока 2

|2|{[a-z][a-z0-9]* }{ *@-$}

 

Идентификаторы параметров не изменяются.

|2|{[a-z][a-z][a-z0-9]

     [a-z0-9][rdci][ |.|)|,|(]}

#[{1}|1..-2 & "_c" &

   {1}|-1..-1 //{1}]

Добавление к имени п/п окончания _c .

|2|$${<h3> *Версии}

 

Конец блока 2.

|2|%$

#[BlockOper(repl,{10},

   {10})]

Запись отредактированного блока  в выходной файл.

 

17. Замена содержимого раздела 'Использование' на обращение к п/п на Си и содержимого раздела 'Пример использования' на тест к п/п на Си. Эти действие выполняются контекстными преобразованиями:

 

Контекст поиска:

Контекст замены:

Комментарий:

|1|%%<h3> *

   Использование

 

Начало блока 1

|1|$${%\0d\0a}

 

Конец блока 1 (пустая строка - в начале строки стоят коды #13#10 ).

|1|%$

#[BlockOper(repl,{{3}},

   {10},,2..-2,False)]

Содержимое третьей ячейки общего архива замещает строки блока редактирования от второй до предпоследней, без записи блока в выходной файл (ключ False ).

|1|%$

#[BlockOper(insb,{{2}},

   {10},,-1,False)]

Перед последней строкой блока вставляется содержимое второй ячейки общего архива ( </pre> ) без записи блока в выходной файл (ключ False ).

|1|%$

#[BlockOper(insb,{{1}},

   {10},,2)]

Перед второй строкой блока вставляется содержимое первой ячейки общего архива ( <pre> ) и блок записывается в файл.

|2|%%{<h3> *Пример

        использования}

 

Начало блока 2

|2|{% +[АВЕКМНОРСТ

ХУA-Z][АВЕКМНОРСТ

ХУA-Z0-9]* }

#[BlockEdit(selsp,sysfile)]

Формирование системного файла sysfile, содержащего номера min и max строки блока с оператором языка ФОРТРАН (для строк теста, начинающихся с идентификатора).

|2|{% +[0-9]+ +[АВЕКМН

    ОРСТХУA-Z]}

#[BlockEdit(selsp,sysfile)]

Формирование системного файла sysfile, содержащего номера min и max строки блока с оператором языка ФОРТРАН (для строк теста, начинающихся с цифровой метки).

2|$${% *Результат}

 

Конец блока 2.

|2|%$

#[BlockOper(repl,{{4}},

   {10},,&1|sysfile ..

   &2|sysfile )]

Замена в блоке диапазона строк, взятого из первой и второй лексем системного файла sysfile, на содержимое четвертой ячейки общего архива .

 

18. Замена в обращений к первым операторам п/п на языке ФОРТРАН  subroutine fname( … )  на их аналог на языке Си (п/п может быть версией исходной п/п и ее следует искать непосредственно в каталоге files_&1|1  под именем fname_c.c, или содержаться в тесте исходной п/п и ее следует искать в том же каталоге под именем &3|3 , находящимся в третьей лексеме файла цикла 3). Эти действия выполняются контекстными преобразованиями:

 

Контекст поиска:

Контекст замены:

Комментарий:

|1|%%{subroutine}{[a-z]+

[_a-z0-9]*[ |&|(]}{?*)}

#[{2}|1..-2//{{5}}]

Начало блока 1: имя п/п выделяется из второй группы (без последнего граничного с именем символа) и записывается в ячейку пять общего архива.

|1|$$

 

Конец блока 1: строка совпадает с началом блока, т.к. закрывающая скобка списка параметров находится в этой же строке.

|1[file=d:\docci\files_&1|1 \{{5}}.c

:: file=d:\docci\files_&1|1 \&3|3 ] |

%$

#[BlockFile(extr,sysRcond,

{10},"int {{5}}"::"real

{{5}}",")","subroutine",")") ::

BlockFile(extr,sysRcond,

{10},"%int {{5}}_c"::"%real

{{5}}_c",")","subroutine",")")]

Системная переменная sysRcond формируется в процессе проверки блокового условия и содержит имя файла, по которому будет производиться поиск контекстов; по номеру выполненного условия выбирается блоковая функция для работы с эти файлом, производится поиск контекста по заданным граничным условиям и запись его в блок.

|2|%%{subroutine}

   {[a-z]+[_a-z0-9]*[ |&|(]}

#[{2}|1..-2//{{5}}]

Начало блока 2: имя п/п выделяется из второй группы (без последнего граничного с именем символа) и записывается в ячейку пять общего архива.

|2|$${)}

 

Конец блока 2: строка не совпадает с началом блока, т.к. закрывающая скобка находится в другой строке.

|2[file=d:\docci\files_&1|1 \{{5}}.c

 :: file=d:\docci\files_&1|1 \&3|3 ]|

%$

#[BlockFile(extr,sysRcond,

{10},"int {{5}}"::"real

{{5}}",")","subroutine",")") ::

BlockFile(extr,sysRcond,

{10},"%int {{5}}_c"::"%real

{{5}}_c",")","subroutine",")")]

Контекстные преобразования аналогичные преобразования блока 1.

 

Завершение цикла 3:

#КОНЕЦ:3

 

19. Создание левого списка файлов htm-файлов каталога d:\docci\cat\&1|1 \  (например, для подкаталога am).

 

20. Создание правого абстрактного списка htm-файлов каталога d:\docci\cat\&1|1 \ с добавлением к именам файлов окончания _c .

 

21. Переименование файлов из левого списка в правый (например, Am00r.htm в Am00r_c.htm ).

 

22. Перевод имен файлов на нижний регистр в каталоге d:\docci\cat\&1|1 \  (например, . Am00r_c.htm в am00r_c.htm ).

 

Завершение цикла 1:

#КОНЕЦ:1

 

Полный текст сценария:  teconv.srcc.msu.ru/resurs/docscrpt.html

 

Иллюстрация  перекодировки документации для  программ SF60R  и  sf60r_c :