Автоматическая локализация структурных ошибок в процессе форматирования исходных текстов Pascal + Delphi (исходники)Источник: grafor Василий Трошин
Отладчики и форматеры исходных кодов программ, используемые в современной практике программирования, базируются в основном на принципе однонаправленной обработки текста. Из исходного файла вводится строка текста и тут же производится вывод этой информации в выходной файл. Максимум, что позволяет данный подход, это выделять операторы на отдельную строку и выводить их с соответствующим сдвигом. В данной статье будет расcмотрена модификация имеющегося метода форматирования, получившая название графическое форматирование. Для PASCAL + DELPHI разработан отладчик-форматер PGF (Pascal-programs Graphical Formatter), обеспечивающий следующие дополнительные возможности: 1. Автоматическое ВЫЯВЛЕНИЕ и локализация СТРУКТУРНЫХ ошибок с указанием наиболее вероятного варианта их ИСПРАВЛЕНИЯ. 2. Преобразование блоков по умолчанию (когда имеется всего один исполняемый оператор в теле условного- или цикл-оператора ) в явные блоки (добавляется begIN-eND). 3. Реальная структура программы, полученная после вышеуказанных преобразований, визуализируется в виде форматированного текста с использованием ЦВЕТА и ЖИРНОСТИ. 4. Операторы перехода (явные - GoTo, неявные - Exit, Halt, Continue …) ПОЗИЦИОННО и ЦВЕТОМ выравниваются на свою метку (если нет метки, то в нужном месте генерируется фантом-метка), что делает их заметными с первого взгляда. 5. В текст программы добавляется большое количество вспомогательных комментариев структурного характера, в частности ко всем стуктурообразующим операторам приписываются комментарии с информацией, обеспечивающей их ВЗАИМНО-ПЕРЕКРЕСТНЫЕ ссылки. Подбирая в меню желаемые значения параметров, можно легко настроить работу программы на индивидуально желаемый профиль функционирования. Для всех *.PAS файлов создаются их *.RTF эквиваленты, в которых новая структура программы (сформированная в результате нейтрализации неточностей), а также выявленные структурные ошибки визуализируются с помощью отступов, цвета и жирности. При желании можно прямо в *.RTF-файлах произвести отладку текста, сохранить их "File: Save as", указав режим "Save as type: Text document" и приписав в "File name" после имени файла расширение ".PAS". В этом случае исправленный текст заменит старый *.PAS файл и можно продолжать отладку в Turbo Pascal или Delphi. Наглядно видя реализованную в исходном тексте программы РЕАЛЬНУЮ структуру, программист легко может определить требуемые коррекции, чтобы она стала адекватна ЖЕЛАЕМОЙ структуре. Вам самим решать, насколько это облегчит разработку собственной и адаптацию чужой программной продукции, повысит ее надежность. Вполне возможно, что применение пакета в учебном процессе и при оформлении иллюстрационных примеров в учебниках также даст положительный эффект, поскольку более наглядная и качественная визуализация структуры программ облегчит усвоение учебного материала. FreeWare, пакет распространяется бесплатно. Система Windows. Пользователь может сам переделать интерфейс выходных форм по своему усмотрению (в инсталлятор включены исходные тексты программы); легко добавить в интерфейс любой желаемый язык (PGF.exe мультиноязычен, объём сообщений невелик и пока English, Russian, RuTranslit, Georgian, German, French, Spanish). Пакет распространяется несколько месяцев и за это время сообщений о сбоях не поступало, т.е. можете брать смело - если не поможет, то уж, наверняка, не навредит. Чтобы скопировать подробное описание, инсталлятор или обновление пакета PGF, перейдите на сайтах GRAFOR.MOY.SU, GRAFOR.PVT.GE в раздел Files. Если PGF у Вас уже инсталлирован, то для обновления достаточно скопировать новую версию PGFWin.exe. Однако меня теперь больше интересует обсуждение с пользователями вопроса о возможности и целесообразности развития аналогичного подхода к другим языкам программирования. Какой язык программирования Вам кажется наиболее перспективным? Можете ли Вы принять участие в подобных работах? Знаете ли Вы организацию, которая заинтересована в проведении подобной работы настолько, что готова её профинансировать, и как с ней связаться? Можно открыть общую дискусию здесь. В идеале это должен быть модуль, подключаемый к имеющимся трансляторам с данного языка, а еще лучше интегрированный в его новые разрабатываемые трансляторы. Если Вы уже ведёте похожие работы, берите понравившиеся идеи (локализация структурных ошибок; использование цвета и жирности для визуализации структуры; выравнивание переходов по позиции их метки; генерация для структурообразующих элементов комментариев с взаимоперекрестными ссылками; ...) . В заключение хотелось бы привести несколько примеров, иллюстрирующих возможности предлагаемого подхода. Визуализация неявных переходов и генерация фантом-меток. function GetSourceEditor(Module: IOTAModule): IOTASourceEditor; var i: integer; begin Result := nil; if not assigned(Module) then Exit; for i := 0 to Module.GetModuleFileCount - 1 do if Supports(Module.GetModuleFileEditor(i), IOTASourceEditor, Result) then break; end; {{ www.grafor.pvt.ge PGF(Ver 1.3 activ 01.07.2009) formatted 24. 5.2009/13:22 } {{ 1 } function GetSourceEditor(Module:IOTAModule):IOTASourceEditor; {{ 2 } var i:integer; {{ 3 fb } begin {{ #17} {{ 4 f } Result:= nil; {{ 5 f tb } if not assigned(Module) then begIN {{ #7} {{ 6 f V<======<} Exit; {{ #16} {{ 7 f I te } eND; {{t not assign #5} {{ 8 f I fb } for i:= 0 to Module.GetModuleFileCount - 1 do begIN {{ #14} {{ 9 f I f } if Supports(Module.GetModuleFileEditor(i), {{ 10 f I f } IOTASourceEditor, Result) {{ 11 f I f tb } then begIN {{ #13} {{ 12 f IV<=====<} break; {{ #15} {{ 13 f IIf te } eND {{t GetModuleF #11} {{ 14 f IIfe } eND; {{f GetModuleF #8} {{ 15 f I>>=====>} {{FANTOM02:{LABEL} {{ #12} {{ 16 f >>======>} {{FANTOM01:{LABEL} {{ #6} {{ 17 fe } end; {{f GetSourceE #3} Визуализация глубоко вложенной структуры и выхода из неё. function TIDETextExpert.HasShortCut(Menu: TIMainMenuIntf; Ch: Char): Boolean; var SubMenuItem, SubMenu, MenuItems: TIMenuItemIntf; short, I, j: Integer; begin short := ShortCut(Word(Ch), [ssCtrl]); Result := False; if menu <> nil then begin MenuItems := Menu.GetMenuItems; if MenuItems <> nil then try for j := 0 to MenuItems.GetItemCount - 1 do begin SubMenu := MenuItems.GetItem(j); if SubMenu <> nil then try for I := 0 to SubMenu.GetItemCount - 1 do begin SubMenuItem := SubMenu.GetItem(I); if SubMenuItem <> nil then try if SubMenuItem.GetShortCut = short then begin Result := True; Exit; end; finally SubMenuItem.Free; end; end; finally SubMenu.DestroyMenuItem; end; end; finally MenuItems.DestroyMenuItem; end; end; end; {{ www.grafor.pvt.ge PGF(Ver 1.3 activ 01.07.2009) formatted 24. 5.2009/13:22 } {{ 1 } {{ 2 } function TIDETextExpert.HasShortCut(Menu:TIMainMenuIntf; {{ 3 } Ch:Char):Boolean; {{ 4 } var {{ 5 } SubMenuItem, SubMenu, MenuItems:TIMenuItemIntf; {{ 6 } short, I, j:Integer; {{ 7 fb } begin {{ #45} {{ 8 f } short:= ShortCut(Word(Ch),[ssCtrl]); {{ 9 f } Result:= False; {{ 10 f tb } if menu <> nil then begIN {{ #43} {{ 11 f t } MenuItems:= Menu.GetMenuItems; {{ 12 f t tb } if MenuItems <> nil then begIN {{ #42} {{ 13 f t t tb } try {{ #41} {{ 14 f t t t fb } for j:= 0 to MenuItems.GetItemCount - 1 do begIN {{ #37} {{ 15 f t t t f } SubMenu:= MenuItems.GetItem(j); {{ 16 f t t t f tb } if SubMenu <> nil then begIN {{ #36} {{ 17 f t t t f t tb } try {{ #35} {{ 18 f t t t f t t fb } for I:= 0 to SubMenu.GetItemCount - 1 do begIN {{ #31} {{ 19 f t t t f t t f } SubMenuItem:= SubMenu.GetItem(I); {{ 20 f t t t f t t f tb } if SubMenuItem <> nil then begIN {{ #30} {{ 21 f t t t f t t f t tb } try {{ #29} {{ 22 f t t t f t t f t t tb } if SubMenuItem.GetShortCut = short then begIN {{ #25} {{ 23 f t t t f t t f t t t } Result:= True; {{ 24 f V<======<} Exit; {{ #44} {{ 25 f I t t t f t t f t t te } end; {{t GetShortCu #22} {{ 26 f I t t t f t t f t t fb } finally begIN {{ #28} {{ 27 f I t t t f t t f t t f } SubMenuItem.Free; {{ 28 f I t t t f t t f t t fe } eND {{f FINALLY #26} {{ 29 f I t t t f t t f t te } end; {{t TRY #21} {{ 30 f I t t t f t t f te } eND; {{t SubMenuIte #20} {{ 31 f I t t t f t t fe } end; {{f GetItemCou #18} {{ 32 f I t t t f t t fb } finally begIN {{ #34} {{ 33 f I t t t f t t f } SubMenu.DestroyMenuItem; {{ 34 f I t t t f t t fe } eND {{f FINALLY #32} {{ 35 f I t t t f t te } end; {{t TRY #17} {{ 36 f I t t t f te } eND; {{t SubMenu<>n #16} {{ 37 f I t t t fe } end; {{f GetItemCou #14} {{ 38 f I t t t fb } finally begIN {{ #40} {{ 39 f I t t t f } MenuItems.DestroyMenuItem; {{ 40 f I t t t fe } eND {{f FINALLY #38} {{ 41 f I t t te } end; {{t TRY #13} {{ 42 f I t te } eND; {{t MenuItems< #12} {{ 43 f I te } end; {{t menu<>nil #10} {{ 44 f >>======>} {{FANTOM01:{LABEL} {{ #24} {{ 45 fe } end; {{f HasShortCu #7} Локализация структурной ошибки - не закрытый цикл Repeat. program Presentation_graphics; {Si typedef.sys} begin InitGraphic; PlotPie; PlotBar; repeat untei KeyPressed; LeaveGraphic; end. {{ www.grafor.pvt.ge PGF(Ver 1.3 activ 01.07.2009) FORMATTED 24. 5.2009/13:22 } {{ 1 } program Presentation_graphics; {{ 2 } {{ 3 } {Si typedef.sys} {{ 4 PB } begin {{ #11} {{ 5 P } InitGraphic; {{ 6 P } PlotPie; {{ 7 P } PlotBar; {{ 8 P UB } repeat untei KeyPressed; {{!ERROR!NO #10} {{ 9 P U } LeaveGraphic; {{ 10 P UE } UNTIL !ERROR!NO UNT1L! {{U #8} {{ 11 PE } end. {{P Presentati #4} |