SlideShare a Scribd company logo
Теория и практика парсинга
формальных языков
Иван Кочуркин
Работаю в Positive Technologies над открытым
универсальным сигнатурным анализатором кода PT.PM
Подрабатываю в Swiftify, веб‐сервисе для конвертинга
кода Objective‐C в Swift
Веду активную деятельность на GitHub
Пишу статьи на Хабре и GitHub под ником KvanTTT
1
Почему не Regex?
1.  <table>(.*?)</table> 
2. А если аттрибуты?  <table.*?>(.*?)</table> 
3. А если элементы?  tr ,  td 
4. А если комментарии?  <!‐‐ html comment ‐‐> 
5. ...
6. NO NOO̼OO NΘ stop the an*̶͑̾̾̅ͫ
̙̤g͇̫
͛͆̾ͫ̑͆
l͖͉̗̩̳̟
̍ͫͥͨ
e̠̅s ͎a̧͈͖r̽̾̈́͒͑
e not rè̑ͧ̌
aͨl̘̝̙
̃ͤ
͂̾̆
ZA̡͊͠͝LGΌ ISͮ̂
҉̯͈͕̹̘̱
TO͇̹̺ͅ
Ɲ̴ȳ̳
TH̘Ë͖́̉
͠P̯͍̭O̚N̐Y̡H̸̡̪̯ͨ͊̽̅̾̎
E̾͛ͪ̈́̀́
̶̧̧̨̬̩̱̹̭̯͘
ͧ̾ͬ
C̷̙̲̝͖
ͭ̏ͥͮ
͟O̮̪̝͍ͮ
M̲̖͊̒ͪͩͬ̚̚
͜Ȇ̴̟̟͙̞
ͩ͌͝S̨̥̫͎̭
ͯ̿̔̀
ͅ
2
Лексемы и токены
Лексема ‐ распознанная последовательность символов
Токен ‐ лексема + тип
MyKeyword: 'var';
Id:        [a‐z]+;
Digit:     [0‐9]+;
Comment:   '<!‐‐' .*? '‐‐>';
Пример:
 TagOpen(<) Identifier(html) TagClose(>) Whitespace() 
3
Дерево разбора и AST
Дерево разбора ‐ древовидная структура, распознанная из
потока токенов
AST ‐ дерево разбора без пробелов, точек с запятых и т.д.
4
Типы парсеров
Готовые библиотеки парсинга ﴾regex, JSON.NET﴿
API
Только самые распространенные языки
Парсеры, написанные вручную ﴾Roslyn﴿
Большие возможности и гибкость
Большой порог вхождения
Медленная скорость разработки
Автоматически сгенерированные парсеры ﴾ANTLR﴿
Порог вхождения
Быстрая скорость разработки после освоения
Меньшая гибкость по сравнению с ручными
парсерами
5
Грамматика
Формальное описание языка, которое может быть
использовано для распознавания его структуры.
Пример грамматики
expr
    : expr '*' expr
    | expr '+' expr
    | ID '(' args ')'
    | ID
    ;
ID: [a‐zA‐Z]+;
Пример данных
a + b * c
6
Типы языков
Иерархия Хомского
Регулярные
Контекстно‐свободные
Контекстно‐зависимые
Тьюринг‐полные
Пример КС‐КЗ конструкции:  T a = new T() 
7
Инструменты и библиотеки под C#
Генераторы
Контекстно‐свободные ﴾ANTLR, Coco/R, Gardens Point
Parser Generator, Grammatica, Hime Parser Generator,
LLLPG﴿
Безлексерные PEG ﴾IronMeta, Pagarus﴿
Комбинаторы ﴾Parseq, Parsley, LanguageExt.Parsec, Sprache,
Superpower﴿
Языковые фреймворки ﴾JetBrains MPS, Nitra, Roslyn﴿
Детальное описание: Parsing In C#: Tools And Libraries.
8
Парсер-комбинаторы
Использование внутри языка разработки ﴾C#﴿
Использование в IDE
Библиотеки:
Sprache
Superpower
9
Примеры кода парсер-комбинатора
// Parse any number of capital 'A's in a row
var parseA = Parse.Char('A').AtLeastOnce();
Правило для  id :
Parser<string> identifier =
    from leading in Parse.WhiteSpace.Many()
    from first in Parse.Letter.Once()
    from rest in Parse.LetterOrDigit.Many()
    from trailing in Parse.WhiteSpace.Many()
    select new string(first.Concat(rest).ToArray());
