Технология модификации программного кода, основанная на параметризуемых шаблонах

динамики характеризуются слабой связанностью подмоделей, поэтому для моделирования целесообразно использовать GRJD-вычисления. Эксперименты по получению результатов в GRID-среде планируются на дальнейших этапах разработки программного комплекса параллельного расчета

динамики систем тел. Предполагается разработка модуля декомпозиции сложных многотельных моделей для эффективного использования распределенных ресурсов GRID-среды. Это позволит осуществлять междисциплинарное моделирование с высокой детализацией.

СПИСОК ЛИТЕРАТУРЫ

1. Виттенбург, И.С. Динамика систем твердых тел [Текст]/И.С. Виттенбург.-М.: Мир.-1980.-294 с.

2. Официальный сайт пакета ФРУНД [Электронный ресурс].-2009.-Режим доступа: http://frund.vstu.ru.

3. Bayo, E. A modified Lagrangian formulation for the dynamic analysis of constrained mechanical systems [Текст]/Е. Bayo, J. Garcia de Jalon, M.A. Serna//Computer Methods in Applied Mechanics and Engineering.-1988.-Vol. 71.-Iss. 2.-P. 183-195.

4. Банах, Л.Я. Условия разбиения системы дифференциально-алгебраических уравнений на слабосвязанные подсистемы [Текст]/Л.Я. Банах, А.С. Го-робцов, О.К. Чесноков//Журнал вычислительной математики и математической физики.-2006.-№ 12.-C. 2223-2227.

5. Hockney, R. The communication challenge for MPP: Intel paragon and meiko CS-Parallel computing [Текст]Ж. Hockney//Parallel Computing archive.-1994.-Vol. 20. Iss. 3.-P. 389-398.

6. Pjesivac-Grbovic, J. Performance analysis of MPI collective operations [Текст]Л. Pjesivac-Grbovic, T. Angskun, G. Bosilca [et al.]//Cluster Computing.-2007. -Vol. 10.-P. 127-143.

7. Matsuda, M. The design and implementation of MPI collective operations for clusters in long-and-fast networks [Текст]/ M. Matsuda, T. Kudoh, Y. Kodama [et al.]//Cluster Computing.-2008.-Vol. 11.-Iss. 1.-P. 45-55.

8. Lucas, H.V. Hint Controlled Distribution with Parallel File Systems [TeKCT]/H.V. Lucas, T. Ludwig// European PVM/MPI Users Group Meeting.-2005.-P. 110-118.

9. Worringen, J. Improving generic non-contiguous file access for MPI-IO [Текст]Л. Worringen, J.L. Traft, H. Ritzdorf//Lecture Notes in Computer Science, Recent Advances in Parallel Virtual Machine and Message Passing Interface .-2003.-P. 309-318.

УДК 004.4'23, 004.4'24

В.М. Ицыксон, Д.А. Тимофеев

ТЕХНОЛОГИЯ МОДИФИКАЦИИ ПРОГРАММНОГО КОДА, ОСНОВАННАЯ НА ПАРАМЕТРИЗУЕМЫХ ШАБЛОНАХ

Различные модификации исходного кода -одни из самых частых действий разработчиков во время всего жизненного цикла программной системы. Целями модификации могут являться внесение новой функциональности, исправление ошибок, улучшение читаемости, повышение производительности, переход на другие библиотеки и т. п. В общем случае эту задачу сложно автоматизировать, поэтому разработчики обычно решают ее вручную. Она усложняется еще и тем, что сравнительно небольшие локальные изменения могут повлечь за собой необходимость обработки большого количества зависимого программного кода.

Если модификация программного кода представляет собой изменения с сохранением поведения (рефакторинги), то задача решается относительно легко с привлечением современной среды разработки, в которой данные модификации поддержаны и автоматизированы. Однако часто требуется вносить изменения, которые не могут быть выражены набором шаблонов рефакторинга. Кроме того, их иногда необходимо производить многократно в разных участках программы. Примером таких изменений может быть однотипная оптимизация циклов в программе.

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

