diff --git a/book.md b/book.md index cafaa1c..e9ba17e 100644 --- a/book.md +++ b/book.md @@ -84,14 +84,206 @@ Данные методы составляют основной программный интерфейс для внешней по отношению к парсеру системы. Позволяют выполнить разбор исходного кода, обход AST с плагинами и выполнить модификацию исходного кода по сгенерированным плагинами заменам. Чаще всего используется метод `Пуск()`, который заключает в себе типовую последовательность вызовов `Разобрать()`, `Подключить()` и `Посетить()`. -Примеры использования данных методов смотрите в скриптах в папке /oscript - -* `Пуск(Исходник: Строка, Плагины: Массив или Обработка, Параметры: Соответствие, Окружение: Структура): Массив` - выполняет разбор исходника в указанном окружении, обход AST с указанными плагинами и указанными параметрами плагинов, возвращает результаты (обычно текстовые) работы плагинов. -* `Разобрать(Исходник: Строка, ВнешнееОкружение: Структура): Структура` - выполняет разбор исходника в указанном окружении и возвращает AST. -* `Подключить(Плагины: Массив или Обработка)` - подключает плагины к парсеру. -* `Посетить(Модуль: Структура, Параметры: Соответствие)` - выполняет обход AST с подключенными плагинами и указанными параметрами плагинов. -* `Токенизировать(Исходник: Строка): ТаблицаЗначений` - выполняет лексический анализ и возвращает таблицу токенов. -* `ВыполнитьЗамены(): Строка` - возвращает исходник после выполнения на нем замен участков текста. +Рабочие примеры использования данных методов смотрите в скриптах в папке /oscript + +* **`Пуск(Исходник, Плагины, Параметры, Окружение): Массив`** - выполняет разбор исходника в указанном окружении, обход AST с указанными плагинами и их параметрами и возвращает результаты (обычно текстовые) работы плагинов. + + Параметры: + * `Исходник: Строка` -- исходный код для анализа. + * `Плагины: Массив или Обработка` -- плагины, с которыми будет выполняться обход AST. + * `Параметры: Соответствие (необязательный)` -- параметры плагинов. + * `Окружение: Структура (необязательный)` -- окружение (контекст), в котором будет выполняться разбор исходника. + + Пример с одним плагином: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + Парсер.Пуск(Исходник, Плагин); // тут выполняется синтаксический анализ и обход АСД с плагинами + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + + Пример с набором плагинов: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Плагины = Новый Массив; + Плагины.Добавить(ВнешниеОбработки.Создать(Плагин1Путь, Ложь)); + Плагины.Добавить(ВнешниеОбработки.Создать(Плагин2Путь, Ложь)); + + Парсер.Пуск(Исходник, Плагины); // тут выполняется синтаксический анализ и обход АСД с плагинами + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагинами ошибок + КонецЦикла; + ``` + + Пример с параметрами плагинов: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин1 = ВнешниеОбработки.Создать(Плагин1Путь, Ложь); + Плагин2 = ВнешниеОбработки.Создать(Плагин2Путь, Ложь); + + Плагины = Новый Массив; + Плагины.Добавить(Плагин1); + Плагины.Добавить(Плагин2); + + Параметры = Новый Соответствие; // у каждого плагина своя структура параметров + Параметры[Плагин1.ЭтотОбъект] = Новый Структура("Параметр1, Параметр2", 1, 2); + Параметры[Плагин2.ЭтотОбъект] = Новый Структура("Параметр1, Параметр2", 3, 4) + + Парсер.Пуск(Исходник, Плагины, Параметры); // тут выполняется синтаксический анализ и обход АСД с плагинами + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагинами ошибок + КонецЦикла; + ``` + + Пример с окружением: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь)); + + Окружение = Парсер.Окружение(); + + // например, контекст формы: + Элемент = Парсер.ЭлементОкружения("ЭтаФорма"); + Окружение.Переменные.Вставить("ЭтаФорма", Элемент); // добавили в контекст переменную + // ... + Элемент = Парсер.ЭлементОкружения("РеквизитФормыВЗначение"); + Окружение.Методы.Вставить("РеквизитФормыВЗначение", Элемент); // добавили в контекст метод + // ... + + Парсер.Пуск(Исходник, Плагины,, Окружение); + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + +* **`Разобрать(Исходник, Окружение): Структура`** - выполняет разбор исходника в указанном окружении и возвращает AST. + + Параметры: + * `Исходник: Строка` -- исходный код для анализа. + * `Окружение: Структура (необязательный)` -- окружение (контекст), в котором будет выполняться разбор исходника. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + Окружение = Парсер.Окружение(); + + // например, контекст формы: + Элемент = Парсер.ЭлементОкружения("ЭтаФорма"); + Окружение.Переменные.Вставить("ЭтаФорма", Элемент); // добавили в контекст переменную + // ... + Элемент = Парсер.ЭлементОкружения("РеквизитФормыВЗначение"); + Окружение.Методы.Вставить("РеквизитФормыВЗначение", Элемент); // добавили в контекст метод + // ... + + АСД = Парсер.Разобрать(Исходник, Окружение); + + Сообщить(АСД.Объявления.Количество()); + ``` + +* **`Подключить(Плагины)`** - подключает плагины к парсеру. + + Параметры: + * `Плагины: Массив или Обработка` -- плагины для подключения к парсеру. + + Пример: + + ```bsl + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + АСД = Парсер.Разобрать(Исходник); // тут выполняется синтаксический анализ + Парсер.Подключить(Плагин); // тут плагин подключается к парсеру + Парсер.Посетить(АСД); // тут выполняется обход АСД с вызовом подписок плагина + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + +* **`Посетить(Модуль: Структура, Параметры: Соответствие)`** - выполняет обход AST с подключенными плагинами и указанными параметрами плагинов. + + Параметры: + * `Модуль: Структура` -- АСД для обхода. + * `Параметры: Соответствие (необязательный)` -- параметры плагинов, с которыми нужно выполнить обход. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + АСД = Парсер.Разобрать(Исходник); // тут выполняется синтаксический анализ + Парсер.Подключить(Плагин); // тут плагин подключается к парсеру + Парсер.Посетить(АСД); // тут выполняется обход АСД с вызовом подписок плагина + + Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл + Сообщить(Ошибка.Текст); // вывод найденных парсером и плагином ошибок + КонецЦикла; + ``` + +* **`Токенизировать(Исходник: Строка): ТаблицаЗначений`** - выполняет лексический анализ и возвращает таблицу токенов. + + Параметры: + * `Исходник: Строка` -- исходный код для анализа. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + + ТаблицаТокенов = Парсер.Токенизировать(Исходник); // тут выполняется лексический анализ + + Для Каждого ДанныеТокена Из ТаблицаТокенов Цикл + Сообщить(ДанныеТокена.Токен); // вывод всех токенов + КонецЦикла; + ``` + +* **`ВыполнитьЗамены(): Строка`** - возвращает исходник после выполнения на нем замен участков текста. + + Пример: + + ```bsl + Исходник = ЧтениеТекста.Прочитать(); + + Парсер = ВнешниеОбработки.Создать(ПарсерПуть, Ложь); + Плагин = ВнешниеОбработки.Создать(ПлагинПуть, Ложь); + + Парсер.Пуск(Исходник, Плагин); // тут плагин наполняет таблицу замен + + ИсправленныйИсходник = Парсер.ВыполнитьЗамены(); // тут по таблице замен последовательно заменяются участки текста в исходнике. + + Сообщить(ИсправленныйИсходник) + ``` #### Дополнительные методы @@ -99,19 +291,324 @@ Примеры использования данных методов смотрите в плагинах в папке /plugins -* `КлючевыеСлова(): Структура` - возвращает перечисление допустимых ключевых слов (например: `КлючевыеСлова.ИначеЕсли`). -* `Токены(): Структура` - возвращает перечисление допустимых токенов (например: `Токены.ЗнакСложения`). -* `Типы(): Структура` - возвращает перечисление допустимых типов узлов AST (например: `Типы.ОператорПрисваивания`). -* `Директивы(): Структура` - возвращает перечисление допустимых директив (например: `Директивы.НаСервереБезКонтекста`). -* `Аннотации(): Структура` - возвращает перечисление допустимых аннотаций (например: `Аннотации.Вместо`). -* `ИнструкцииПрепроцессора(): Структура` - возвращает перечисление допустимых инструкций препроцессора (например: `ИнструкцииПрепроцессора.КонецОбласти`). -* `СимволыПрепроцессора(): Структура` - возвращает перечисление допустимых символов препроцессора (например: `СимволыПрепроцессора.ТолстыйКлиентОбычноеПриложение`). -* `Стек(): Массив` - возвращает стек узлов, который меняется во время обхода AST и позволяет получить текущие родительские узлы в подписках плагинов. -* `Счетчики(): Соответствие` - возвращает счетчики родительских узлов, которые меняются во время обхода AST и позволяет получить количество текущих родительских узлов по типам в подписках плагинов. -* `Исходник(): Строка` - возвращает текущий исходник. -* `ТаблицаТокенов(): ТаблицаЗначений` - возвращает текущую таблицу токенов, которая содержит подробную информацию о положении каждого токена в исходном коде. Каждый узел AST имеет поля `Начало` и `Конец`, которые хранят строки данной таблицы и представляют первый и последний токен узла. Например, получить номер первой строки узла можно так: `НомерСтроки = Узел.Начало.НомерСтроки`. Получить следующий за узлом токен можно так: `ДанныеСледующегоТокена = ТаблицаТокенов[Узел.Конец.Индекс + 1]`. -* `ТаблицаЗамен(): ТаблицаЗначений` - возвращает текущую таблицу замен, в которой плагины могут регистрировать замены. -* `ТаблицаОшибок(): ТаблицаЗначений` - возвращает текущую таблицу ошибок, в которой плагины могут регистрировать ошибки. +* **`КлючевыеСлова(): Структура`** - возвращает перечисление допустимых ключевых слов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем ТаблицаТокенов, КлючевыеСлова; + + Процедура Открыть(Парсер, Параметры) Экспорт + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КлючевыеСлова = Парсер.КлючевыеСлова(); + КонецПроцедуры + + Функция Закрыть() Экспорт + Для Каждого ДанныеТокена Из ТаблицаТокенов Цикл + Если ДанныеТокена.Токен = КлючевыеСлова.ИначеЕсли Тогда + // ... + КонецЕсли; + КонецЦикла; + Возврат Неопределено; + КонецФункции + ``` + +* **`Токены(): Структура`** - возвращает перечисление допустимых токенов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем ТаблицаТокенов, Токены; + + Процедура Открыть(Парсер, Параметры) Экспорт + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + Токены = Парсер.Токены(); + КонецПроцедуры + + Функция Закрыть() Экспорт + Для Каждого ДанныеТокена Из ТаблицаТокенов Цикл + Если ДанныеТокена.Токен = Токены.ЗнакСложения Тогда + // ... + КонецЕсли; + КонецЦикла; + Возврат Неопределено; + КонецФункции + ``` + +* **`Типы(): Структура`** - возвращает перечисление допустимых типов узлов AST. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Типы; + + Процедура Открыть(Парсер, Параметры) Экспорт + Типы = Парсер.Типы(); + КонецПроцедуры + + Процедура ПосетитьОператоры(Операторы) Экспорт + Для Каждого Оператор Из Операторы Цикл + Если Оператор.Тип = Типы.ОператорПрисваивания Тогда + // ... + КонецЕсли; + КонецЦикла; + КонецПроцедуры + ``` + +* **`Директивы(): Структура`** - возвращает перечисление допустимых директив. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Директивы; + + Процедура Открыть(Парсер, Параметры) Экспорт + Директивы = Парсер.Директивы(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеПеременнойМодуля(Объявление) Экспорт + Если Объявление.Директивы.Количество() = 1 + И Объявление[0].Директива = Директивы.НаКлиенте Тогда + // ... + КонецЕсли; + КонецПроцедуры + ``` + +* **`Аннотации(): Структура`** - возвращает перечисление допустимых аннотаций. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Аннотации; + + Процедура Открыть(Парсер, Параметры) Экспорт + Аннотации = Парсер.Аннотации(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(Объявление) Экспорт + Аннотации = Объявление.Сигнатура.Аннотации; + Если Аннотации.Количество() = 1 + И Аннотации[0].Аннотация = Аннотации.Вместо Тогда + // ... + КонецЕсли; + КонецПроцедуры + ``` + +* **`СимволыПрепроцессора(): Структура`** - возвращает перечисление допустимых символов препроцессора. + + Пример (фрагмент кода плагина): + + ```bsl + Перем СимволыПрепроцессора; + + Процедура Открыть(Парсер, Параметры) Экспорт + СимволыПрепроцессора = Парсер.СимволыПрепроцессора(); + КонецПроцедуры + + Процедура ПосетитьВыражениеПрепроцессораСимвол(Выражение) Экспорт + Если Выражение.Символ = СимволыПрепроцессора.ТолстыйКлиентОбычноеПриложение Тогда + // ... + КонецЕсли; + КонецПроцедуры + ``` + +* **`Стек(): Массив`** - возвращает стек узлов, который меняется во время обхода AST и позволяет получить текущие родительские узлы в подписках плагинов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Стек; + + Процедура Открыть(Парсер, Параметры) Экспорт + Стек = Парсер.Стек(); + КонецПроцедуры + + Процедура ПосетитьВыражениеТернарное(Выражение) Экспорт + Для Каждого Родитель Из Стек Цикл + Если Родитель.Тип = Типы.ВыражениеТернарное Тогда + Сообщить("Вложенный тернарный оператор"); + Прервать; + КонецЕсли; + КонецЦикла; + КонецПроцедуры + ``` + +* **`Счетчики(): Соответствие`** - возвращает счетчики родительских узлов, которые меняются во время обхода AST и позволяет получить количество текущих родительских узлов по типам в подписках плагинов. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Счетчики; + + Процедура Открыть(Парсер, Параметры) Экспорт + Счетчики = Парсер.Счетчики(); + КонецПроцедуры + + Процедура ПосетитьВыражениеТернарное(Выражение) Экспорт + Если Счетчики[Типы.ВыражениеТернарное] > 0 Тогда + Сообщить("Вложенный тернарный оператор"); + КонецЕсли; + КонецПроцедуры + ``` + +* **`Исходник(): Строка`** - возвращает текущий исходник. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + ДанныеСледующегоТокена = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + Если ДанныеСледующегоТокена.Токен = Токены.Комментарий Тогда + Сообщить(Сред(Исходник, ДанныеСледующегоТокена.Позиция, ДанныеСледующегоТокена.Длина)); + КонецЕсли; + КонецПроцедуры + ``` + +* **`ТаблицаТокенов(): ТаблицаЗначений`** - возвращает текущую таблицу токенов, которая содержит подробную информацию о положении каждого токена в исходном коде. Каждый узел AST имеет поля `Начало` и `Конец`, которые хранят строки данной таблицы и представляют первый и последний токен узла. Например, получить номер первой строки узла можно так: `НомерСтроки = Узел.Начало.НомерСтроки`. Получить следующий за узлом токен можно так: `ДанныеСледующегоТокена = ТаблицаТокенов[Узел.Конец.Индекс + 1]`. + + Колонки: + * `Индекс: Число` -- индекс строки для удобства. + * `Токен: Строка` -- токен из перечисления Токены. + * `НомерСтроки: Число` -- номер строки, в которой находится токен. + * `НомерКолонки: Число` -- номер колонки, в которой начинается токен. + * `Позиция: Число` -- позиция в тексте, в которой начинается токен. + * `Длина: Число` -- длина участка текста, который представляет токен. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + ДанныеСледующегоТокена = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + Если ДанныеСледующегоТокена.Токен = Токены.Комментарий Тогда + Сообщить(Сред(Исходник, ДанныеСледующегоТокена.Позиция, ДанныеСледующегоТокена.Длина)); + КонецЕсли; + КонецПроцедуры + ``` + +* **`ТаблицаОшибок(): ТаблицаЗначений`** - возвращает текущую таблицу ошибок, в которой плагины могут регистрировать ошибки. + + Колонки: + * `Источник: Строка` -- имя обработки, которая зарегистрировала ошибку. + * `Текст: Строка` -- текст ошибки + * `ПозицияНачала: Число` -- позиция в тексте, с которой начинается ошибочный участок. + * `ПозицияКонца: Число` -- позиция в тексте, на которой заканчивается ошибочный участок. + * `ЕстьЗамена: Булево` -- признак, что для ошибки есть замена (исправление) в таблице замен. + * `Код: Число` -- код ошибки (для плагинов всегда 0). + * `НомерСтрокиНачала: Число` -- номер строки, на которой начинается ошибочный участок. + * `НомерКолонкиНачала: Число` -- номер колонки, с которой начинается ошибочный участок. + * `НомерСтрокиКонца: Число` -- номер строки, на которой заканчивается ошибочный участок. + * `НомерКолонкиКонца: Число` -- номер колонки, на которой заканчивается ошибочный участок. + * `МинутНаИсправление: Число` -- примерная оценка затрат на исправление ошибки в минутах. + * `Серьезность: Строка` -- произвольный текст на усмотрение разработчика. + * `Приоритет: Число` -- произвольное число на усмотрение разработчика. + * `Правило: Строка` -- произвольный текст на усмотрение разработчика. + * `Тип: Строка` -- произвольный текст на усмотрение разработчика. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + + СледующийТокен = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + + Если СледующийТокен.Токен = Токены.Комментарий + И СледующийТокен.НомерСтроки = ОбъявлениеМетода.Конец.НомерСтроки Тогда + + Комментарий = СокрП(Сред(Исходник, СледующийТокен.Позиция, СледующийТокен.Длина)); + ПравильныйКомментарий = СтрШаблон(" %1%2", ОбъявлениеМетода.Сигнатура.Имя, "()"); + + Если Комментарий <> ПравильныйКомментарий Тогда + Ошибка("Замыкающий комментарий неактуален", СледующийТокен); + КонецЕсли; + + КонецЕсли; + + КонецПроцедуры + + Процедура Ошибка(Текст, ДанныеТокена) + Ошибка = ТаблицаОшибок.Добавить(); + Ошибка.Источник = "ИмяЭтогоПлагина"; + Ошибка.Текст = Текст; + Ошибка.ПозицияНачала = ДанныеТокена.Позиция; + Ошибка.НомерСтрокиНачала = ДанныеТокена.НомерСтроки; + Ошибка.НомерКолонкиНачала = ДанныеТокена.НомерКолонки; + Ошибка.ПозицияКонца = ДанныеТокена.Позиция + ДанныеТокена.Длина; + Ошибка.НомерСтрокиКонца = ДанныеТокена.НомерСтроки; + Ошибка.НомерКолонкиКонца = ДанныеТокена.НомерКолонки + ДанныеТокена.Длина; + КонецПроцедуры + + ``` + +* **`ТаблицаЗамен(): ТаблицаЗначений`** - возвращает текущую таблицу замен, в которой плагины могут регистрировать замены. + + Колонки: + * `Источник: Число` -- имя обработки, которая зарегистрировала замену. + * `Текст: Строка` -- фрагмент текста, на который нужно заменить указанный участок. + * `Позиция: Число` -- позиция участка текста для замены. + * `Длина: Число` -- длина участка текста для замены. + + Пример (фрагмент кода плагина): + + ```bsl + Перем Исходник, Токены, ТаблицаТокенов, ТаблицаЗамен; + + Процедура Открыть(Парсер, Параметры) Экспорт + Исходник = Парсер.Исходник(); + Токены = Парсер.Токены(); + ТаблицаТокенов = Парсер.ТаблицаТокенов(); + ТаблицаЗамен = Парсер.ТаблицаЗамен(); + КонецПроцедуры + + Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) Экспорт + + СледующийТокен = ТаблицаТокенов[ОбъявлениеМетода.Конец.Индекс + 1]; + + Если СледующийТокен.Токен = Токены.Комментарий + И СледующийТокен.НомерСтроки = ОбъявлениеМетода.Конец.НомерСтроки Тогда + + Комментарий = СокрП(Сред(Исходник, СледующийТокен.Позиция, СледующийТокен.Длина)); + ПравильныйКомментарий = СтрШаблон(" %1%2", ОбъявлениеМетода.Сигнатура.Имя, "()"); + + Если Комментарий <> ПравильныйКомментарий Тогда + Замена(ПравильныйКомментарий, СледующийТокен); + КонецЕсли; + + КонецЕсли; + + КонецПроцедуры + + Процедура Замена(Текст, ДанныеТокена) + НоваяЗамена = ТаблицаЗамен.Добавить(); + НоваяЗамена.Источник = "ИмяЭтогоПлагина"; + НоваяЗамена.Текст = Текст; + НоваяЗамена.Позиция = ДанныеТокена.Позиция; + НоваяЗамена.Длина = ДанныеТокена.Длина; + КонецПроцедуры + ``` #### Продвинутые методы diff --git a/docs/index.html b/docs/index.html index 8838b7c..7b49961 100644 --- a/docs/index.html +++ b/docs/index.html @@ -12,7 +12,8 @@