var id = identifier.Parse(" abc123  ");
Assert.AreEqual("abc123", id);
10
Проблемы и задачи парсинга
На основе ANTLR и Roslyn.
Неоднозначность
Контекстно‐зависимые конструкции
Регистронезависимость
Островные языки и конструкции
Скрытые токены
Препроцессорные директивы
Парсинг фрагментов кода
Обработка и восстановление от ошибок
11
Неоднозначность
Пример:  var var = 100500; 
Решение с помощью грамматики
// Lexer
VAR: 'var';
ID:  [0‐9a‐zA‐Z];
// Parser
varDeclaration
    : VAR identifier ('=' expression)? ';'
    ;
identifier
    : ID
    // Other conflicted tokens
    | VAR;
12
Объектный конструктор в C#
class Foo
{
    public string Bar { get; set; }
}
public string Bar { get; set; } = "Bar2";
...
foo = new Foo
{
    Bar = Bar // Umbiguity here
};
13
Какой результат возвращает  nameof ?
class Foo
{
    public string Bar { get; set; }
}
static void Main(string[] args)
{
    var foo = new Foo();
    WriteLine(nameof(foo.Bar));
}
14
 nameof как функция и оператор
class Foo
{
    public string Bar { get; set; }
}
static void Main(string[] args)
{
    var foo = new Foo();
    WriteLine(nameof(foo.Bar));
}
static string nameof(string str)
{
    return "42";
}
15
Неоднозначность: решение с
использованием вставок кода
Действия ‐ производят вычисления на целевом языке
парсера.
Семантические предикаты ‐ возвращают результат.
// Lexer
ID:  [0‐9a‐zA‐Z];
// Parser
varDeclaration
    : id {_input.Lt(‐1).Text == "var"}? id ('=' expression)? ';'
    ;
id
    : ID;
16
Контекстно-зависимые конструкции
Heredoc в PHP или интерполируемые строки в C#
<?php
    echo <<< HeredocIdentifier
Line 1.
Line 2.
HeredocIdentifier
;
Решение
Использование вставок кода, смотри лексер PHP.
17
 $"Интерполируемые строки в C# {2+2*2}" 