Одним из способов решения указанной проблемы может быть использование существующих универсальных средств для различного рода трансформаций кода, таких как Stratego/XT [1], ASF+SDF [2], TXL [3] и т. п. Эти системы являются универсальными преобразователями структурированных текстов, управляемыми грамматикой. С их помощью можно описать довольно сложные преобразования программ, написанных на различных языках программирования.

Однако, на наш взгляд, им присущи существенные недостатки:

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

сложность интеграции с существующими средами разработки с сохранением необходимого уровня интерактивности;

необходимость описания операций преобразования программы в терминах ее модельного представления (например, в терминах абстрактного синтаксического дерева (АСД) или грамматики целевого языка);

трудоемкость и затратность внедрения в текущий процесс разработки программного обеспечения.

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

язык шаблонов, позволяющий описывать параметризуемые шаблоны кода «до» и «после» модификации. На основе данных шаблонов генерируется список операций, необходимых для модификации программного кода. Поиск участков кода, для которых необходимо произвести изменения, осуществляется с использованием шаблона «до». После завершения поиска и изменения необходимых участков, происходит запись программного кода в форматированном виде обратно в файл. На рис. 1 представлена общая схема предлагаемого подхода.

Ниже более подробно рассматриваются основные этапы осуществления модификаций кода, применяемые в этом подходе.

Язык шаблонов. Указанные выше инструменты, такие как Stratego, TXL и т. п., используют сложный язык описания трансформаций. Для того, чтобы упростить работу разработчика, необходимо создать декларативный язык описания модификаций программного кода, который является максимально близким к целевому языку программирования. В таком случае синтаксис языка трансформаций в основных чертах повторяет синтаксис языка программирования. Благодаря этому он более легок в изучении и применении.

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

необходимость оперирования шаблонами «до» и «после» модификации;

возможность параметризации шаблонов; наличие элементов регулярных выражений для осуществления более гибкого поиска участков кода;

иерархичность языка - не должно быть ограничений на количество вложенных конструкций.

Выбор в пользу использования шаблонов «до» и «после» обоснован тем, что в данном случае возможно осуществить автоматическое определение списка операций, необходимых для при-

Рис. 1. Общая схема подхода

ведения шаблона «до» к виду шаблона «после». Этот список впоследствии может быть использован для преобразования участков кода, найденных на основе шаблона «до».

В статье описывается разработанный язык шаблонов для языка программирования Java 1.5. Язык Java выбран как один из самых распростра-

Шаблон «до»:

ненных в настоящее время языков программирования. Формальная спецификация языка шаблонов не приведена из-за ограниченного объема статьи.

В листинге 1 дан пример параметризованных шаблонов для преобразования цикла «for» в цикл «while».

Шаблон «после»:

for( }

#var; #cond; #upd) { #expr;

#var;

while(#cond) #expr; #upd;

}

Листинг 1: Пример параметризованных шаблонов для преобразования

Используя такие шаблоны можно за одну операцию трансформировать все операторы «for» в «while» и обратно. Шаблон «до»:

В листинге 2 приведены шаблоны для оптимизации цикла «&г» в том случае, если условие выражения «й» является константным.

Шаблон «после»:

£ог( ^аг; #соп^ #ир^ { 1£("Ьгие) { #ехрг;

}

} }

Листинг 2: Пример шаблонов для оптимизации

Как видно из рассмотренных примеров, разработанный язык шаблонов является достаточно прозрачным и простым в изучении.

Параметры в приведенных выше шаблонах выступают в роли элементов-«заполнителей», которые во время поиска заполняются найденными конструкциями языка программирования. Изменение местоположения параметра в шаблоне «после» позволяет указать место перемещения