Парсер встроенного языка

Оглавление

Примеры использования парсера


@@ -68,32 +69,75 @@

Примеры использования парсера Сообщить(СтрСоединить(Отчет)); -

Шаблон плагина

+

Минимальный шаблон плагина

+
+
+Перем Результат;
+
+// Будет вызвана один раз перед обходом дерева.
+Процедура Открыть(Парсер, Параметры) Экспорт
+	Результат = Новый Массив;
+КонецПроцедуры // Открыть()
+
+// Будет вызвана после полного обхода дерева.
+// Возвращает текстовый результат работы плагина, если он есть.
+Функция Закрыть() Экспорт
+	Возврат СтрСоединить(Результат);
+КонецФункции // Закрыть()
+
+// Возвращает список процедур-подписок, которые будут вызываться визитером.
+// Состав возможных подписок можно посмотреть в парсере в функции Подписки().
+Функция Подписки() Экспорт
+	Перем Подписки;
+	Подписки = Новый Массив;
+	Подписки.Добавить("ПосетитьОператорПрисваивания");
+	Возврат Подписки;
+КонецФункции // Подписки()
+
+#Область РеализацияПодписок
+
+Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт
+
+КонецПроцедуры // ПосетитьОператорПрисваивания()
+
+#КонецОбласти // РеализацияПодписок
+
+
+ + +