WriteLine($"{p.Name} is "{p.Age} year{(p.Age == 1 ? "" : "s")} old"
WriteLine($"{(p.Age == 2 ? $"{new Person { } }" : "")}");
WriteLine($@"{p.Name}
           """);
WriteLine($"Color[R={func(b: 3):#0.##}, G={g:#0.##}, B={b:#0.##}
Реализация в лексере C#.
18
Регистронезависимость
Языки: Delphi, T‐SQL, PL/SQL и другие.
Решение с помощью грамматики
Фрагментный токен облегчает запись других токенов.
Abstract:           A B S T R A C T;
BoolType:           B O O L E A N | B O O L;
BooleanConstant:    T R U E | F A L S E;
fragment A: [aA];
fragment B: [bB];
Без использования фрагметных токенов:
Abstract:           [Aa][Bb][Ss][Tt][Rr][Aa][Cc][Tt];
19
Регистронезависимость: решение на
уровне рантайма
Abstract:           'ABSTRACT';
BoolType:           'BOOLEAN' | 'BOOL';
BooleanConstant:    'TRUE' | 'FALSE';
Используется CaseInsensitiveInputStream.
Чувствительные к регистру токены обрабатываются на этапе
обхода дерева. Например  $id и  $ID в PHP.
Достоинства:
Код лексера чище и проще
Производительность выше
20
Островные языки и конструкции
JavaScript внутри PHP или C# внутри Aspx.
<?php
<head>
  <script type="text/javascript">
    document.body.innerHTML="<svg/onload=alert(1)>"
  </script>
</head>
21
Островные языки и конструкции
Использовать режимы переключения лексем  mode .
Сначала парсинг PHP. Текст внутри тегов  <script> ‐
обычная строка.
Затем парсинг JavaScript во время обхода дерева.
22
PHP: альтернативный синтаксис
Смесь блоков кода на HTML и PHP
<?php switch($a): case 1: // without semicolon?>
        <br>
    <?php break ?>
    <?php case 2: ?>
        <br>
    <?php break;?>
    <?php case 3: ?>
        <br>
    <?php break;?>
<?php endswitch; ?>
23
Использование отдельного режима
лексем для JavaScript
//SCRIPT_BODY: .*? '</script>'; // "Жадная" версия
SCRIPT_BODY:   ~[<]+;
SCRIPT_CLOSE:  '</script>' ‐> popMode;
SCRIPT_DUMMY:  '<' ‐> type(SCRIPT_BODY);
 pushMode ‐ зайти в другой режим распознавания лексем
﴾JavaScript ‐> PHP﴿
 popMode ‐ выйти из режима ﴾PHP ‐> JavaScript﴿
 type ‐ изменить тип токена
 channel ‐ поместить токен в изолированный канал
﴾пробелы, комментарии﴿
24
Обработка  /*комментариев*/ и пр·б·лов
Включение скрытых токенов в грамматику
declaration:
    property COMMENT* COLON COMMENT* expr COMMENT* prio?;
Связывание скрытые токенов с правилами грамматики
﴾ANTLR, Swiftify﴿
Связывание скрытых токенов с основными ﴾Roslyn﴿
25
Связывание скрытых токенов с узлами
дерева (Swiftify)
Предшествующие (Precending)
//First comment
'{' /*Precending1*/ a = b; /*Precending2*/ b = c; '}'
Последующие (Following)
'{' a = b; b = c; /*Following*/ '}' /*Last comment*/
Токены-сироты (Orphans)
'{' /*Orphan*/ '}'
26
Связывание скрытых токенов со
значимыми (Roslyn)
Типы узлов Roslyn
Node ‐ не конечный узел дерева, содержащий детей
Token ‐ конечный узел ﴾keyword, id, литерал, пунктуация﴿
Trivia ‐ скрытый токен без родителя, связывается с  Token .
Лидирующие ﴾Leading﴿
Замыкающие ﴾Trailing﴿
// leading 1 (var)
// leading 2 (var)
var foo = 42; /*trailing (;)*/ int bar = 100500; //trailing (;)
// leading (EOF)
EOF
27
Препроцессорные директивы (Roslyn)
bool trueFlag =
#if NETCORE
    true
#else
    new Random().Next(100) > 95 ? true : false
#endif
;
Лидирующие для  true 
#if NETCORE
∙∙∙∙
Лидирующие для  ; 
#else
∙∙∙∙new Random().Next(100) > 95 ? true : false
#endif
28
Препроцессорные директивы:
одноэтапная обработка (Swiftify)
Одновременный парсинг директив и основного языка.
Каналы для изоляции токенов препроцессорных директив.
Интерпретация и обработка макросов вместе с функциями:
Objective-C
#define DEGREES_TO_RADIANS(degrees) (M_PI * (degrees) / 180)
Swift
func DEGREES_TO_RADIANS(degrees: Double)
   ‐> Double { return (.pi * degrees)/180; }
Пример на Swiftify.
29
Препроцессорные директивы:
двухэтапная обработка (Codebeat)
bool∙trueFlag∙=
∙∙∙∙∙∙∙∙∙
∙∙∙∙true
∙∙∙∙∙
∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙
∙∙∙∙∙∙
;
1. Токенизация и разбор кода препроцессорных диреткив.
2. Вычисление условных директив  #if и компилируемых
блоков кода.
3. Замена директив из исходника на пробелы.
4. Токенизация и парсинг результирующего текста.
30
Парсинг фрагментов кода (Swiftify)
Задача: определение корректного правила для
фрагмента кода
Применение
Конвертинг кода в плагине IDE ﴾в Swiftify для плагинов к
AppCode, XCode﴿
Определение языка программирования ﴾в PT.PM для
редактора Approof﴿
Решение
Регулярные выражения
Токенизация и операции с токенами
Парсинг разными правилами
Примеры: утверждения, декларации методов, свойства. 31
АОшибки парсинга
Лексическая ошибка
class # T { }
Отдельный канал:  ERROR: . ‐> channel(ErrorChannel) 
32
Ошибки парсинга
Отсутствующий и лишний токены
class T { // Отсутствующий токен
class T ; { } // Лишний токен
Несколько лишних токенов (режим «паники»)
class T { a b c }
Отсутствующее альтернативное подправило
33
Ошибки парсинга в Roslyn
namespace App
{
    class Program
    {
        static void void Main(string[] args)  // Invalid token
        {
            a                // ';' expected
            string s = """;  // Newline in constant
            char c = '';     // Empty character literal
        }
    }
}
34
Уязвимость goto fail
hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
hashOut.length = SSL_SHA1_DIGEST_LEN;
if ((err = SSLFreeBuffer(&hashCtx)) != 0)
    goto fail;
