Upload
semyon-grigorev
View
80
Download
0
Embed Size (px)
DESCRIPTION
Презентация результатов исследовательского проекта лаборатории JetBrains на Математико-Механическом факультете СПбГУ. Работа посвящена статическому анализу выражений на встроенных языках -- выражения, которые собираются из строковых литералов во время выполнения основной программы. Примеры таких языков -- встроенный SQL (в C++, C#, Java и т.д.), динамический SQL, генерация HTML. Представлена платформа, предназначенная для разработки различных инструментов для работы со встроенными языками. Описаны основные её компоненты и их особенности: генератор лексических анализаторов для встроенных языков, генератор синтаксических анализаторов, особенности диагностики ошибок, особенности вычисления семантики. Также представлен плагин для Microsoft Visual Studio IDE на основе ReSharper, который демонстрирует возможности платформы и предоставляет следующие возможности: статический поиск ошибок, подсветка синтаксиса (в том числе динамическая: подсветка парных скобок). Исследования ведутся на основе проекта с открытым исходным кодом YaccConstructor: https://code.google.com/p/recursive-ascent/ Основной язык разработки: F#.
Citation preview
Семинар ”Наукоемкоепрограммное обеспечение“
PSI-201424-27 июня, Санкт-Петербург
Инструментальная поддержка встроенных языков винтегрированных средах разработки
Автор: Григорьев Семён, Вербицкая Екатерина,Иванов Андрей, Мавчун Екатерина,
Полубелова Марина
Лаборатория JetBrains на Математико-Механическом факультетеСанкт-Петербургского государственного университета
26 июня 2014г.Григорьев Семён (JetBrains) 26 июня 2014г. 1 / 30
Встроенные языки
Динамический SQLIF @X = @Y
SET @TABLE = ’#table1’ELSE
SET @TABLE = ’table2’EXECUTE
(’SELECT x FROM’ + @TABLE + ’ WHERE ISNULL(n,0) > 1’)
JavaScript в JavaString script =
"function hello(name) print(’Hello, ’ + name); ";engine.eval(script);Invocable inv = (Invocable) engine;inv.invokeFunction("hello", "Scripting!!!" );
Григорьев Семён (JetBrains) 26 июня 2014г. 2 / 30
Проблемы
Динамически формируемые выражения – код на некотором языкеи его нужно соответствующим образом поддерживать иобрабатывать
I Ошибки в динамически формируемых выраженияхобнаруживаются лишь во время выполнения
I Поддержка в IDEI Реинжиниринг ПО, разработанного с использованием встроенных
языковОднако для стандартных инструментов это просто строки
I Ошибки во время выполненияI Нет поддержки в IDE
Григорьев Семён (JetBrains) 26 июня 2014г. 3 / 30
Актуальность
Да, новый код так почти не пишут. Но:I Многое уже написано и оно требует поддержки, сопровожденияI Альтернатив динамическому SQL пока малоI Есть кодогенераторы и они генерируют код в виде текста
Григорьев Семён (JetBrains) 26 июня 2014г. 4 / 30
Предлагаемое решение
Статическая обработка встроенных языковI Поддержка в IDE
F Многие ошибки можно искать без запуска программыF Автодополнение, рефакторинги
I РеинжинирингF Статический анализF Трансформация (трансляция)
Григорьев Семён (JetBrains) 26 июня 2014г. 5 / 30
Существующие решения
Alvor – плагин для Eclipse для статической проверки встроенногов Java SQLJava String Analyzer – статический анализатор динамическихвыражеинй для JavaPHP String Analyzer – статический анализатор динамическихвыражеинй для PHPPHPStorm – IDE для PHP с поддержкой HTML, CSS, JavaScriptIntelliLang – плагин к PHPStorm и IDEA, осуществляющийподдержку различных языков
Предоставляемая функциональность часто скуднаЧасто поддержка других языков возможна только путёмизменения исходного кода инструмента
Григорьев Семён (JetBrains) 26 июня 2014г. 6 / 30
Цели
Платформа для создания инструментов анализа встроенныхязыков
I Расширяемость в смысле поддержки других языковI Расширяемость в смысле предоставляемой функциональности
Плагин для MS Visual Studio на основе ReSharperI Демонстрация возможностей платформыI Поддержка встроенных языков в MS Visual Studio
Григорьев Семён (JetBrains) 26 июня 2014г. 7 / 30
Языковые расширения
Поддержка нового языка – создание плагина на основе общейфункциональности
IDE
Ядро SDK
Lang1 Lang3Lang2
Григорьев Семён (JetBrains) 26 июня 2014г. 8 / 30
Языковые расширения
SDKI Генератор абстрактных лексических анализаторовI Генератор абстрактных синтаксических анализаторовI Описание общих интерфейсовI ...
Плагинная система на основе Mono.AddinsМеханизм разметки кода конечного пользователя
Григорьев Семён (JetBrains) 26 июня 2014г. 9 / 30
Языковые расширения: пример
var tbl1 = “#tbl1”var tbl2 = “tbl2”
[<InjectedLang("TSQL")>]execute (“select x from ” + if cond then tbl1 else tbl2)
[<InjectedLang("Calc")>]eval (“12 + 3 * (4 + 5)”)
Григорьев Семён (JetBrains) 26 июня 2014г. 10 / 30
Как это работает: абстрактный анализ
Kyung-Goo Doh, Hyunha Kim, David A. SchmidtI Комбинация LR-анализа и анализа потока данных для обработки
встроенных языковДля каждого выражения строится конструкция,аппроксимирующая множество его возможных значений
I Data-flow уравнениеI ГрафI Регулярное выражение
Выполнение лексического, синтаксического анализа над графом
Григорьев Семён (JetBrains) 26 июня 2014г. 11 / 30
Пример
IF @X = @YSET @TABLE = ’#table1’
ELSESET @TABLE = ’table2’
EXECUTE(’SELECT x FROM ’ + @TABLE + ’ WHERE ISNULL(n,0) > 1’)
Множество значений:{’SELECT x FROM #table1 WHERE ISNULL(n,0) > 1’ ;’SELECT x FROM table2 WHERE ISNULL(n,0) > 1’}Аппроксимация:
1 2"SELECT x FROM "
3"#table1"
"table2"4
" WHERE ISNULL(n,0) > 1"
Григорьев Семён (JetBrains) 26 июня 2014г. 12 / 30
Абстрактный лексический анализ
Аппроксикация (граф со строками на рёбрах) → граф с токенамина рёбрах
I Привязка к литералу в исходном кодеI Точная привязка внутри литерала
Например:I Входной граф
0 1"12" 2"3" 3"+5""*6"
I Результат лексического анализа
0 1NUM: 1232*
3
+ 4
NUM: 6
NUM: 5
Григорьев Семён (JetBrains) 26 июня 2014г. 13 / 30
Абстрактный лексический анализ: рваные токены
Токены могут собираться из нескольких частей
0 1"select x from name_" 2"1"" 2"
Нужно обрабатывать такие ситуацииНужно сохранять привязку каждой части
Григорьев Семён (JetBrains) 26 июня 2014г. 14 / 30
Обобщённый синтаксический анализ
Generalized LR parsing (GLR)Предназначен для работы с произвольными КС грамматиками
I Shift-Reduce и Reduce-Reduce конфликты
Использует организованный в виде графа стек (GSS)
1
0
s
43
e
2 PLUS
2PLUS
NUM
NUM
5
NUM
Использует компактное представление леса вывода (SPPF)I Переиспользование общих узлов
Григорьев Семён (JetBrains) 26 июня 2014г. 15 / 30
Абстрактный синтаксический анализ
Добавим Shift-Shift ”конфликты“ – ситуации, возникающие приветвлении входного потокаПолучилось расширение GLRВход:
10 321 + 2
3
Результат:
1
+
2 1
+
3
Григорьев Семён (JetBrains) 26 июня 2014г. 16 / 30
Диагностика ошибок
Нужно возвращать лес разбора для корректных выражений исписок ошибок для некорректныхДля обычного GLR умершая ветка — нормально, дляабстрактного не всегдаПропускать токены в графе сложнее, чем в линейном потоке
0 11
2+
32
6
*
4
)
7
3
8-
/
5/
4
95
Существуют проблемы, связанные с особенностями базового(GLR) алгоритма
Григорьев Семён (JetBrains) 26 июня 2014г. 17 / 30
Восстановление после ошибок
Отдельный вопрос для исследованийI В больших выражениях хочется видеть все ошибкиI В сложных выражениях может быть много ложных ошибокI Бывают принципиально некорректные выражения, которые при
реальном выполнении не формируютсяI Например
x = condition ? “(1+2” : “1+2”;y = condition ? “)*3” : “*3”;Program.Eval(x + y);
2 из 4 путей не могут быть получены, но в графе есть все
0 1(1+21+2
2)*3*3
Григорьев Семён (JetBrains) 26 июня 2014г. 18 / 30
Вычисление семантики
Результат анализа – минимум одно дерево для пути в графе ивесь лес разбора сжат в SPPFЧто-то можно вычислить прямо на графе, но часто нужноизвлекать деревья
0
1
"1 + "
2
" 2 "" 3 "
n expr
prod 1
n expr t PLUS n expr
prod 2 prod 2 prod 2
t NUM 1 t NUM 2 t NUM 3
Григорьев Семён (JetBrains) 26 июня 2014г. 19 / 30
Вычисление семантики: пример
Подсветка синтаксисаДостаточно покрыть все токеныМожно возвращать не все деревья, а некоторое подмножество
0 1NUM 1
NUM 22
PLUS3
NUM 3
NUM 4
n expr
n expr t PLUS n expr
t NUM 1 t NUM 3
n expr
n expr t PLUS n expr
t NUM 2 t NUM 4
Григорьев Семён (JetBrains) 26 июня 2014г. 20 / 30
Вычисление семантики
В худшем случае придётся перебирать все деревья
0 1...
2
...
...
...
...
3...
4...
Ленивая генерация деревьев
Григорьев Семён (JetBrains) 26 июня 2014г. 21 / 30
Демонстрация
Григорьев Семён (JetBrains) 26 июня 2014г. 22 / 30
Что дальше
Большинство задач, применимых к обычному коду, применимо ико встроенным языкам:
I навигацияI проверка типовI трансформацииI ...
Григорьев Семён (JetBrains) 26 июня 2014г. 23 / 30
Навигация по коду
Визуальное представление динамического выражения в видеграфа
I Навигация в кодI Навигация в граф из кодаI Информация об ошибках на графе: если ошибка на стыке
строковых литералов, то трудно понять, где она реально
Григорьев Семён (JetBrains) 26 июня 2014г. 24 / 30
Проверка типов
Внутри выраженияI int x = eval (“12 * ’string’ + 3 ”)
Согласованность с внешним кодомI int x = execute (“select ’string’ from dual”)
Григорьев Семён (JetBrains) 26 июня 2014г. 25 / 30
Трансформации
РефакторингПереход с одного диалекта на другой
I Для SQL особенно актуальноПереход на новые технологии
I Встроенный SQL → LINQ
Много вопросовВозможны ли нетривиальные трансформации?
I Как обратно генерировать код?
Как гарантировань корректность трансформаций?
Григорьев Семён (JetBrains) 26 июня 2014г. 26 / 30
Результаты
ЯдроI Генератор абстрактных лексических анализаторов
F Привязка к исходному кодуI Генератор абстрактных синтаксических анализаторов
F Диагностика ошибокF Механизм вычисления семантики
I Модульная архитектура для языковых расширенийПлагин для ReSharper
I Расширяемая архитектура, позволяющая легко поддержать любойвстроенный язык
F Внешний язык должен поддерживаться в ReSharper
Григорьев Семён (JetBrains) 26 июня 2014г. 27 / 30
Реализация
Открытый кодПлатформа .NE.Основной язык – F#Проект YaccConstructor – платформа для исследований в областисинтаксического анализа
Григорьев Семён (JetBrains) 26 июня 2014г. 28 / 30
Область применения
Поддержка встроенных языков в IDEI Интерактивная ("на лету")I "Офлайновая" проверка (ручной запуск)
Поддержка, сопровождение кода со встроенными языкамиАвтоматизированный реинжиниринг ПО, разработанного сприменением встроенных языковВерификация генераторов кода
Григорьев Семён (JetBrains) 26 июня 2014г. 29 / 30
Информация о проекте
Контакты:I Григорьев Семён: [email protected] Вербицкая Екатерина: [email protected] Мавчун Екатерина: [email protected] Иванов Андрей: [email protected] Полубелова Марина: [email protected]
Исходный код YaccConstructor:http://recursive-ascent.googlecode.comGoogle+ сообщество:https://plus.google.com/u/0/communities/102842370317111619055Сообщество GitHub: https://github.com/YaccConstructor
Григорьев Семён (JetBrains) 26 июня 2014г. 30 / 30