Полный шаблон плагина

 Перем Типы;
 Перем Токены;
 Перем Исходник;
 Перем ТаблицаТокенов;
-Перем Директивы;
-Перем ИнструкцииПрепроцессора;
-Перем СимволыПрепроцессора;
 Перем ТаблицаОшибок;
 Перем ТаблицаЗамен;
+Перем Стек;
+Перем Счетчики;
+Перем Директивы;
+Перем Аннотации;
+Перем СимволыПрепроцессора;
 
 Перем Результат;
 
 // Будет вызвана один раз перед обходом дерева.
 Процедура Открыть(Парсер, Параметры) Экспорт
+	
 	Типы = Парсер.Типы();
 	Токены = Парсер.Токены();
 	Исходник = Парсер.Исходник();
 	ТаблицаТокенов = Парсер.ТаблицаТокенов();
-	Директивы = Парсер.Директивы();
-	ИнструкцииПрепроцессора = Парсер.ИнструкцииПрепроцессора();
-	СимволыПрепроцессора = Парсер.СимволыПрепроцессора();
 	ТаблицаОшибок = Парсер.ТаблицаОшибок();
 	ТаблицаЗамен = Парсер.ТаблицаЗамен();
+	Стек = Парсер.Стек();
+	Счетчики = Парсер.Счетчики();
+	Директивы = Парсер.Директивы();
+	Аннотации = Парсер.Аннотации();
+	СимволыПрепроцессора = Парсер.СимволыПрепроцессора();
+	
 	Результат = Новый Массив;
