Программа АВ (Algorithms Builder) V 1.10, от 20.12.2009 находится на стадии тестирования 1. Общие замечания и форматы представления блок-схем в АВ Замечание для программеров, говорящих: "Мы можем программировать и без всяких там блок-схем и прочих рисуночков и диаграмок". Если вы хотите, чтобы в тексте вашей программы разобрался кто-нибудь еще, кроме вас, то какие-то пояснения к тексту программы вам все же написать придется. Проанализировав формат файла *.drt на предмет возможности редактирования его "вручную" и мои возможности программиста (никогда не заявлял, что я - крутой программер), я решил по-быстрому написать генератор кода для С из блок-схем с использованием уже написанной мной раньше программы АВ. В результате внесенных в АВ изменений стала возможной генерация из АВ файлов исходного кода на С/С++, паскале и и других языках (в том числе русскоязычных), в состав которых входит классический goto. Эти файлы - не какие-то шаблоны, а полноценные исходники, которые можно подключать к проекту и сразу же компилировать. Задав в конфигурации АВ для файлов исходного кода рабочий каталог программного проекта и сгенерировав исходник, а затем перейдя в окно среды программирования, увидим там вопрос типа: "Файл *** изменен. Загрузить его ?". Отвечаем "Да" и запускаем его на компиляцию. Визуальный язык блок-схем (далее ВЯЗ БС) программы АВ изображает БС в вертикальном порядке, одну под другой, и позволяет задавать и просматривать дерево БС, образующееся при написании программы. Пока изображения БС псевдографические, но в будущем возможен переход на графическое отображение БС. Поскольку ВЯЗ БС по логике изображения БС отвечает основному требованию ДРАКОНа: "желательно все логически связанные блоки располагать на одной вертикали", то можно считать ВЯЗ БС неким сильно упрощенным подмножеством ДРАКОНа, т.е. маленьким дракончиком. Формат текстового представления БС в АВ прост. Он состоит из последовательно размещенных друг за другом описаний БС и строится из двух блоков описания данных: описателя заголовков БС и описателя действий БС. Описатели данных отделяются друг от друга пустыми строками. Формат описателя заголовка: :.<индекс заголовка>. текстовая строка 1 текстовая строка 2 ... текстовая строка N --------------------- процедурная строка 1 ... процедурная строка N Максимальное количество строк заголовка, отображаемое на БС, равно 10. Максимальное число процедурных строк заголовка не ограничено. Формат описателя действия: .<индексная строка действия> текстовая строка 1 ... текстовая строка N ------------------- процедурная строка 1 ... процедурная строка N Максимальное количество текстовых строк действия равно 10. Максимальное количество процедурных строк действия не ограничено. Индексная строка действия редактируется автоматически и при вводе нового действия ограничиваемся тем, что ставим точку в первой колонке этой строки. Процедурные строки заголовка и действий на БС не отображаются и доступны для просмотра в окне редактирования текстового представления БС. Процедурные строки заголовка и действий представляют собой языковые конструкции, без изменений помещаемые в исходный файл (исключение - задаваемый, если нужно, в последней процедурной строке заголовка оператор выхода из процедуры с параметром, подробнее см. ниже, в описании ab.cfg). Если у БС есть только заголовок и нет ни одного действия, тело процедуры для нее не генерируется. Максимальное число действий для БС равно 200. Максимальное число строк БС равно 700. Максимальное число БС в файле текстового задания БС равно 200. Максимальное число файлов текстового задания БС, с которыми может одновременно работать АВ равно 15. В АБ ширина поля ввода для задания и редактирования текстов БС и действий равна 40 символам. На замечание, что почему поле ввода такое маленькое, надо бы побольше, отвечу. Я предполагаю, что действия БС - это или вызовы процедур, или несколько сравнительно компактных операторов. Если вам нужно запрограммировать что-нибудь громоздкое и с таким форматированием текста, которое вам удобно, то создайте свою процедуру в другом модуле и делайте там, что хотите. А в сгенерированном модуле будет только вызов этой процедуры. Для вызова окна редактирования текста БС из окна просмотра БС нужно щелкнуть мышью по нужной БС, а затем нажать кнопку "Ред." или клавишу F4. В АВ есть возможность открытия до 4-х окон редактирования текстов БС (окна выбираются и открываются одно за другим). Переход к нужному окну - Alt+<номер окна редактирования> 2. Файл ab.cfg Ниже приводится примерный текст файла ab.cfg: ; файлы задаются тройками ; 1) файл текстового описания блок-схем ; 2) файл псевдографических блок-схем (ПГА) ; 3) файл генерируемого исходного текста (Прг.) ; d:\wrk_comp\dima_f\bcb\ab\temp.txt d:\wrk_comp\dima_f\bcb\ab\temp.pga d:\wrk_comp\dima_f\bcb\ab\temp.prg ; d:\wrk_comp\dima_f\bcb\ab\test11.txt d:\wrk_comp\dima_f\bcb\ab\test11.pga d:\wrk_comp\dima_f\bcb\test1\test11.cpp --------------------------- ; ; задание ключевых слов и символов для языка, на котором ; будет сгенерирован код ; ; генерация возможна для классических языков типа C/C++ ; и паскаля, имеющих традиционный оператор goto ; ; язык может быть и русскоязычным ; ; ; " " или "значение" ; _комментарий "//" _конец_оператора ";" __если "if" __иначе "else" _если_отрицание "!" ; в паскале это "not" _начало_метки "m_" _конец_метки ":" _метка_выхода "end" ; без начала метки _декларация_меток " " ; в паскале это label _оператор_перехода "goto" ; в паскале это "then goto" _конец_если_перед_иначе ";" ; в паскале это " " ; ; т.е. if (usl) act1 else act2; ; _начало_процедуры " " ; в паскале это "begin" _окончание_процедуры "}" ; в паскале это "end" _выход_с_параметром "return" ; в паскале это " " . По поводу выхода с параметром. Если последняя из процедурных строк заголовка, отделенных минусами, имеет вид - <выход_с_параметром> параметр <конец_оператора> то она будет воспринята генератором кода в качестве выходной строки, если, конечно, выход_с_параметром не определен как " ". 3. Пример файла текстового описания БС test11.txt :.1. common defs. ------------------ #include #pragma hdrstop // #include #include #include #include #include "Unit1.h" // char str1[100], str2[100], str3[100]; :.2. proc 1 --------------- void proc_1(char *stro, int a, int b, int c, int d) { char s1[20], s2[20], s3[20]; int res; ..1 сложение ----------- res = a+b+c+d; ..2 перевод в строку ---------------- itoa(res, stro, 10); :.3. proc 2 --------------- void proc_2(char *stro, int *a, int *b) { ..1 а из строки ------------- *a = atoi(stro); ..2 b = a*10 ---------- *b = (*a)*10; :.4. proc 3 --------------- void proc_3(char *stro, int c, int d) { ..1 c = d + 10 ----------- c = d + 10; :.5. proc 4 --------------- void proc_4(char *stro, int c, int d) { ..1 задание строки -------------- itoa(c+d, stro, 10); :.6. func 5 ------------------ int div_5(int a, int b) { int ot; - return ot; ..1 деление ---------- ot = (a/b); :.7. func 6 ------------------ char * add_str_6(int a, int b) { char *uch = str2; - return uch; ..1 add ------------------- itoa(a+b, uch, 10); :.8. func 7 ------------------ char * mult_str_7(int a, int b) { char *uch = str1; int c; - return uch; ..1 предварительное деление i.6. ---------------------- c = div_5(a, b); ..2 умножить ------------- c = c+(a*b); ..3 |- 5 больше 100 ? ------------- (c > 100) ..4 | выход присвоить "много" ---------------- strcpy(uch, "много"); ..5 присвоить значение ---------------- itoa(c, str1, 10); 4. Пример файла исходного кода test11.cpp // i.1. common defs. #include #pragma hdrstop // #include #include #include #include #include "Unit1.h" // char str1[100], str2[100], str3[100]; // i.2. proc 1 void proc_1(char *stro, int a, int b, int c, int d) { char s1[20], s2[20], s3[20]; int res; res = a+b+c+d; // 1 itoa(res, stro, 10); // 2 } // i.3. proc 2 void proc_2(char *stro, int *a, int *b) { *a = atoi(stro); // 1 *b = (*a)*10; // 2 } // i.4. proc 3 void proc_3(char *stro, int c, int d) { c = d + 10; // 1 } // i.5. proc 4 void proc_4(char *stro, int c, int d) { itoa(c+d, stro, 10); // 1 } // i.6. func 5 int div_5(int a, int b) { int ot; ot = (a/b); // 1 return ot; } // i.7. func 6 char * add_str_6(int a, int b) { char *uch = str2; itoa(a+b, uch, 10); // 1 return uch; } // i.8. func 7 char * mult_str_7(int a, int b) { char *uch = str1; int c; c = div_5(a, b); // 1 c = c+(a*b); // 2 if (! (c > 100)) goto m_5; // 3 strcpy(uch, "ьэюую"); goto m_end; // 4 m_5: itoa(c, str1, 10); // 5 m_end: ; return uch; } 5. Создание псевдографических БС Все, кто имеет высшее техническое образование, хорошо знакомы с блок-схемами, позволяющими наглядно и понятно представить некоторый не очень сложный алгоритм. Но есть у блок-схем и недостатки, резко ограничивающие их использование при документировании ПО. Основными среди этих недостатков являются следующие: 1) При нарастании сложности алгоритма растет и сложность блок-схемы, становится затруднительным ее размещение на одном листе. 2) При нарастании сложности алгоритма резко ухудшается читаемость блок-схемы. 3) При взаимодействии нескольких алгоритмов взаимосвязь между блок-схемами не является наглядной. Здесь нужно использовать ссылку одного алгоритма на другой. Для этого, кстати, удобно использовать нумерацию (индексацию) взаимодействующих друг с другом алгоритмов и реализующих эти алгоритмы процедур. 4) Рисование блок-схемы выполняется с использованием одного из графических редакторов. Здесь налицо трудоемкость рисования и исправления блок-схемы. Программисту некогда отвлекаться на рисование. Кроме того, такую блок-схему нельзя поместить в обычный текстовый файл. Редактор Word решает эту проблему, но, как правило, среда разработки ПО работает только с текстовыми файлами. С первого взгляда кажется, что использование для документирования ПО псевдографических БС, которые являются упрощенными изображениями обычных блок-схем, не дает никакого выигрыша в смысле трудоемкости и лишь ухудшает читаемость таких блок-схем. Но ситуация принципиально меняется при использовании простой программы, позволяющей генерировать файл псевдографических БС из текстового файла, содержащего текст программы или текст документации к этой программе. Тогда сразу устраняются недостатки 1 (часть псевдографической БС можно, в случае нехватки места, просто перенести на следующую страницу) и 4. А для устранения недостатка 2 при увеличении сложности алгоритма нужно дробить этот алгоритм на несколько взаимодействующих друг с другом алгоритмов. В написанной мной программе AB (Algorithms Builder) процесс создания псевдографической БС выглядит следующим образом. Сначала в окне текстового задания БС вводится текст вида: :.1. заголовок 1 вторая строка заголовка . строка 1 . строка 2 . строка 3 . строка 4 . строка 5 . строка 6 . строка 7 где ":." отмечает начало текста заголовка, а следующее за ним число с точкой - индекс заголовка. "." задает строку индексов действия. Заголовок и действия разделяются между собой пустыми строками. Строка индексов действия будет сформирована программой AB автоматически. В окне псевдографики это будет выглядеть так: i.1. заголовок 1 вторая строка заголовка 1 строка 1 | + 2 строка 2 | + 3 строка 3 | + 4 строка 4 | + 5 строка 5 | + 6 строка 6 | + 7 строка 7 | + ВЫХОД Чтобы задать связи между действиями алгоритма, нужно в окне псевдографики сначала щелкнуть левой кнопкой мыши на выбранном действии. Затем нужно нажать правую кнопку мыши, и на экране появится меню переходов: > - безусловный переход + - переход по выполнению условия - - переход по невыполнению условия X - отмена связей для действия После этого левой кнопкой выбираем тип перехода, а затем щелкаем левой кнопкой на действии, куда переходим. После задания нескольких связей БС примет вид: i.1. заголовок 1 вторая строка заголовка 1 строка 1 | +---------------------------------------------- 2 строка 2 ----------------------------------ДА---|--- | | | | НЕТ | | + | | 3 строка 3 ---------------------------------------|--|--- | | | +---------------------------------------------|--- | 4 строка 4 | | | | | + | | 5 строка 5 ----------------------------------НЕТ--|-----|------ | | | | | ДА | | | + | | | 6 строка 6 ----------------------------------ДА---- | | | | | | НЕТ | | ----------------------------------------------------|-----| | | +---------------------------------------------------- | 7 строка 7 | | | +---------------------------------------------------------- ВЫХОД А текст задания БС, после входа в окно редактирования, будет следующим: :.1. заголовок 1 вторая строка заголовка ..1 строка 1 ..2 |+ 4 строка 2 ..3 | 7 строка 3 ..4 строка 4 ..5 |- выход строка 5 ..6 |+ 2 | выход строка 6 ..7 строка 7 Чтобы сбросить БС в файл, нужно щелкнуть по кнопке "ПГА". После этого в рабочем каталоге программы AB будет создан файл с расширением .pga, содержащий тексты БС, сгенерированные из файла текстового задания БС. 2. Установление связей между БС Для установления связи между двумя БС нужно в окне редактирования текста задания БС для соответствующего действия задать ссылку на соответствующую этому действию БС. Например: ..7.9 строка 9 см. i.3. - ссылка на другую БС в этом же файле ..7.10 строка 10 см. temp.txt\i.2. - ссылка на БС в другом файле. Если в окне псевдографики сделать двойной щелчок на строке со ссылкой на другую БС, то в этом окне появится выбранная БС. Для возврата к предыдущей БС нужно щелкнуть мышью по кнопке "<". 3. Задание новых и удаление ненужных БС Задание новых и удаление ненужных БС выполняется в режиме редактирования текста задания БС. Чтобы редактировать текст задания для БС, нужно в окне псевдографики щелкнуть по одной из строк нужной БС, а затем щелкнуть по кнопке "Ред.". После вызова окна редактирования текста задания БС, если требуется задать новую БС, ввести текст для нее перед или после текста для уже существующей БС. А для удаления существующей БС нужно просто удалить текст этой БС и сохранить результат редактирования. Если текстовый файл задания, указанный в ab.cfg, не существует, то он будет создан автоматически. Текущая версия AB может считывать до 15 текстовых файлов задания БС. 4. Задание новых действий из окна псевдографики Чтобы задать новое действие из окна псевдографики, нужно сделать двойной щелчок на строке, находящейся сразу перед или после какого-либо действия БС. После чего будет вызвано поле редактирования для ввода нового действия. 5. Генерация из БС тела процедуры Для генерации из БС тела процедуры нужно указать в окне текстового задания БС процедурные строки, соответствующие действиям ПГБС: :.1. заголовок 1 вторая строка заголовка ..1.1 строка 1 --------- proc1(u); ..1.2 |+ 1.4 строка 2 --------- proc2(u) ..1.3 | 1.7 строка 3 --------- proc3(u); ..1.4 строка 4 --------- proc4(u); ..1.5 |- выход строка 5 --------- proc5(u) ..1.6 |+ 1.2 | выход строка 6 --------- proc6(u) ..1.7 строка 7 --------- proc7(u); Вид окна псевдографики после этого не изменится. После щелчка по кнопке "Прг." в рабочем каталоге программы AB будет создан файл с расширением .prg, в котором, если для всех действий БС заданы процедурные строки, будет сгенерировано тело процедуры БС. Для заголовка 1 тело процедуры на языке C/C++ будет иметь вид: i.1. заголовок 1 proc1(u); // 1 m_2: if (proc2(u)) goto m_4; // 2 proc3(u); goto m_7; // 3 m_4: proc4(u); // 4 if (! proc5(u)) goto m_end; // 5 if (proc6(u)) goto m_2; // 6 else goto m_end; m_7: proc7(u); // 7 m_end: ; Конечно, здесь полно операторов goto, осуждаемых классиками программирования. Но сгенерированное тело процедуры выглядит вполне прозрачным, а при небходимости изменения текста процедуры можно либо сгенерировать ее новый вариант из AB, либо внести правку прямо в текст процедуры, а затем внести изменения в файл текстового задания ПГБС, что совсем нетрудно, учитывая простой формат этого файла. Таким образом будет сохранено соответствие между текстом программы и текстом комментария к программе, что и требуется.