// ...
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
    goto fail;
    goto fail;  /* MISTAKE! THIS LINE SHOULD NOT BE HERE */
Способы выявления:
Анализ достоверного дерева разбора ﴾full fidelity﴿
Анализ графа потока управления ﴾CFG﴿
35
Заключение о парсинге
О чем не будет рассказываться:
Форматирование кода ﴾антипарсинг﴿
Автокомплит
Производительность
36
Обработка древовидных структур
Методы обхода
Архитектура и реализации Visitor и Listener
Фичи C# 7 на практике
Оптимизации
37
Методы обхода деревьев
Посетитель (Visitor)
Тип возвращаемого значения для каждого
правила. Например,  string для конвертера
исходных кодов ﴾Swiftify﴿.
Выборочный обход дочерних узлов.
Слушатель (Listener)
Посещает все узлы.
Ограниченный функционал: можно
использовать для подсчета простых метрик
кода.
38
Visitor & Listener
39
Реализации Visitor
Написанные вручную
Долгая и утомительная разработка
Сгенерированные (ANTLR)
Избыточность и нарушение Code Style
Доступны не всегда
Универсальность ﴾Java, C#, Python2|3, JS, C++, Go, Swift﴿
Скорость разработки
Динамические
Медленная скорость, но хорошо для прототипов
40
Диспетчеризация с использованием
рефлексии
// invocation in VisitChildren
Visit((dynamic)customNode);
// visit methods
public virtual T Visit(ExpressionStatement expressionStatement)
{
    return VisitChildren(expressionStatement);
}
public virtual T Visit(StringLiteral stringLiteral)
{
    return VisitChildren(stringLiteral);
}
41
Архитектура Visitor
Архитектура
Несколько маленьких. Создание визиторов при
необходимости.
Один большой с использованием  partial классов.
Формализация
Перегрузка всех методов и использование "заглушек"
throw new ShouldNotBeVisitedException(context);
42
C# 7: локальные функции
public static List<Terminal> GetLeafs(this Rule node)
{
    var result = new List<TerminalNode>();
    GetLeafs(node, result);
    // Local function
    void GetLeafs(Rule localNode, List<Terminal> localResult)
    {
        for (int i = 0; i < localNode.ChildCount; ++i)
        {
            IParseTree child = localNode.GetChild(i);
            // Is expression
            if (child is TerminalNode typedChild)
                localResult.Add(typedChild);
            GetLeafs(child, localResult);
        }
    }
    return result;
}
43
Оптимизации
Мемоизация
Поиск первого потомка определенного типа
 FirstDescendantOfType .
Хранение всех потомков для каждого узла дерева вместо
их поиска.
Увеличение производительности в 2‐3 раза.
Увеличение потребления памяти в 3 раза.
Уменьшение аллокаций
Метод  Visit ‐ базовый, он часто вызывается.
44
Ресурсы
Исходники презентации и примеров.
Статьи:
Теория и практика парсинга исходников с помощью
ANTLR и Roslyn
Обработка препроцессорных директив в Objective‐C
Движок поиска по шаблонам PT.PM и грамматики
grammars‐v4 ﴾PL/SQL, T‐SQL, PHP, C#, Java8, Objective‐C﴿.
45
Выводы
Парсинг ‐ это не так просто как кажется
Существуют языки с различной выразительностью и
синтаксисом
На C# можно пользоваться разными методами и
библиотеками парсинга
ANTLR предоставляет широкие возможности по разработке
парсеров
Roslyn очень продуман в построении дерева, но только C#
и VB
Деревья можно обрабатывать разными способами
46
Вопросы?
Positive Technologies на GitHub
Swiftify
47

