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

На данной странице находится быстрая справка.
Руководство по парсеру находится в Книге Джедая.

Настоящим Джедаям рекомендуется смотреть исходный код.
Только так можно достичь просветления.

Содержание

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



// 1С:Предприятие 8.3.13

ПарсерВстроенногоЯзыка = ВнешниеОбработки.Создать(ПарсерВстроенногоЯзыкаПуть, Ложь);
Плагины = Новый Массив;

Плагины.Добавить(ВнешниеОбработки.Создать(ПлагинПуть1, Ложь));
Плагины.Добавить(ВнешниеОбработки.Создать(ПлагинПуть2, Ложь));

ПарсерВстроенногоЯзыка.Пуск(Исходник.ПолучитьТекст(), Плагины);

Отчет = Новый Массив;
Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл
	Отчет.Добавить(Ошибка.Текст);
	Отчет.Добавить(СтрШаблон(" [стр: %1; кол: %2]", Ошибка.НомерСтрокиНачала, Ошибка.НомерКолонкиНачала));
	Отчет.Добавить(Символы.ПС);
КонецЦикла;
Сообщить(СтрСоединить(Отчет));

// OneScript

ПодключитьСценарий("..\..\src\ПарсерВстроенногоЯзыка\Ext\ObjectМодуль.bsl", "ПарсерВстроенногоЯзыка");
ПодключитьСценарий("..\plugins\ДетекторНеиспользуемыхПеременных\src\ДетекторНеиспользуемыхПеременных\Ext\ObjectМодуль.bsl", "ДетекторНеиспользуемыхПеременных");

ЧтениеТекста = Новый ЧтениеТекста("..\src\ПарсерВстроенногоЯзыка\Ext\ObjectМодуль.bsl");
Исходник = ЧтениеТекста.Прочитать();

Парсер = Новый ПарсерВстроенногоЯзыка;
Плагин = Новый ДетекторНеиспользуемыхПеременных;
Парсер.Пуск(Исходник, Плагин);

Отчет = Новый Массив;
Для Каждого Ошибка Из Парсер.ТаблицаОшибок() Цикл
	Отчет.Добавить(Ошибка.Текст);
	Отчет.Добавить(СтрШаблон(" [стр: %1; кол: %2]", Ошибка.НомерСтрокиНачала, Ошибка.НомерКолонкиНачала));
	Отчет.Добавить(Символы.ПС);
КонецЦикла;
Сообщить(СтрСоединить(Отчет));

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


Перем Результат;

// Будет вызвана один раз перед обходом AST.
// Тут можно получить необходимые перечисления и таблицы из парсера,
// и выполнить инициализацию плагина с учетом полученных параметров.
Процедура Открыть(Парсер, Параметры) Экспорт
	Результат = Новый Массив;
КонецПроцедуры

// Будет вызвана после полного обхода AST.
// Возвращает текстовый результат работы плагина, если он есть.
// Плагины, которые регистрируют ошибки и/или замены, могут вернуть Неопределено.
Функция Закрыть() Экспорт
	Возврат СтрСоединить(Результат);
КонецФункции

// Возвращает список процедур-подписок, которые будут вызываться визитером.
// Состав возможных подписок можно посмотреть в исходнике парсера в функции Подписки().
// Имена большинства подписок образуются добавлением префикса Посетить/Покинуть к имени типа узла.
// Справка по типам узлов находится по этому адресу: https://lead-tools.github.io/bsparser/
Функция Подписки() Экспорт
	Перем Подписки;
	Подписки = Новый Массив;
	Подписки.Добавить("ПосетитьОператорПрисваивания");
	Подписки.Добавить("ПокинутьОператорПрисваивания");
	Возврат Подписки;
КонецФункции

#Область РеализацияПодписок

// Описание структуры узла `ОператорПрисваивания`: https://lead-tools.github.io/bsparser/#ОператорПрисваивания

// Данная процедура будет вызвана при посещении узла AST перед посещением подчиненных ему узлов.
// Вызов подписок с префиксом `Посетить` отражает рекурсивный спуск визитера по AST.
// Сначала вызывается подписка на родительский узел, потом на этот, потом на подчиненный и так далее.
Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт
	// ...
КонецПроцедуры

// Данная процедура будет вызвана при посещении узла AST после посещения подчиненных ему узлов.
// Вызов подписок с префиксом `Покинуть` отражает рекурсивный подъем визитера по AST.
// Сначала вызывается подписка на подчиненный узел, потом на этот, потом на родительский и так далее.
Процедура ПокинутьОператорПрисваивания(ОператорПрисваивания) Экспорт
	// ...
КонецПроцедуры

#КонецОбласти

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

Перем Типы;
Перем Токены;
Перем Исходник;
Перем ТаблицаТокенов;
Перем ТаблицаОшибок;
Перем ТаблицаЗамен;
Перем Стек;
Перем Счетчики;
Перем Директивы;
Перем Аннотации;
Перем СимволыПрепроцессора;

Перем Результат;

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

Функция Закрыть() Экспорт
	// ...
	Возврат СтрСоединить(Результат);
КонецФункции