+
 КонецПроцедуры // Открыть()
 
 // Будет вызвана после полного обхода дерева.
@@ -108,16 +152,16 @@ 

Шаблон плагина

Функция Подписки() Экспорт Перем Подписки; Подписки = Новый Массив; - //Подписки.Добавить("ПосетитьОператорПрисваивания"); + Подписки.Добавить("ПосетитьОператорПрисваивания"); //Подписки.Добавить("ПокинутьОператорПрисваивания"); Возврат Подписки; КонецФункции // Подписки() #Область РеализацияПодписок -//Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт -// Ошибка("Ошибка в операторе присваивания", ОператорПрисваивания.Начало, ОператорПрисваивания.Конец); -//КонецПроцедуры // ПосетитьОператорПрисваивания() +Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт + Ошибка("Ошибка в операторе присваивания", ОператорПрисваивания.Начало, ОператорПрисваивания.Конец); +КонецПроцедуры // ПосетитьОператорПрисваивания() //Процедура ПокинутьОператорПрисваивания(ОператорПрисваивания) Экспорт // @@ -226,65 +270,65 @@

ТаблицаЗамен

- |

Шаблон плагина

+ |

Минимальный шаблон плагина

+ |
+		|
+		|Перем Результат;
+		|
+		|// Будет вызвана один раз перед обходом дерева.
+		|Процедура Открыть(Парсер, Параметры) Экспорт
+		|	Результат = Новый Массив;
+		|КонецПроцедуры // Открыть()
+		|
+		|// Будет вызвана после полного обхода дерева.
+		|// Возвращает текстовый результат работы плагина, если он есть.
+		|Функция Закрыть() Экспорт
+		|	Возврат СтрСоединить(Результат);
+		|КонецФункции // Закрыть()
+		|
+		|// Возвращает список процедур-подписок, которые будут вызываться визитером.
+		|// Состав возможных подписок можно посмотреть в парсере в функции Подписки().
+		|Функция Подписки() Экспорт
+		|	Перем Подписки;
+		|	Подписки = Новый Массив;
+		|	Подписки.Добавить(""ПосетитьОператорПрисваивания"");
+		|	Возврат Подписки;
+		|КонецФункции // Подписки()
+		|
+		|#Область РеализацияПодписок
+		|
+		|Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт
+		|
+		|КонецПроцедуры // ПосетитьОператорПрисваивания()
+		|
+		|#КонецОбласти // РеализацияПодписок
+		|
+		|
+ | + | + |