More Related Content

What's hot

Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++
corehard_by
 
Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...
Sergey Vasilyev
 
C++ idioms
C++ idiomsC++ idioms
C++ idioms
COMAQA.BY
 
Отладка в Python: 2016 edition
Отладка в Python: 2016 editionОтладка в Python: 2016 edition
Отладка в Python: 2016 edition
Кирилл Борисов
 
Mixing c++ and python
Mixing c++ and pythonMixing c++ and python
Mixing c++ and python
corehard_by
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Platonov Sergey
 
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
Python Meetup
 
Способы записи алгоритмов
Способы записи алгоритмовСпособы записи алгоритмов
Способы записи алгоритмов
Andrey Dolinin
 
Профессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом EnterpriseПрофессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом Enterprise
Alexander Granin
 
Общие сведения о языке программирования Паскаль
Общие сведения о языке программирования ПаскальОбщие сведения о языке программирования Паскаль
Общие сведения о языке программирования Паскаль
Andrey Dolinin
 
Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...
Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...
Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...
Tech Talks @NSU
 
Презентация. Основы Pascal
Презентация. Основы PascalПрезентация. Основы Pascal
Презентация. Основы PascalEvgen67
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
corehard_by
 
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр КоротковPG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
pgdayrussia
 
SECON'2016. Ефимов Максим, JMM в Android
SECON'2016.  Ефимов Максим, JMM в AndroidSECON'2016.  Ефимов Максим, JMM в Android
SECON'2016. Ефимов Максим, JMM в Android
SECON
 
Основы ооп на языке C#. Часть 2. базовый синтаксис.
Основы ооп на языке C#. Часть 2. базовый синтаксис.Основы ооп на языке C#. Часть 2. базовый синтаксис.
Основы ооп на языке C#. Часть 2. базовый синтаксис.
YakubovichDA
 
паскаль
паскальпаскаль
паскаль
Гимназия
 
«JMM в Android», Максим Ефимов, Redmadrobot
«JMM в Android», Максим Ефимов, Redmadrobot«JMM в Android», Максим Ефимов, Redmadrobot
«JMM в Android», Максим Ефимов, Redmadrobot
Mail.ru Group
 
Перевод на русский язык: отрыв от оригинала и адаптация перевода
Перевод на русский язык: отрыв от оригинала и адаптация переводаПеревод на русский язык: отрыв от оригинала и адаптация перевода
Перевод на русский язык: отрыв от оригинала и адаптация перевода
Eugene Bartov
 

What's hot (19)

Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++Компилируемые в реальном времени DSL для С++
Компилируемые в реальном времени DSL для С++
 
Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...Правила статического анализа кода для диагностики потенциально опасных констр...
Правила статического анализа кода для диагностики потенциально опасных констр...
 
C++ idioms
C++ idiomsC++ idioms
C++ idioms
 
Отладка в Python: 2016 edition
Отладка в Python: 2016 editionОтладка в Python: 2016 edition
Отладка в Python: 2016 edition
 
Mixing c++ and python
Mixing c++ and pythonMixing c++ and python
Mixing c++ and python
 
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотекSWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
SWIG — cоздание мультиязыковых интерфейсов для C/C++ библиотек
 
Способы записи алгоритмов
Способы записи алгоритмовСпособы записи алгоритмов
Способы записи алгоритмов
 
Профессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом EnterpriseПрофессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом Enterprise
 
Общие сведения о языке программирования Паскаль
Общие сведения о языке программирования ПаскальОбщие сведения о языке программирования Паскаль
Общие сведения о языке программирования Паскаль
 
Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...
Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...
Tech Talks @NSU: Back to the Future: Функциональное программирование вчера и ...
 
