Диссертация (1150733), страница 13
Текст из файла (страница 13)
В XML-теге Matched содержится описание парных элементов. Каждая пара описывается в XML-теге Pairи для одного языка может быть указано более одной такой пары.1234567891011121314151617181920212223242526272829303132<?xml version="1.0" encoding="utf-8"?><SyntaxDefinition name="CalcHighlighting"><Colors><Tokens color="CONSTANT_IDENTIFIER_ATTRIBUTE"><Token> DIV </Token><Token> LBRACE </Token><Token> MINUS </Token><Token> MULT </Token><Token> NUMBER </Token><Token> PLUS </Token><Token> POW </Token><Token> RBRACE </Token></Tokens></Colors><!-- Dynamic highlighting: --><Matched><Pair><Left> LBRACE </Left><Right> RBRACE </Right></Pair><!-- You can specify more then one pair:<Pair><Left> LEFT_SQUARE_BRACKET </Left><Right> RIGHT_SQUARE_BRACKET </Right></Pair><Pair><Left> LEFT_FIGURE_BRACKET </Left><Right> LEFT_FIGURE_BRACKET </Right></Pair>--></Matched></SyntaxDefinition>Листинг 15: Пример конфигурационного файла для настройки подсветкисинтаксисаЛистинг 16 содержит пример описания точек интереса.
Для каждой точкиинтереса должна быть указана следующая информация.– Какому встроенному языку соответствует точка. Информация хранится вXML-теге Language.68– Полное имя метода, являющегося точкой интереса. Информация хранитсяв XML-теге Method.– Порядковый номер аргумента данного метода, являющегося выражениемна встроенном языке. Нумерация начинается с нуля. Информация хранитсяв XML-теге ArgumentPosition.– Возвращаемыйтипметода.ИнформацияхранитсявXML-тегеReturnType.1<?xml version="1.0" encoding="utf-8"?>2<!-- comment about body -->3<Body><!-- comment about hotspot -->45<Hotspot>6<!-- comment about tsql -->7<Language> TSQL </Language>8<!-- comment about fullName -->9<Method>Program.ExecuteImmediate</Method>10<!-- zero-based -->11<ArgumentPosition> 0 </ArgumentPosition>12<!-- comment about return type -->13<ReturnType> void </ReturnType>14</Hotspot>15<Hotspot>16<Language> Calc </Language>17<Method>Program.Eval</Method>18<ArgumentPosition> 0 </ArgumentPosition>19<ReturnType> int </ReturnType>2021</Hotspot></Body>Листинг 16: Пример конфигурационного файла для настройки точек интереса3.2Применение YC.SEL.SDKРазработанный SDK предназначен для создания инструментов статическогоанализа динамически формируемых строковых выражений.
Решения, созданные69с его помощью, могут применяться для работы с проектами, активно использующими динамически формируемые строковые выражения. Необходимость работать с такими проектами может возникнуть, например, в следующих областях.– Реинжиниринг программного обеспечения.– Поддержка встроенных языков в средах разработки.– Оценка качества и сложности кода.Общим для всех этих областей является то, что для решения соответствующих задач необходимо структурное представление динамически формируемогокода. При этом процесс анализа встроенных языков часто тесно связан с анализом внешнего языка.Отметим, что в современных проектах встроенные языки используются всёменее активно.
На смену им приходят более надёжные способы композицииязыков и метапрограммирования. Например LINQ или ORM-технологии. Однако всё ещё широко распространено использование строковых выражений длявзаимодействия с базами данных и генерации WEB-страниц в приложениях наPHP [9].
Это необходимо учитывать при поддержке встроенных языков в средахразработки. Для каких-то языков на первый план выходят возможности по изучению и модификации уже созданного кода, а для каких-то — возможность быстрои удобно создавать новый код. Во втором случае могут возникнуть дополнительные требования к скорости работы инструмента, так как подразумеваетсявыполнение некоторых операций “на лету”, что может послужить ограничениемна использование SDK. Оценка качества и сложности кода часто может выполняться в рамках комплекса задач по реинжинирингу системы, однако может бытьи самостоятельной задачей, например, при оценке сложности работ по поддержке и сопровождению информационной системы.Детали применения SDK могут варьироваться в зависимости от решаемыхзадач и контекста использования.
Например, механизм построения регулярнойаппроксимации может быть реализован независимо, в рамках внешнего инструмента. Однако основной сценарий использования аналогичен использованиюинструментариев для разработки компиляторов.70Шаг 1. Создание грамматики обрабатываемого языка. Грамматика можетбыть создана на основе документации соответствующего языка или переиспользована готовая, что оправданно, например, при создании анализатора для динамического SQL, когда внешний и встроенный языки совпадают.Шаг 2.
Генерация синтаксического анализатора по грамматике. Для этогоиспользуется генератор синтаксических анализаторов, присутствующий в SDK.Результатом работы является файл с исходным кодом на языке F#, который должен быть включён в разрабатываемый проект. Файл содержит описание типовдля лексических единиц, управляющие таблицы анализатора и функцию, которая по конечному автомату над алфавитом токенов анализируемого языка построит SPPF, содержащий деревья вывода всех корректных цепочек.Шаг 3.
Создание лексической спецификации обрабатываемого языка. Спецификация может быть извлечена из документации или заимствована из других проектов. При обработке динамически формируемого SQL возможно переиспользовать спецификацию, созданную для основного языка, которым такжеявляется SQL. При этом необходимо обратить внимание на то, что типы лексических единиц определяются на основе созданного на предыдущих шагах синтаксического анализатора.Шаг 4.
Генерация лексера по созданной спецификации. Для этого применяется генератор лексических анализаторов, входящий в состав SDK. В результатеего применения получается файл с исходным кодом на языке F#, который должен быть подключён к разрабатываемому решению.Шаг 5. Реализация механизма построения регулярной аппроксимации, результатом которого является функция, строящая конечный автомат над алфавитом символов. Данный механизм может быть реализован либо на основе предоставляемого в рамках SDK, либо независимо. В первом случае от разработчикатребуется построить обобщённый CFG для внешнего языка. Во втором случаенеобходимо только гарантировать правильность возвращаемого конечного автомата.
Второй подход может быть использован, например, при наличии реализованного механизма протягивания констант для внешнего языка. Это позволитсоздать менее точный, но более быстрый механизм для построения аппроксимации. Такой подход применим при автоматизированном реинжиниринге, когдаручная доработка кода является обязательным шагом и высокая точность авто-71матической обработки не требуется. Ещё одна возможная область применениявторого подхода — это поддержка встроенных языков в средах разработки.
Здесьтакже часто не требуется высокая точность для подсказок пользователю, однако производительность крайне важна. Поэтому иногда приходится жертвоватьточностью анализа для достижения нужной скорости работы.Шаг 6. Реализация работы с SPPF. Синтаксический анализатор возвращаетSPPF — конечное представление леса разбора всех корректных цепочек, содержащихся в аппроксимации. Дальнейшая работа с ним может строиться по двумосновным сценариям.Первый сценарий — непосредственная обработка SPPF.
В этом случае всевычисления происходят над SPPF без извлечения отдельных деревьев. Это позволит ускорить обработку результатов разбора, так как количество деревьев может быть бесконечным, а SPPF является конечной структурой данных. Однакосуществует несколько проблем, связанных с таким подходом. Во-первых, требуется создание новых процедур обработки, так как классические, как правило,ориентированы на работу с деревьями. Во-вторых, могут возникнуть трудностипри выполнении некоторых видов анализа, вызванные тем, что в SPPF хранятся“бесконечные” деревья.
Например, необходимо вычислить максимальную глубину вложенности конструкции if, являющуюся одной из стандартных метриксложности кода. SPPF может содержать циклы, и может оказаться, что конструкция if встречается в цикле таким образом, что потенциальная глубина вложенности может быть бесконечной. Такая ситуация не является стандартной приработе с деревьями разбора и её надо обрабатывать отдельно.Второй сценарий — извлечение и обработка отдельных деревьев из SPPF.Данный подход может оказаться удобным, если уже существуют процедуры обработки синтаксических деревьев для языка, который оказался встроенным. Этопомогает избежать затрат на создание новой функциональности. Такая ситуациявозможна при работе с динамическим SQL. В этом случае для обработки дереваразбора внешнего языка и деревьев, извлечённых из SPPF, можно использоватьодни и те же процедуры, так как языки идентичны.Недостатком второго подхода является то, что конечность числа деревьев негарантирована.
Это значит, что не удастся обработать все деревья. Стоит отме-72тить, что даже в случае конечности числа деревьев перебор и обработка всехдеревьев разбора может потребовать значительных ресурсов.Шаг 7. Реализация механизмов сбора, обработки и отображения информации— сообщений об ошибках или любой другой, полученной в процессе анализа.Рассмотренная последовательность шагов может быть изменена в зависимости от особенностей задачи. На рисунке 13 изображён возможный сценарийиспользования SDK. Его особенностью является цикличность, характерная, например для реинжиниринга.Рисунок 13: Один из возможных вариантов использования SDK в проектах пореинжинирингуВстраивание анализа строковых выражений в обработку кода всей системы зависит от решаемых задач. Сначала необходимо получить входные данныедля анализа. Для этого следует провести лексический и синтаксический анализвнешнего языка, построить граф потока управления.
После этого возможно построение аппроксимации и дальнейший анализ встроенных языков. Параллельнос этим может проводиться дальнейшая обработка внешнего языка. Степень параллельности зависит от независимости решаемых задач. Например, некоторыеметрики сложности для основного кода и для динамически формируемого мож-73но вычислять независимо. С другой стороны, может возникнуть необходимостьвычислить комплексную метрику, учитывающую параметры внешнего и динамически формируемого кода, что приведёт к необходимости синхронизации.3.3Особенности реализацииРазработка инструментального пакета с описанной выше архитектуройи плагинов для ReSharper велась в рамках исследовательского проектаYaccConstructor (YC), описанного в разделе 1.7.1.