Полный шаблон плагина

|
 		|Перем Типы;
 		|Перем Токены;
 		|Перем Исходник;
 		|Перем ТаблицаТокенов;
-		|Перем Директивы;
-		|Перем ИнструкцииПрепроцессора;
-		|Перем СимволыПрепроцессора;
 		|Перем ТаблицаОшибок;
 		|Перем ТаблицаЗамен;
+		|Перем Стек;
+		|Перем Счетчики;
+		|Перем Директивы;
+		|Перем Аннотации;
+		|Перем СимволыПрепроцессора;
 		|
 		|Перем Результат;
 		|
 		|// Будет вызвана один раз перед обходом дерева.
 		|Процедура Открыть(Парсер, Параметры) Экспорт
+		|	
 		|	Типы = Парсер.Типы();
 		|	Токены = Парсер.Токены();
 		|	Исходник = Парсер.Исходник();
 		|	ТаблицаТокенов = Парсер.ТаблицаТокенов();
-		|	Директивы = Парсер.Директивы();
-		|	ИнструкцииПрепроцессора = Парсер.ИнструкцииПрепроцессора();
-		|	СимволыПрепроцессора = Парсер.СимволыПрепроцессора();
 		|	ТаблицаОшибок = Парсер.ТаблицаОшибок();
 		|	ТаблицаЗамен = Парсер.ТаблицаЗамен();