Презентация. Основы Pascal
Презентация. Основы PascalПрезентация. Основы Pascal
Презентация. Основы Pascal
 
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
C++ CoreHard Autumn 2018. Что не умеет оптимизировать компилятор - Александр ...
 
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр КоротковPG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
 
SECON'2016. Ефимов Максим, JMM в Android
SECON'2016.  Ефимов Максим, JMM в AndroidSECON'2016.  Ефимов Максим, JMM в Android
SECON'2016. Ефимов Максим, JMM в Android
 
Основы ооп на языке C#. Часть 2. базовый синтаксис.
Основы ооп на языке C#. Часть 2. базовый синтаксис.Основы ооп на языке C#. Часть 2. базовый синтаксис.
Основы ооп на языке C#. Часть 2. базовый синтаксис.
 
паскаль
паскальпаскаль
паскаль
 
«JMM в Android», Максим Ефимов, Redmadrobot
«JMM в Android», Максим Ефимов, Redmadrobot«JMM в Android», Максим Ефимов, Redmadrobot
«JMM в Android», Максим Ефимов, Redmadrobot
 
Перевод на русский язык: отрыв от оригинала и адаптация перевода
Перевод на русский язык: отрыв от оригинала и адаптация переводаПеревод на русский язык: отрыв от оригинала и адаптация перевода
Перевод на русский язык: отрыв от оригинала и адаптация перевода
 

Similar to Иван Кочуркин. Теория и практика парсинга формальных языков

ekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питонеekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питонеit-people
 
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
Mail.ru Group
 
«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...
«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...
«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...
MoscowJS
 
введение
введениевведение
введение
AndEdr
 
Cреда программирования
Cреда программированияCреда программирования
Cреда программированияirina8682
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Yandex
 
Opensource на .NET
Opensource на .NETOpensource на .NET
Opensource на .NET
lugnsk
 
лекция 4
лекция 4лекция 4
[RU] Connecting AutoCAD and Python (by Alex Bausk)
[RU] Connecting AutoCAD and Python (by Alex Bausk)[RU] Connecting AutoCAD and Python (by Alex Bausk)
[RU] Connecting AutoCAD and Python (by Alex Bausk)
Alexander Bausk
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть II
Python Meetup
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
Alexander Shigin
 
Step cpp0201
Step cpp0201Step cpp0201
Step cpp0201
Evgenij Laktionov
 
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studioчто пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
corehard_by
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
Andrey Karpov
 
Algorithms and programming lecture in ru
Algorithms and programming lecture in ruAlgorithms and programming lecture in ru
Algorithms and programming lecture in ru
ssuser0562f1
 
Алгоритмизация и программирование С/С++
Алгоритмизация и  программирование С/С++Алгоритмизация и  программирование С/С++
Алгоритмизация и программирование С/С++
ssuser0562f1
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — Lua
Yury Yurevich
 
Сущность библиотеки анализа кода VivaCore
Сущность библиотеки анализа кода VivaCoreСущность библиотеки анализа кода VivaCore
Сущность библиотеки анализа кода VivaCore
Tatyanazaxarova
 
static - defcon russia 20
static  - defcon russia 20static  - defcon russia 20
static - defcon russia 20
DefconRussia
 

Similar to Иван Кочуркин. Теория и практика парсинга формальных языков (20)

ekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питонеekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
 
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
 
«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...
«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...
«Пуленепробиваемый фронтенд: разработка под React на TypeScript», Станислав П...
 
введение
введениевведение
введение
 
Cреда программирования
Cреда программированияCреда программирования
Cреда программирования
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
 
Opensource на .NET
Opensource на .NETOpensource на .NET
Opensource на .NET
 
python vs ruby
python vs rubypython vs ruby
python vs ruby
 
лекция 4
лекция 4лекция 4
лекция 4
 
[RU] Connecting AutoCAD and Python (by Alex Bausk)
[RU] Connecting AutoCAD and Python (by Alex Bausk)[RU] Connecting AutoCAD and Python (by Alex Bausk)
[RU] Connecting AutoCAD and Python (by Alex Bausk)
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть II
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
Step cpp0201
Step cpp0201Step cpp0201
Step cpp0201
 
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studioчто пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
что пришлось тестировать и о чем узнать при подготовке Linux версии pvs-studio
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
 