if(true) {

for(#var; #cond; #upd) { #expr;

}

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

#EXPR:1; - количество конструкций языка = 1;

#EXPR:1-5; - количество конструкций языка от 1 до 5; #EXPR:1-; - количество конструкций языка больше 1;

Листинг 3: Примеры настраиваемого параметра

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

коде. В качестве примера в листинге 4 приведен шаблон для поиска всех методов в классе, описанном на языке Java.

#method

{

this.a = b;

}

#EXPR;

}

Листинг 4: Пример шаблона для поиска методов

Рис. 2. АСД участка кода, отвечающего за объявление переменной

Модельное представление программы. Для

осуществления операций поиска необходимых участков кода и их последующей модификации необходимо выбрать промежуточное представление программного кода, наиболее пригодное для проведения поиска и модификаций. В качестве основного представления было выбрано абстрактное синтаксическое дерево [4] (далее -АСД) в силу следующих его свойств:

расширяемость - в случае необходимости в АСД может быть включена дополнительная информация (например, различные семантические свойства, комментарии и т. п.);

эффективность - существуют эффективные алгоритмы обработки деревьев;

адаптивность - возможность настраивания уровня детализации при генерации АСД.

На рис. 2 представлен пример возможного АСД для участка кода, отвечающего за объявление переменной.

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

Модельное представление шаблонов. В качестве промежуточного представления шаблонов также используется АСД. Для его построения используется парсер, который создается на основе

расширеннои грамматики целевого языка программирования. В результирующем АСД имеются узлы двух типов:

простые узлы, соответствующие конструкциям целевого языка программирования (например, «for» или «if»);