+		|	Стек = Парсер.Стек();
+		|	Счетчики = Парсер.Счетчики();
+		|	Директивы = Парсер.Директивы();
+		|	Аннотации = Парсер.Аннотации();
+		|	СимволыПрепроцессора = Парсер.СимволыПрепроцессора();
+		|	
 		|	Результат = Новый Массив;
+		|
 		|КонецПроцедуры // Открыть()
 		|
 		|// Будет вызвана после полного обхода дерева.
@@ -126,16 +170,16 @@
 		|Функция Подписки() Экспорт
 		|	Перем Подписки;
 		|	Подписки = Новый Массив;
-		|	//Подписки.Добавить(""ПосетитьОператорПрисваивания"");
+		|	Подписки.Добавить(""ПосетитьОператорПрисваивания"");
 		|	//Подписки.Добавить(""ПокинутьОператорПрисваивания"");
 		|	Возврат Подписки;
 		|КонецФункции // Подписки()
 		|
 		|#Область РеализацияПодписок
 		|
-		|//Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт
-		|//	Ошибка(""Ошибка в операторе присваивания"", ОператорПрисваивания.Начало, ОператорПрисваивания.Конец);
-		|//КонецПроцедуры // ПосетитьОператорПрисваивания()
+		|Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт
+		|	Ошибка(""Ошибка в операторе присваивания"", ОператорПрисваивания.Начало, ОператорПрисваивания.Конец);
+		|КонецПроцедуры // ПосетитьОператорПрисваивания()
 		|
 		|//Процедура ПокинутьОператорПрисваивания(ОператорПрисваивания) Экспорт
 		|//