Algorithms and programming lecture in ru
Algorithms and programming lecture in ruAlgorithms and programming lecture in ru
Algorithms and programming lecture in ru
 
Алгоритмизация и программирование С/С++
Алгоритмизация и  программирование С/С++Алгоритмизация и  программирование С/С++
Алгоритмизация и программирование С/С++
 
Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — Lua
 
Сущность библиотеки анализа кода VivaCore
Сущность библиотеки анализа кода VivaCoreСущность библиотеки анализа кода VivaCore
Сущность библиотеки анализа кода VivaCore
 
static - defcon russia 20
static  - defcon russia 20static  - defcon russia 20
static - defcon russia 20
 

More from MskDotNet Community

Антон Сысоев «IIoT: на границе HW и .NET»
Антон Сысоев «IIoT: на границе HW и .NET»Антон Сысоев «IIoT: на границе HW и .NET»
Антон Сысоев «IIoT: на границе HW и .NET»
MskDotNet Community
 
Николай Гусев «Функциональное программирование для C# разработчиков»
 Николай Гусев «Функциональное программирование для C# разработчиков» Николай Гусев «Функциональное программирование для C# разработчиков»
Николай Гусев «Функциональное программирование для C# разработчиков»
MskDotNet Community
 
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
MskDotNet Community
 
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовЮлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
MskDotNet Community
 
Владимир Кочетков "OWASP TOP 10 для.NET"
Владимир Кочетков  "OWASP TOP 10 для.NET"Владимир Кочетков  "OWASP TOP 10 для.NET"
Владимир Кочетков "OWASP TOP 10 для.NET"
MskDotNet Community
 
Дмитрий Сошников Искусственный интеллект и нейросети для .NET-разработчиков
Дмитрий Сошников    Искусственный интеллект и нейросети для .NET-разработчиковДмитрий Сошников    Искусственный интеллект и нейросети для .NET-разработчиков
Дмитрий Сошников Искусственный интеллект и нейросети для .NET-разработчиков
MskDotNet Community
 
Викторина MskDotNet Субботник
Викторина MskDotNet СубботникВикторина MskDotNet Субботник
Викторина MskDotNet Субботник
MskDotNet Community
 
Елизавета Голенок Переходим на mono или как это было
Елизавета Голенок  Переходим на mono или как это былоЕлизавета Голенок  Переходим на mono или как это было
Елизавета Голенок Переходим на mono или как это было
MskDotNet Community
 
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
MskDotNet Community
 
Павел Притчин "Конфигурации в.NET"
Павел Притчин  "Конфигурации в.NET"Павел Притчин  "Конфигурации в.NET"
Павел Притчин "Конфигурации в.NET"
MskDotNet Community
 
Андрей Кирпичев "Гибкая модульность инструментами АОП"
Андрей Кирпичев  "Гибкая модульность инструментами АОП"Андрей Кирпичев  "Гибкая модульность инструментами АОП"
Андрей Кирпичев "Гибкая модульность инструментами АОП"
MskDotNet Community
 
Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
 Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере" Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
MskDotNet Community
 
Андрей Матвеев "Основные принципы микросервисов и их реализации"
Андрей Матвеев "Основные принципы микросервисов и их реализации"Андрей Матвеев "Основные принципы микросервисов и их реализации"
Андрей Матвеев "Основные принципы микросервисов и их реализации"
MskDotNet Community
 
Александр Сурков «Вещи» в «Интернете вещей»
Александр Сурков «Вещи» в «Интернете вещей»Александр Сурков «Вещи» в «Интернете вещей»
Александр Сурков «Вещи» в «Интернете вещей»
MskDotNet Community
 
Петр Тимошевский «Industrial IoT на практике»
Петр Тимошевский «Industrial IoT на практике»Петр Тимошевский «Industrial IoT на практике»
Петр Тимошевский «Industrial IoT на практике»
MskDotNet Community
 
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
MskDotNet Community
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»
MskDotNet Community
 
Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»
MskDotNet Community
 
