anonym_mouse (anonym_mouse) wrote,
anonym_mouse
anonym_mouse

"Литературное программирование" Кнута - пример

.
ЛЛИТЕРАТУРНОЕ ПРОГРАММИРОВАНИЕ
объяснение на одном примере

Предыдущий мой пост (в ru_programming) был, наверно, слишком общим и заставил читателей гадать и представлять себе зверя, которого никто раньше не видел (вспомните средневековые рисунки бегемотов)

Для примера давайте рассмотрим HTML-документ созданный из одного классического примера - микро-программы для подсчета букв, слов и строчек в файле, юникс "wc" utility. Пример создан на программе "noweb".

An Example of noweb

Norman Ramsey
Dept. of Computer Science, Princeton University
Princeton, NJ 08544

Contents

Introduction

The following short program illustrates the use of noweb, a low-tech tool for literate programming. The purpose of the program is to provide a basis for comparing WEB and noweb, so I have used a program that has been published before; the text, code, and presentation are taken from Chapter 12 of D. E. Knuth, Literate Programming (volume 27 of Center for the Study of Language and Information Lecture Notes, Stanford Univ., 1992).


Выпустим кусок текста, который написан как эссе, или объяснение, или "мысли во время программирования" - вскрывая логику, т.е. не документ пытающийся после создания программы как-то преставить её той или иной аудитории.

Интересное начинается ниже.
Заметьте, как авторы программы пишут кусок программного текста вставляя в него строчки-заголовки, на самом деле строчки, описывающие смысл выпущенного куска, и "сворачивающие" текст программы, позволяя читателю увидеть главное, о котором речь идет сейчас.


Строчки, служащие заголовками будут раскрыты в другом месте, они - ссылки, а ссылки "используется" и "определение" под отрывком дают возможность читателю увидеть целое.
Не надо понимать так, что это обычные гиперссылки в документации. НЕТ. Главная идея в том, что вы программируете в логическом, выбранном вами порядке, а utilities создадут из него верный исходник, правильный для компилятора или интерпретатора.
Другими словами, программу можно писать в логической последовательности, а не в последовательности предписанной правилами языка.

Now we come to the general layout of the main function.
<The main program>=
main(argc, argv)
  int argc;
    /* number of arguments on UNIX command line */
  char **argv;
    /* the arguments, an array of strings */
{
  <Variables local to main>
  prog_name = argv[0];
  <Set up option selection>
  <Process all the files>
  <Print the grand totals if there were multiple files>
  exit(status);
}
Used above.

If the first argument begins with a `-', the user is choosing the desired counts and specifying the order in which they should be displayed. Each selection is given by the initial character (lines, words, or characters). For example, `-cl' would cause just the number of characters and the number of lines to be printed, in that order.

We do not process this string now; we simply remember where it is. It will be used to control the formatting at output time.

<Variables local to main>=
int file_count;
  /* how many files there are */
char *which;
  /* which counts to print */
Used above; next definition.

<Set up option selection>=
which = "lwc";
  /* if no option is given, print 3 values */
if (argc > 1 && *argv[1] == '-') {
  which = argv[1] + 1;
  argc--;
  argv++;
}
file_count = argc - 1;
Used above.

Теперь - следующая важная черта. Слишком часто приходится держать в уме слишком много. Например, на языке Ц определения переменных или includes приходится дописывать в начало файла.
"Литературное программирование" позволяет добавлять к уже существующим секциям, из любых мест в файле, где по логике добавления возникают. Заметьте "плюсики" в заголовках в отрывке ниже: мы дописываем в уже существующие и определенные куски те части, которые по логике возникли только сейчас

Now we scan the remaining arguments and try to open a file, if possible. The file is processed and its statistics are given. We use a do ... while loop because we should read from the standard input if no file name is given.
<Process all the files>=
argc--;
do {
  <If a file is given, try to open *(++argv); continue if unsuccessful>
  <Initialize pointers and counters>
  <Scan file>
  <Write statistics for file>
  <Close file>
  <Update grand totals>
    /* even if there is only one file */
} while (--argc > 0);
Used above.

Here's the code to open the file. A special trick allows us to handle input from stdin when no name is given. Recall that the file descriptor to stdin is 0; that's what we use as the default initial value.

<Variables local to main>+=
int fd = 0;
  /* file descriptor, initialized to stdin */
Used above; previous and next definitions.

<Definitions>+=
#define READ_ONLY 0
  /* read access code for system open */
Used above; previous and next definitions.

<If a file is given, try to open *(++argv); continue if unsuccessful>=
if (file_count > 0
&& (fd = open(*(++argv), READ_ONLY)) < 0) {
  fprintf(stderr, 
    "%s: cannot open file %s\n",
    prog_name, *argv);
  status |= cannot_open_file;
  file_count--;
  continue;
}
Used above.

И, наконец, программа автоматически создает индекс всех ваших "заголовков" (т.е. логических кусков текста которые вы выделили и в собственном порядке описали в "литературной программе"),
а также - тех переменных, которые вы пометили как нужные для индексирования.

Я привел лишь 4 отрывка из всего текста, поэтому не все ссылки будут работать - но те, которые включены в эти отрывки будут. Можете попробовать. "D" изначает "определение", definition, а "U" - использование, usage.

Index

Chunks

"D" means "defined" , peice by piece
"U" means "used in", again numbered by instance of use

Identifiers


Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 2 comments