@@ -248,6 +292,11 @@
 КонецПроцедуры // Открыть()
 
 Функция Закрыть() Экспорт
+	Результат.Добавить("

#Перечисления

"); + Результат.Добавить(СгенерироватьПеречисление("Директивы", Директивы)); + Результат.Добавить(СгенерироватьПеречисление("Аннотации", Аннотации)); + Результат.Добавить(СгенерироватьПеречисление("СимволыПрепроцессора", СимволыПрепроцессора)); + Результат.Добавить(СгенерироватьПеречисление("Токены", Токены)); Результат.Добавить( "

#Прочее

|

Доступность

@@ -266,12 +315,6 @@ | |" ); - Результат.Добавить("

#Перечисления

"); - Результат.Добавить(СгенерироватьПеречисление("Директивы", Директивы)); - Результат.Добавить(СгенерироватьПеречисление("Аннотации", Аннотации)); - Результат.Добавить(СгенерироватьПеречисление("ИнструкцииПрепроцессора", ИнструкцииПрепроцессора)); - //Результат.Добавить(СгенерироватьПеречисление("Типы", Типы, Истина)); - Результат.Добавить(СгенерироватьПеречисление("Токены", Токены)); Возврат СтрСоединить(Результат); КонецФункции // Закрыть() @@ -289,9 +332,9 @@ КонецЦикла; Для Каждого Элемент Из ЗначенияПеречисления Цикл Если Ссылка Тогда - Буфер.Добавить(СтрШаблон("
  • ""%1""
  • " "", Элемент.Key)); + Буфер.Добавить(СтрШаблон("
  • %1
  • " "", Элемент.Key)); Иначе - Буфер.Добавить(СтрШаблон("
  • ""%1""
  • " "", Элемент.Key)); + Буфер.Добавить(СтрШаблон("
  • %1
  • " "", Элемент.Key)); КонецЕсли; КонецЦикла; Буфер.Добавить("" ""); diff --git "a/src/\320\237\320\260\321\200\321\201\320\265\321\200\320\222\321\201\321\202\321\200\320\276\320\265\320\275\320\275\320\276\320\263\320\276\320\257\320\267\321\213\320\272\320\260/Ext/ObjectModule.bsl" "b/src/\320\237\320\260\321\200\321\201\320\265\321\200\320\222\321\201\321\202\321\200\320\276\320\265\320\275\320\275\320\276\320\263\320\276\320\257\320\267\321\213\320\272\320\260/Ext/ObjectModule.bsl" index 59b9fca..8c9cf29 100644 --- "a/src/\320\237\320\260\321\200\321\201\320\265\321\200\320\222\321\201\321\202\321\200\320\276\320\265\320\275\320\275\320\276\320\263\320\276\320\257\320\267\321\213\320\272\320\260/Ext/ObjectModule.bsl" +++ "b/src/\320\237\320\260\321\200\321\201\320\265\321\200\320\222\321\201\321\202\321\200\320\276\320\265\320\275\320\275\320\276\320\263\320\276\320\257\320\267\321\213\320\272\320\260/Ext/ObjectModule.bsl" @@ -358,7 +358,7 @@ ); КонецФункции // Аннотации() -Функция ИнструкцииПрепроцессора() Экспорт +Функция ИнструкцииПрепроцессора() Возврат Перечисление(Новый Структура, "Если.If," "ИначеЕсли.ElsIf,"