Владимир Кошелев «Автоматический поиск ошибок»
Владимир Кошелев «Автоматический поиск ошибок»Владимир Кошелев «Автоматический поиск ошибок»
Владимир Кошелев «Автоматический поиск ошибок»
MskDotNet Community
 

More from MskDotNet Community (19)

Антон Сысоев «IIoT: на границе HW и .NET»
Антон Сысоев «IIoT: на границе HW и .NET»Антон Сысоев «IIoT: на границе HW и .NET»
Антон Сысоев «IIoT: на границе HW и .NET»
 
Николай Гусев «Функциональное программирование для C# разработчиков»
 Николай Гусев «Функциональное программирование для C# разработчиков» Николай Гусев «Функциональное программирование для C# разработчиков»
Николай Гусев «Функциональное программирование для C# разработчиков»
 
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
Кирилл Ветчинкин Практика использования .NET Core на ОС Linux с применением а...
 
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовЮлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
 
Владимир Кочетков "OWASP TOP 10 для.NET"
Владимир Кочетков  "OWASP TOP 10 для.NET"Владимир Кочетков  "OWASP TOP 10 для.NET"
Владимир Кочетков "OWASP TOP 10 для.NET"
 
Дмитрий Сошников Искусственный интеллект и нейросети для .NET-разработчиков
Дмитрий Сошников    Искусственный интеллект и нейросети для .NET-разработчиковДмитрий Сошников    Искусственный интеллект и нейросети для .NET-разработчиков
Дмитрий Сошников Искусственный интеллект и нейросети для .NET-разработчиков
 
Викторина MskDotNet Субботник
Викторина MskDotNet СубботникВикторина MskDotNet Субботник
Викторина MskDotNet Субботник
 
Елизавета Голенок Переходим на mono или как это было
Елизавета Голенок  Переходим на mono или как это былоЕлизавета Голенок  Переходим на mono или как это было
Елизавета Голенок Переходим на mono или как это было
 
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...Дмитрий Тежельников  «Разработка вэб-решений с использованием Asp.NET.Core и ...
Дмитрий Тежельников «Разработка вэб-решений с использованием Asp.NET.Core и ...
 
Павел Притчин "Конфигурации в.NET"
Павел Притчин  "Конфигурации в.NET"Павел Притчин  "Конфигурации в.NET"
Павел Притчин "Конфигурации в.NET"
 
Андрей Кирпичев "Гибкая модульность инструментами АОП"
Андрей Кирпичев  "Гибкая модульность инструментами АОП"Андрей Кирпичев  "Гибкая модульность инструментами АОП"
Андрей Кирпичев "Гибкая модульность инструментами АОП"
 
Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
 Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере" Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
Даниил Соколюк "ReactJS.NET — опыт рендеринга на сервере"
 
Андрей Матвеев "Основные принципы микросервисов и их реализации"
Андрей Матвеев "Основные принципы микросервисов и их реализации"Андрей Матвеев "Основные принципы микросервисов и их реализации"
Андрей Матвеев "Основные принципы микросервисов и их реализации"
 
Александр Сурков «Вещи» в «Интернете вещей»
Александр Сурков «Вещи» в «Интернете вещей»Александр Сурков «Вещи» в «Интернете вещей»
Александр Сурков «Вещи» в «Интернете вещей»
 
Петр Тимошевский «Industrial IoT на практике»
Петр Тимошевский «Industrial IoT на практике»Петр Тимошевский «Industrial IoT на практике»
Петр Тимошевский «Industrial IoT на практике»
 
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
Стас Павлов «Построение безопасной архитектуры IoT решений на примере Azure I...
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»
 
Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»Кирилл Маурин «Проектирование и разработка модульных приложений»
Кирилл Маурин «Проектирование и разработка модульных приложений»
 
Владимир Кошелев «Автоматический поиск ошибок»
Владимир Кошелев «Автоматический поиск ошибок»Владимир Кошелев «Автоматический поиск ошибок»
Владимир Кошелев «Автоматический поиск ошибок»
 

Иван Кочуркин. Теория и практика парсинга формальных языков