параметрические узлы, соответствующие шаблонным элементам (например, «#var» или «#expr:1»).

Так как синтаксис языка шаблонов близок к синтаксису целевого языка, при реализации можно применять единый парсер, используемый для формирования и АСД исходной программы, и АСД шаблонов.

На рис. 3 представлено АСД, построенное для шаблона, позволяющего выбрать определенную конструкцию объявления переменной независимо от инициализирующей конструкции.

Автоматическое определение операций модификации. Для того чтобы этап получения списка операций, необходимых для модификации программного кода, осуществлялся в автоматическом режиме, можно применить алгоритм определения изменений в иерархических структурах данных, описанный в [5].

Данный алгоритм работает с упорядоченными деревьями, в которых узлы поименованы (имеют идентификатор типа узла) и имеют значения. Принимая на вход дерево «до» и «после» изменений,

Рис. 3. АСД шаблона, позволяющего выбирать определенную конструкцию объявления переменной

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

На рис. 4 представлены четыре типа операций, которые извлекаются с использованием алгоритма получения дифференциальной разности деревьев:

Insert. Операция вставки нового узла. Узел G

добавляется на первую позицию списка дочерних узлов узла B.

Move. Операция перемещения узла. Узел D перемещается на вторую позицию списка дочерних узлов узла B.

Update. Операция обновления значения узла. Значение «Value» узла C изменяется на значение «NewValue».

Delete. Операция удаления узла. Узел Е удаляется из списка дочерних узлов узла C.

Полное описание алгоритма рассмотрено в [5].

Рис. 4. Операции, извлекаемые с использованием алгоритма получения дифференциальной разности деревьев

Рис. 5. АСД шаблонов «до» и «после» модификации

В качестве примера рассмотрим преобразование АСД шаблонов «до» и «после», представленных на рис. 5.

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

1. Insert: node EXPR in node DECLARATOR in 1 position.

2. Insert: node DOT in node EXPR in 0 position.

3. Insert: node Settings in node DOT in 0 position.

4. Insert: node DEFAULT_CONSTANT_ VALUE in node DOT in 1 position.

5. Delete: node EXPR.

6. Delete: node SELECTOR.

7. Delete: node #initializer.

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

Поиск участков кода. Поиск участков программного кода, подлежащих изменениям, осу-

#ехрг

Рис. 6. Пример соответствий, построенных для параметров шаблона

ществляется в АСД исходной программы с использованием шаблона «до» модификации. Задача алгоритма поиска найти в дереве исходного кода поддеревья, соответствующие шаблону «до».

При этом используются следующие критерии соответствия.

1. Для простых узлов шаблонов:

типы и значения узлов дерева шаблона и дерева исходного кода совпадают;

выполняются критерии соответствия для всех дочерних узлов дерева шаблона и дерева исходного кода.

2. Для параметрических узлов шаблонов:

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

Во время поиска осуществляется построение соответствий между узлами АСД шаблона и узлами найденного поддерева АСД исходного кода. Так как параметрам шаблона может соответствовать неограниченное количество узлов, то для них строятся соответствующие списки, которые хранят найденные конструкции. На рис. 6 представлен пример построенных соответствий.

Модификация абстрактного синтаксического дерева. Все операции модификации осуществляются над АСД исходного кода путем последовательного применения операций, полученных при использовании алгоритма, описанного выше.

Операции модификации применяются во время поиска участков кода, удовлетворяющих шаблону «до», при первом же совпадении. На основе построенных соответствий между узлами исходного АСД и АСД шаблона «до» происходит проверка количества найденных узлов на соответствие количеству, указанному в свойствах параметров шаблона. В случае нахождения несоответствий поиск продолжается далее. Участки кода, которые были изменены, помечаются специальным образом для исключения их повторного нахождения. Затем поиск продолжается повторно от корня АСД. Поиск заканчивается, когда все узлы АСД проверены на соответствие шаблону «до».

Реализация. В рамках описанного подхода был разработан прототип системы модификации программного кода на основе параметризуемых шаблонов для языка Java 1.5. Для получения АСД исходного кода и шаблонов модификации используется парсер, созданный генератором парсеров ANTLR v3 [6]. Этот парсер работает на основе модифицированной грамматики языка Java 1.5. Так как модификация исходного кода осуществляется над промежуточным представлением, в качестве которого используется АСД, то при формировании текста измененного программного кода на языке Java необходимо осуществить преобразование АСД в программы на целевом языке. В разработанном прототипе используется промежуточное преобразование АСД в DOM-модель, использование которой упрощает формирование структуры и оформления (форматирования) программного кода.

Для удобства программистов, разработанный программный модуль оформлен в виде плагина для среды разработки Eclipse 3.5 [7].

Разработанная технология модификации программного кода может служить основой поддержки таких этапов жизненного цикла программного обеспечения, как разработка, тестирование и сопровождение. Использование автоматизированных преобразований существенно снижает количество ошибок, вносимых разработчиком на перечисленных этапах, и позволяет сократить время, затрачиваемое на проведение рефакторин-гов и оптимизаций.

Направления развития технологии связаны с расширением языка шаблонов в сторону поддержки семантических особенностей целевого языка и введения контекстно-чувствительной трансформации. Благодаря универсальному внутреннему представлению программы и шаблонов технология легко адаптируется к другим языкам программирования, таким как C/C++ и C#.

Работа выполнена в рамках госконтракта № П2226 ФЦП «Научные и научно-педагогические кадры инновационной России на 2009-2013 гг.».

СПИСОК ЛИТЕРАТУРЫ

1. Stratego/XT [Электронный ресурс]/Ъйр:// strategoxt.org/

2. ASF+SDF [Электронный ресур^/httpV/www. meta-environment.org/

3. The TXL Programming Language [Электронный ресур^/httpV/www.txl.ca/

4. Aho, A.V. Compilers: Principles, Techniques, and Tools [Текст]/А^. Aho, R. Sethi, J.D. Ullman.-1986.

5. Chawathe, S.S. Change detection in hierarchically structured information [TeKCT]/S.S. Chawathe, A. Rajaraman, H. Garcia-Molina [et al.]//Proc. of the 1996 ACM SIGMOD International Conf. on Management of Data.-1996.-P. 493-504.

6. ANTLR Parser Generator [Электронный ресурс]/ http://www. antlr.org/

7. Eclipse.org Home. The Eclipse Foundation [Электронный pecypc]/http://www. eclipse.org/