Функция Подписки() Экспорт
	Перем Подписки;
	Подписки = Новый Массив;
	Подписки.Добавить("ПосетитьОператорПрисваивания");
	//Подписки.Добавить("ПокинутьОператорПрисваивания");
	Возврат Подписки;
КонецФункции

#Область РеализацияПодписок

Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) Экспорт
	Ошибка("Ошибка в операторе присваивания", ОператорПрисваивания.Начало, ОператорПрисваивания.Конец);
КонецПроцедуры // ПосетитьОператорПрисваивания()

//Процедура ПокинутьОператорПрисваивания(ОператорПрисваивания) Экспорт
//
//КонецПроцедуры // ПокинутьОператорПрисваивания()

#КонецОбласти

Процедура Ошибка(Текст, Начало, Конец = Неопределено, ЕстьЗамена = Ложь)
	Ошибка = ТаблицаОшибок.Добавить();
	Ошибка.Источник = "ИмяЭтогоПлагина";
	Ошибка.Текст = Текст;
	Ошибка.ПозицияНачала = Начало.Позиция;
	Ошибка.НомерСтрокиНачала = Начало.НомерСтроки;
	Ошибка.НомерКолонкиНачала = Начало.НомерКолонки;
	Если Конец = Неопределено Или Конец = Начало Тогда
		Ошибка.ПозицияКонца = Начало.Позиция + Начало.Длина;
		Ошибка.НомерСтрокиКонца = Начало.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Начало.НомерКолонки + Начало.Длина;
	Иначе
		Ошибка.ПозицияКонца = Конец.Позиция + Конец.Длина;
		Ошибка.НомерСтрокиКонца = Конец.НомерСтроки;
		Ошибка.НомерКолонкиКонца = Конец.НомерКолонки + Конец.Длина;
	КонецЕсли;
	Ошибка.ЕстьЗамена = ЕстьЗамена;
КонецПроцедуры

Процедура Замена(Текст, Начало, Конец = Неопределено)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "ИмяЭтогоПлагина";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Начало.Позиция;
	Если Конец = Неопределено Тогда
		НоваяЗамена.Длина = Начало.Длина;
	Иначе
		НоваяЗамена.Длина = Конец.Позиция + Конец.Длина - Начало.Позиция;
	КонецЕсли;
КонецПроцедуры

Процедура Вставка(Текст, Позиция)
	НоваяЗамена = ТаблицаЗамен.Добавить();
	НоваяЗамена.Источник = "ИмяЭтогоПлагина";
	НоваяЗамена.Текст = Текст;
	НоваяЗамена.Позиция = Позиция;
	НоваяЗамена.Длина = 0;
КонецПроцедуры

Таблицы

ТаблицаТокенов

ТаблицаОшибок

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

Абстрактное синтаксическое дерево

Модуль

ЭлементОкружения

Объявления

ОбъявлениеДирективы

ОбъявлениеАннотации

ОбъявлениеСпискаПеременныхМодуля

ОбъявлениеПеременнойМодуля

ОбъявлениеСпискаЛокальныхПеременных

ОбъявлениеЛокальнойПеременной

ОбъявлениеАвтоПеременной

ОбъявлениеПараметра

ОбъявлениеМетода

ОбъявлениеСигнатурыПроцедуры

ОбъявлениеСигнатурыФункции

ОбъявлениеГлобальногоОбъекта

ОбъявлениеГлобальногоМетода

Выражения

ВыражениеЛитерал

ВыражениеПоле

ВыражениеИндекс

ВыражениеИдентификатор

ВыражениеУнарное

ВыражениеБинарное

ВыражениеНовый

ВыражениеТернарное

ВыражениеСкобочное

ВыражениеНе

ВыражениеСтроковое

Операторы

ОператорПрисваивания

ОператорВозврат

ОператорПрервать

ОператорПродолжить

ОператорВызватьИсключение

ОператорВыполнить

ОператорВызоваПроцедуры

ОператорЕсли

ОператорИначе

ОператорИначеЕсли

ОператорПока

ОператорДля

ОператорДляКаждого

ОператорПопытка

ОператорИсключение

ОператорПерейти

ОператорМетка

ОператорДобавитьОбработчик

ОператорУдалитьОбработчик

ИнструкцииПрепроцессора

ИнструкцияПрепроцессораЕсли

ИнструкцияПрепроцессораИначеЕсли

ИнструкцияПрепроцессораИначе

ИнструкцияПрепроцессораКонецЕсли

ИнструкцияПрепроцессораОбласть

ИнструкцияПрепроцессораКонецОбласти

ИнструкцияПрепроцессораВставка

ИнструкцияПрепроцессораКонецВставки

ИнструкцияПрепроцессораУдаление

ИнструкцияПрепроцессораКонецУдаления

ИнструкцияПрепроцессораИспользовать

ВыраженияПрепроцессора

ВыражениеПрепроцессораБинарное

ВыражениеПрепроцессораНе

ВыражениеПрепроцессораСимвол

ВыражениеПрепроцессораСкобочное

Прочее

Доступность

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

Типы

Директивы

Аннотации

СимволыПрепроцессора

Токены