From 9ac1968ce6894f438918b86df668019c7de7d2d1 Mon Sep 17 00:00:00 2001 From: Vladimir Kharin Date: Wed, 13 Dec 2023 22:10:16 +0400 Subject: [PATCH 1/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D1=83=20?= =?UTF-8?q?=D0=90=D1=81=D0=B8=D0=BD=D1=85=20/=20=D0=96=D0=B4=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20(#159)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\257\320\267\321\213\320\272\320\260.xml" | 62 +- .../Ext/ObjectModule.bsl" | 8488 +++++++++-------- 2 files changed, 4296 insertions(+), 4254 deletions(-) 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.xml" "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.xml" index 9079ec3..f9268a2 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.xml" +++ "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.xml" @@ -1,32 +1,32 @@ - - - - - - c3831ec8-d8d5-4f93-8a22-f9bfae07327f - 9c3982b8-e829-46ac-8582-2ce1d10a5da9 - - - f28eb54c-8e9f-4d35-87dc-9935888205af - 9a0d7ade-475e-423d-9680-3331e902968a - - - - ПарсерВстроенногоЯзыка - - - en - BSParser (built-in script parser) - - - ru - Парсер встроенного языка - - - https://github.com/lead-tools/bsparser - - - - - + + + + + + c3831ec8-d8d5-4f93-8a22-f9bfae07327f + 9c3982b8-e829-46ac-8582-2ce1d10a5da9 + + + f28eb54c-8e9f-4d35-87dc-9935888205af + 9a0d7ade-475e-423d-9680-3331e902968a + + + + ПарсерВстроенногоЯзыка + + + en + BSParser (built-in script parser) + + + ru + Парсер встроенного языка + + + https://github.com/lead-tools/bsparser + + + + + \ No newline at end of file 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 4172d16..99fb606 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" @@ -1,4223 +1,4265 @@ - -// MIT License - -// Copyright (c) 2020 Tsukanov Alexander - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#Область Константы - -Перем КлючевыеСлова; // перечисление -Перем Токены; // перечисление -Перем Типы; // перечисление -Перем Директивы; // перечисление -Перем Аннотации; // перечисление -Перем ИнструкцииПрепроцессора; // перечисление -Перем СимволыПрепроцессора; // перечисление -Перем Ошибки; // массив (строка) -Перем ЛитералКромеСтроки; // массив (один из Токены) -Перем ОперацииСравнения; // массив (один из Токены) -Перем ОперацииАддитивные; // массив (один из Токены) -Перем ОперацииМультипликативные; // массив (один из Токены) -Перем ТокеныНачалаВыражения; // массив (один из Токены) -Перем ПустойМассив; // массив -Перем КартаТокенов; // соответствие[строка] (строка) -Перем КартаБуквЦифр; // соответствие[строка] (строка) -Перем Буква, Цифра; // строка -Перем Символы_ПС; // строка - -#КонецОбласти // Константы - -#Область Параметры - -Перем СтрогийРежим Экспорт; - -#КонецОбласти // Параметры - -#Область СостояниеПарсера - -Перем Парсер_Исходник; // строка -Перем Парсер_ДлинаИсходника; // число -Перем Парсер_НомерТекущейСтроки; // число -Перем Парсер_ТекущаяПозиция; // число -Перем Парсер_ПозицияНачалаТокена; // число -Перем Парсер_Символ; // строка -Перем Парсер_Токен; // строка (один из Токены) -Перем Парсер_Литерал; // строка -Перем Парсер_Значение; // число, строка, дата, булево, неопределено, null -Перем Парсер_Окружение; // структура (Окружение) -Перем Парсер_Переменные; // структура как соответствие[строка] (ЭлементОкружения) -Перем Парсер_Методы; // структура как соответствие[строка] (ЭлементОкружения) -Перем Парсер_Неизвестные; // структура как соответствие[строка] (ЭлементОкружения) -Перем Парсер_ТочкиВызова; // соответствие[ЭлементОкружения] (число) -Перем Парсер_ЭтоФункция; // булево -Перем Парсер_ПеременныеРазрешены; // булево -Перем Парсер_СписокДиректив; // массив (ОбъявлениеДирективы) -Перем Парсер_СписокАннотаций; // массив (ОбъявлениеАннотации) -Перем Парсер_Интерфейс; // массив (ЭлементОкружения) -Перем Парсер_Ошибки; // таблица -Перем Парсер_Замены; // таблица -Перем Парсер_Токены; // таблица -Перем Парсер_ПозицияТекущейСтроки; // число -Перем Парсер_ИндексТокена; // число -Перем Парсер_ДанныеТекущегоТокена; // один из ТаблицаТокенов -Перем Парсер_ДанныеПредыдущегоТокена; // один из ТаблицаТокенов -Перем Парсер_Узлы; // структура как соответствие[строка] (таблица значений) - -#КонецОбласти // СостояниеПарсера - -#Область СостояниеПосетителя - -Перем Посетитель_Плагины; // массив (Обработка) -Перем Посетитель_Подписки; // структура как соответствие[строка] (массив) -Перем Посетитель_Стек; // структура -Перем Посетитель_Счетчики; // структура как соответствие[строка] (число) - -#КонецОбласти // СостояниеПосетителя - -#Область Инициализация - -Процедура Инициализировать() - Перем Буквы, Индекс, Символ; - - ИнициализироватьПеречисления(); - ИнициализироватьУзлы(); - - ЛитералКромеСтроки = Новый Массив; - ЛитералКромеСтроки.Добавить(Токены.Число); - ЛитералКромеСтроки.Добавить(Токены.ДатаВремя); - ЛитералКромеСтроки.Добавить(Токены.Истина); - ЛитералКромеСтроки.Добавить(Токены.Ложь); - ЛитералКромеСтроки.Добавить(Токены.Неопределено); - ЛитералКромеСтроки.Добавить(Токены.Null); - - ОперацииСравнения = Новый Массив; - ОперацииСравнения.Добавить(Токены.ЗнакРавно); - ОперацииСравнения.Добавить(Токены.ЗнакНеРавно); - ОперацииСравнения.Добавить(Токены.ЗнакМеньше); - ОперацииСравнения.Добавить(Токены.ЗнакБольше); - ОперацииСравнения.Добавить(Токены.ЗнакМеньшеИлиРавно); - ОперацииСравнения.Добавить(Токены.ЗнакБольшеИлиРавно); - - ОперацииАддитивные = Новый Массив; - ОперацииАддитивные.Добавить(Токены.ЗнакСложения); - ОперацииАддитивные.Добавить(Токены.ЗнакВычитания); - - ОперацииМультипликативные = Новый Массив; - ОперацииМультипликативные.Добавить(Токены.ЗнакУмножения); - ОперацииМультипликативные.Добавить(Токены.ЗнакДеления); - ОперацииМультипликативные.Добавить(Токены.ЗнакОстатка); - - ТокеныНачалаВыражения = Новый Массив; - ТокеныНачалаВыражения.Добавить(Токены.ЗнакСложения); - ТокеныНачалаВыражения.Добавить(Токены.ЗнакВычитания); - ТокеныНачалаВыражения.Добавить(Токены.Не); - ТокеныНачалаВыражения.Добавить(Токены.Идентификатор); - ТокеныНачалаВыражения.Добавить(Токены.ЛеваяКруглаяСкобка); - ТокеныНачалаВыражения.Добавить(Токены.Число); - ТокеныНачалаВыражения.Добавить(Токены.Строка); - ТокеныНачалаВыражения.Добавить(Токены.НачалоСтроки); - ТокеныНачалаВыражения.Добавить(Токены.ДатаВремя); - ТокеныНачалаВыражения.Добавить(Токены.ЗнакВопроса); - ТокеныНачалаВыражения.Добавить(Токены.Новый); - ТокеныНачалаВыражения.Добавить(Токены.Истина); - ТокеныНачалаВыражения.Добавить(Токены.Ложь); - ТокеныНачалаВыражения.Добавить(Токены.Неопределено); - ТокеныНачалаВыражения.Добавить(Токены.Null); - - ПустойМассив = Новый Массив; - - Символы_ПС = Символы.ПС; - - Буква = "Буква"; - Цифра = "Цифра"; - - КартаТокенов = Новый Соответствие; - КартаБуквЦифр = Новый Соответствие; - - Буквы = ( - "abcdefghijklmnopqrstuvwxyz" - + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - + "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" - + "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" - ); - Индекс = 1; - Символ = "_"; - Пока Символ <> "" Цикл - КартаТокенов[Символ] = Буква; - КартаБуквЦифр[Символ] = Буква; - Символ = Сред(Буквы, Индекс, 1); - Индекс = Индекс + 1; - КонецЦикла; - - Для Индекс = 0 По 9 Цикл - КартаТокенов[Строка(Индекс)] = Цифра; - КартаБуквЦифр[Строка(Индекс)] = Цифра; - КонецЦикла; - - КартаТокенов[""""] = Токены.НачалоСтроки; - КартаТокенов["|"] = Токены.ПродолжениеСтроки; - КартаТокенов["'"] = Токены.ДатаВремя; - КартаТокенов["="] = Токены.ЗнакРавно; - КартаТокенов["+"] = Токены.ЗнакСложения; - КартаТокенов["-"] = Токены.ЗнакВычитания; - КартаТокенов["*"] = Токены.ЗнакУмножения; - КартаТокенов["%"] = Токены.ЗнакОстатка; - КартаТокенов["("] = Токены.ЛеваяКруглаяСкобка; - КартаТокенов[")"] = Токены.ПраваяКруглаяСкобка; - КартаТокенов["["] = Токены.ЛеваяКвадратнаяСкобка; - КартаТокенов["]"] = Токены.ПраваяКвадратнаяСкобка; - КартаТокенов["?"] = Токены.ЗнакВопроса; - КартаТокенов[","] = Токены.Запятая; - КартаТокенов["."] = Токены.Точка; - КартаТокенов[":"] = Токены.Двоеточие; - КартаТокенов[";"] = Токены.ТочкаСЗапятой; - КартаТокенов[""] = Токены.КонецТекста; - - Ошибки = Новый Массив(21); - Ошибки[00] = Неопределено; // ошибки регистрируемые плагинами - Ошибки[01] = "Ожидалось"; - Ошибки[02] = "Ожидалась директива"; - Ошибки[03] = "Неизвестная директива"; - Ошибки[04] = "Ожидалась инструкция препроцессора"; - Ошибки[05] = "Неизвестная инструкция препроцессора"; - Ошибки[06] = "Не обнаружено объявление метода"; - Ошибки[07] = "Ожидался операнд"; - Ошибки[08] = "Ожидался конструктор"; - Ошибки[09] = "Ожидалось не более двух аргументов"; - Ошибки[10] = "Не обнаружено объявление идентификатора"; - Ошибки[11] = "Ожидалось выражение"; - Ошибки[12] = "Повторное объявление идентификатора"; - Ошибки[13] = "Повторное объявление метода"; - Ошибки[14] = "Ожидалась переменная"; - Ошибки[15] = "Имя события указано неправильно"; - Ошибки[16] = "Имя метода указано неправильно"; - Ошибки[17] = "Ожидался символ препроцессора"; - Ошибки[18] = "Ошибка в литерале даты"; - Ошибки[19] = "Не удалось выполнить замену"; - Ошибки[20] = "Ожидалось имя или путь"; - - СтрогийРежим = Ложь; - - Парсер_Ошибки = Новый ТаблицаЗначений; - // основные поля - Парсер_Ошибки.Колонки.Добавить("Источник", Новый ОписаниеТипов("Строка")); - Парсер_Ошибки.Колонки.Добавить("Код", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("Текст", Новый ОписаниеТипов("Строка")); - Парсер_Ошибки.Колонки.Добавить("ПозицияНачала", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("НомерСтрокиНачала", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("НомерКолонкиНачала", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("ПозицияКонца", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("НомерСтрокиКонца", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("НомерКолонкиКонца", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("ЕстьЗамена", Новый ОписаниеТипов("Булево")); - // дополнительные поля - Парсер_Ошибки.Колонки.Добавить("МинутНаИсправление", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("Серьезность", Новый ОписаниеТипов("Строка")); - Парсер_Ошибки.Колонки.Добавить("Приоритет", Новый ОписаниеТипов("Число")); - Парсер_Ошибки.Колонки.Добавить("Правило", Новый ОписаниеТипов("Строка")); - Парсер_Ошибки.Колонки.Добавить("Тип", Новый ОписаниеТипов("Строка")); - - Парсер_Токены = Новый ТаблицаЗначений; - Парсер_Токены.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число")); - Парсер_Токены.Колонки.Добавить("Токен", Новый ОписаниеТипов("Строка")); - Парсер_Токены.Колонки.Добавить("НомерСтроки", Новый ОписаниеТипов("Число")); - Парсер_Токены.Колонки.Добавить("НомерКолонки", Новый ОписаниеТипов("Число")); - Парсер_Токены.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число")); - Парсер_Токены.Колонки.Добавить("Длина", Новый ОписаниеТипов("Число")); - - Парсер_Замены = Новый ТаблицаЗначений; - Парсер_Замены.Колонки.Добавить("Источник", Новый ОписаниеТипов("Строка")); - Парсер_Замены.Колонки.Добавить("Текст", Новый ОписаниеТипов("Строка")); - Парсер_Замены.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число")); - Парсер_Замены.Колонки.Добавить("Длина", Новый ОписаниеТипов("Число")); - -КонецПроцедуры // Инициализировать() - -Процедура ИнициализироватьПеречисления() - КлючевыеСлова = КлючевыеСлова(); - Токены = Токены(КлючевыеСлова); - Типы = Типы(); - Директивы = Директивы(); - Аннотации = Аннотации(); - ИнструкцииПрепроцессора = ИнструкцииПрепроцессора(); - СимволыПрепроцессора = СимволыПрепроцессора(); -КонецПроцедуры // ИнициализироватьПеречисления() - -Процедура ИнициализироватьУзлы() - - Парсер_Узлы = Новый Структура; - - Парсер_Узлы.Вставить("Модуль", Новый ТаблицаЗначений); - // Корень AST. Узел хранит информацию о модуле в целом. - Поля = Парсер_Узлы.Модуль.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Объявления"); // массив (один из #Объявления) - Поля.Добавить("Переменные"); // массив (ОбъявлениеПеременнойМодуля, ОбъявлениеАвтоПеременной) - Поля.Добавить("Операторы"); // массив (один из #Операторы) - Поля.Добавить("Интерфейс"); // массив (ЭлементОкружения) - - Парсер_Узлы.Вставить("ЭлементОкружения", Новый ТаблицаЗначений); - // Узел хранит информацию об объекте области видимости. - // Поле Объявление хранит объявление данного объекта (неопределено = объявление не обнаружено). - Поля = Парсер_Узлы.ЭлементОкружения.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Объявление"); // неопределено, структура (один из #Объявления) - - ИнициализироватьОбъявления(); - ИнициализироватьВыражения(); - ИнициализироватьОператоры(); - ИнициализироватьИнструкцииПрепроцессора(); - ИнициализироватьВыраженияПрепроцессора(); - -КонецПроцедуры // ИнициализироватьУзлы() - -Процедура ИнициализироватьОбъявления() - - Парсер_Узлы.Вставить("ОбъявлениеДирективы", Новый ТаблицаЗначений); - // Хранит информацию об объявлении директивы. - // Пример: - //
-	// &НаКлиенте
-	// 
- Поля = Парсер_Узлы.ОбъявлениеДирективы.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Директива"); // строка (один из Директивы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеАннотации", Новый ТаблицаЗначений); - // Хранит информацию об объявлении аннотации. - // Пример: - //
-	// &Перед("ЗаполнитьТовары")
-	// 
- Поля = Парсер_Узлы.ОбъявлениеАннотации.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Аннотация"); // строка (один из Аннотации) - Поля.Добавить("ИмяМетода"); // строка - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеСпискаПеременныхМодуля", Новый ТаблицаЗначений); - // Хранит информацию об инструкции объявления переменных уровня модуля. - // Пример: - //
-	// &НаКлиенте            // поле "Директивы"
-	// Перем П1 Экспорт, П2; // поле "Объявления"
-	// 
- Поля = Парсер_Узлы.ОбъявлениеСпискаПеременныхМодуля.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) - Поля.Добавить("Объявления"); // массив (ОбъявлениеПеременнойМодуля) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеПеременнойМодуля", Новый ТаблицаЗначений); - // Хранит информацию об объявлении переменной уровня модуля. - // Пример: - // Объявления переменных заключены в скобки {...} - //
-	// &НаКлиенте
-	// Перем {П1 Экспорт}, {П2};
-	// 
- Поля = Парсер_Узлы.ОбъявлениеПеременнойМодуля.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) - Поля.Добавить("Экспорт"); // булево - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеСпискаЛокальныхПеременных", Новый ТаблицаЗначений); - // Хранит информацию об инструкции объявления переменных уровня метода. - // Пример: - //
-	// Перем П1, П2; // поле "Объявления"
-	// 
- Поля = Парсер_Узлы.ОбъявлениеСпискаЛокальныхПеременных.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Объявления"); // массив (ОбъявлениеЛокальнойПеременной) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеЛокальнойПеременной", Новый ТаблицаЗначений); - // Хранит информацию об объявлении локальной переменной. - // Пример: - // Объявления переменных заключены в скобки {...} - //
-	// Перем {П1}, {П2};
-	// 
- Поля = Парсер_Узлы.ОбъявлениеЛокальнойПеременной.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеАвтоПеременной", Новый ТаблицаЗначений); - // Хранит информацию об объявлении авто-переменной. - // Пример: - // Объявления переменных заключены в скобки {...} - //
-	// {Макс} = 0;
-	// Для {Индекс} = 0 По Массив.ВГраница() Цикл
-	//	{Структура} = Массив[Индекс];
-	// 	Для Каждого {Элемент} Из Структура Цикл
-	//		Если Макс < Элемент.Значение Тогда
-	// 			Макс = Элемент.Значение;
-	// 		КонецЕсли;
-	// 	КонецЦикла;
-	// КонецЦикла
-	// 
- Поля = Парсер_Узлы.ОбъявлениеАвтоПеременной.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеПараметра", Новый ТаблицаЗначений); - // Хранит информацию об объявлении параметра. - // Пример: - // Объявления параметров заключены в скобки {...} - //
-	// Процедура Тест({П1}, {Знач П2 = Неопределено})
-	// 
- Поля = Парсер_Узлы.ОбъявлениеПараметра.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("ПоЗначению"); // булево - Поля.Добавить("Значение"); // неопределено, структура (ВыражениеУнарное, ВыражениеЛитерал) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеМетода", Новый ТаблицаЗначений); - // Хранит информацию об объявлении метода. - // Сигнатура метода хранится в поле Сигнатура. - // Пример: - //
-	// &НаКлиенте
-	// Функция Тест() Экспорт
-	//     Перем П1, П2; // поле "Объявления" хранит объявления списков переменных.
-	//                   // каждый элемент объявления (например П2) добавляется в поле "Переменные".
-	//     П1 = 2;       // операторы собираются в поле Операторы
-	//     П3 = П1 + 2;  // Авто-переменные (П2) добавляются в поле "Переменные".
-	// КонецФункции
-	// 
- Поля = Парсер_Узлы.ОбъявлениеМетода.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Сигнатура"); // структура (ОбъявлениеСигнатурыПроцедуры, ОбъявлениеСигнатурыФункции) - Поля.Добавить("Переменные"); // массив (ОбъявлениеЛокальнойПеременной, ОбъявлениеАвтоПеременной) - Поля.Добавить("Объявления"); // массив (ОбъявлениеСпискаЛокальныхПеременных) - Поля.Добавить("Операторы"); // массив (один из #Операторы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеСигнатурыПроцедуры", Новый ТаблицаЗначений); - // Хранит информацию о сигнатуре объявления процедуры. - // Пример: - //
-	// &НаКлиенте
-	// Процедура Тест(П1, П2) Экспорт
-	// 
- Поля = Парсер_Узлы.ОбъявлениеСигнатурыПроцедуры.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) - Поля.Добавить("Аннотации"); // массив (ОбъявлениеАннотации) - Поля.Добавить("Параметры"); // массив (ОбъявлениеПараметра) - Поля.Добавить("Экспорт"); // булево - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеСигнатурыФункции", Новый ТаблицаЗначений); - // Хранит информацию о сигнатуре объявления функции. - // Пример: - //
-	// &НаКлиенте
-	// Функция Тест(П1, П2) Экспорт
-	// 
- Поля = Парсер_Узлы.ОбъявлениеСигнатурыФункции.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) - Поля.Добавить("Аннотации"); // массив (ОбъявлениеАннотации) - Поля.Добавить("Параметры"); // массив (ОбъявлениеПараметра) - Поля.Добавить("Экспорт"); // булево - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОбъявлениеГлобальногоОбъекта", Новый ТаблицаЗначений); - // Хранит информацию о глобальном объекте. - Поля = Парсер_Узлы.ОбъявлениеГлобальногоОбъекта.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Доступность"); // структура (Доступность) - - Парсер_Узлы.Вставить("ОбъявлениеГлобальногоМетода", Новый ТаблицаЗначений); - // Хранит информацию о глобальном методе. - Поля = Парсер_Узлы.ОбъявлениеГлобальногоМетода.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Функция"); // булево - Поля.Добавить("Параметры"); // структура - Поля.Добавить("Доступность"); // структура (Доступность) - -КонецПроцедуры - -Процедура ИнициализироватьВыражения() - - Парсер_Узлы.Вставить("ВыражениеЛитерал", Новый ТаблицаЗначений); - // Хранит информацию о литерале примитивного типа. - Поля = Парсер_Узлы.ВыражениеЛитерал.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Вид"); // строка (один из Токены) - Поля.Добавить("Значение"); // неопределено, строка, число, булево, дата, null - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеПоле", Новый ТаблицаЗначений); - // Хранит информацию об обращении к полю объекта через точку. - // В поле Имя содержится имя поля. - // В поле Аргументы содержатся аргументы вызова (если это вызов). - // Пример: - //
-	// // обращения через точку заключены в скобки {...}
-	// Значение = Объект{.Поле}
-	// Значение = Объект{.Добавить(П1, П2)}
-	// 
- Поля = Парсер_Узлы.ВыражениеПоле.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Аргументы"); // неопределено, массив (неопределено, один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеИндекс", Новый ТаблицаЗначений); - // Хранит информацию об обращении к элементу объекта по индексу. - // Пример: - //
-	// // обращение по индексу заключено в скобки {...}
-	// Значение = Объект{[Ключ]}
-	// 
- Поля = Парсер_Узлы.ВыражениеИндекс.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеИдентификатор", Новый ТаблицаЗначений); - // Хранит информацию об обращении к идентификатору. - // В поле Голова содержится объект области видимости соответствующий идентификатору. - // В поле Хвост содержится последовательность обращений через точку и по индексу. - // В поле Аргументы содержатся аргументы вызова (если это вызов). - // Пример: - //
-	// // идентификатор заключен в скобки {...}
-	// // поле "Голова" будет содержать объект переменной "Запрос";
-	// // поле "Хвост" будет содержать три обращения;
-	// // поле "Аргументы" будет равно Неопределено, т.к. обращение к "Запрос" не является вызовом.
-	// Возврат {Запрос.Выполнить().Выгрузить()[0]};
-	// 
- Поля = Парсер_Узлы.ВыражениеИдентификатор.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Голова"); // структура (ЭлементОкружения) - Поля.Добавить("Хвост"); // массив (ВыражениеПоле, ВыражениеИндекс) - Поля.Добавить("Аргументы"); // неопределено, массив (неопределено, один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеУнарное", Новый ТаблицаЗначений); - // Хранит унарное выражение. - // Пример: - //
-	// // унарные выражения заключены в скобки {...}
-	// // поле "Операция.Токен" равно либо Токены.ЗнакСложения, либо Токены.ЗнакВычитания
-	// // поле "Операнд" хранит операнд-выражение
-	// Значение = {-Сумма} * 2;
-	// Значение = {+Сумма};
-	// Значение = {-(Сумма1 + Сумма2)} / 2;
-	// 
- Поля = Парсер_Узлы.ВыражениеУнарное.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Операция"); // один из ТаблицаТокенов - Поля.Добавить("Операнд"); // структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеБинарное", Новый ТаблицаЗначений); - // Хранит бинарное выражение. - // Пример: - //
-	// // бинарные выражения заключены в скобки {...}
-	// // поле "Операция.Токен" равно одному из допустимых операторов:
-	// // - логических (кроме "Не")
-	// // - реляционных
-	// // - арифметических
-	// // поля "ЛевыйОперанд" и "ПравыйОперанд" содержат операнды-выражения
-	// Если {Не Отмена И Продолжить} Тогда
-	//     Значение = {Сумма1 + {Сумма2 * Коэффициент}};
-	// КонецЕсли;
-	// 
- Поля = Парсер_Узлы.ВыражениеБинарное.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("ЛевыйОперанд"); // структура (один из #Выражения) - Поля.Добавить("Операция"); // один из ТаблицаТокенов - Поля.Добавить("ПравыйОперанд"); // структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеНовый", Новый ТаблицаЗначений); - // Хранит выражение "Новый". - // Для совместимости с OneScript поддерживается - // обращение к конструктору через точку (поле Хвост) - // Пример: - //
-	// // выражения "Новый" заключены в скобки {...}
-	// // в этом варианте поле "Имя" хранит имя типа "Массив",
-	// // а поле "Аргументы" хранит массив из одного выражения
-	// Параметры = {Новый Массив(1)};
-	// Параметры[0] = 10;
-	// // в этом варианте поле "Имя" равно Неопределено,
-	// // а поле "Аргументы" хранит массив из двух выражений
-	// Массив = {Новый (Тип("Массив"), Параметры)};
-	// 
- // Инвариант: если (ВыражениеНовый.Имя = Неопределено) то (0 < ВыражениеНовый.Аргументы.Количество() <= 2) - Поля = Парсер_Узлы.ВыражениеНовый.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // неопределено, строка - Поля.Добавить("Аргументы"); // массив (один из #Выражения) - Поля.Добавить("Хвост"); // массив (ВыражениеПоле, ВыражениеИндекс) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеТернарное", Новый ТаблицаЗначений); - // Хранит тернарное выражение "?(,,)". - // Пример: - //
-	// Значение = ?(Ложь,   // поле "Выражение"
-	//     Неопределено,    // поле "Тогда"
-	//     Новый Массив     // поле "Иначе"
-	// ).Количество();      // поле "Хвост"
-	// 
- Поля = Парсер_Узлы.ВыражениеТернарное.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Тогда"); // структура (один из #Выражения) - Поля.Добавить("Иначе"); // структура (один из #Выражения) - Поля.Добавить("Хвост"); // массив (ВыражениеПоле, ВыражениеИндекс) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеСкобочное", Новый ТаблицаЗначений); - // Хранит скобочное выражение. - // Пример: - //
-	// // скобочное выражение заключено в скобки {...}
-	// Сумма = {(Сумма1 + Сумма2)} * Количество;
-	// 
- Поля = Парсер_Узлы.ВыражениеСкобочное.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеНе", Новый ТаблицаЗначений); - // Хранит выражение, к которому применено логическое отрицание "Не". - // Пример: - //
-	// // выражение-отрицание заключено в скобки {...}
-	// НеРавны = {Не Сумма1 = Сумма2};
-	// 
- Поля = Парсер_Узлы.ВыражениеНе.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеСтроковое", Новый ТаблицаЗначений); - // Хранит строковое выражение. - // Поле "Элементы" хранит упорядоченный список частей строки. - // Пример: - //
-	// Строка1 = "Часть1" "Часть2"; // эта строка состоит из двух частей типа Типы.Строка
-	// Строка2 =                    // эта строка состоит из пяти частей типа:
-	// "Начало строки               // Типы.НачалоСтроки
-	// | продолжение строки         // Типы.ПродолжениеСтроки
-	// | еще продолжение строки     // Типы.ПродолжениеСтроки
-	// | окончание строки"          // Типы.ОкончаниеСтроки
-	// "еще часть";                 // Типы.Строка
-	// 
- Поля = Парсер_Узлы.ВыражениеСтроковое.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Элементы"); // массив (ВыражениеЛитерал) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - -КонецПроцедуры - -Процедура ИнициализироватьОператоры() - - Парсер_Узлы.Вставить("ОператорПрисваивания", Новый ТаблицаЗначений); - // Хранит оператор присваивания. - Поля = Парсер_Узлы.ОператорПрисваивания.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("ЛевыйОперанд"); // структура (ВыражениеИдентификатор) - Поля.Добавить("ПравыйОперанд"); // структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорВозврат", Новый ТаблицаЗначений); - // Хранит оператор "Возврат". - // Поле "Выражение" равно Неопределено если это возврат из процедуры. - Поля = Парсер_Узлы.ОператорВозврат.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // неопределено, структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорПрервать", Новый ТаблицаЗначений); - // Хранит оператор "Прервать". - Поля = Парсер_Узлы.ОператорПрервать.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорПродолжить", Новый ТаблицаЗначений); - // Хранит оператор "Продолжить". - Поля = Парсер_Узлы.ОператорПродолжить.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорВызватьИсключение", Новый ТаблицаЗначений); - // Хранит оператор "ВызватьИсключение". - // Поле "Выражение" равно Неопределено если это вариант оператора без выражения. - Поля = Парсер_Узлы.ОператорВызватьИсключение.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // неопределено, структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорВыполнить", Новый ТаблицаЗначений); - // Хранит оператор "Выполнить". - Поля = Парсер_Узлы.ОператорВыполнить.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорВызоваПроцедуры", Новый ТаблицаЗначений); - // Хранит вызов процедуры или функции как процедуры. - Поля = Парсер_Узлы.ОператорВызоваПроцедуры.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Идентификатор"); // структура (ВыражениеИдентификатор) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорЕсли", Новый ТаблицаЗначений); - // Хранит оператор "Если". - // Пример: - //
-	// Если Сумма > 0 Тогда // поле "Выражение" хранит условие (выражение)
-	//     // поле "Тогда" хранит операторы в этом блоке
-	// ИначеЕсли Сумма = 0 Тогда
-	//     // поле-массив "ИначеЕсли" хранит последовательность блоков ИначеЕсли
-	// Иначе
-	//     // поле "Иначе" хранит операторы в этом блоке
-	// КонецЕсли
-	// 
- // Поля "ИначеЕсли" и "Иначе" равны Неопределено если - // соответствующие блоки отсутствуют в исходном коде. - Поля = Парсер_Узлы.ОператорЕсли.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Тогда"); // массив (один из #Операторы) - Поля.Добавить("ИначеЕсли"); // неопределено, массив (ОператорИначеЕсли) - Поля.Добавить("Иначе"); // неопределено, структура (ОператорИначе) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорИначе", Новый ТаблицаЗначений); - // Хранит блок "Иначе" - Поля = Парсер_Узлы.ОператорИначе.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Операторы"); // массив (один из #Операторы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорИначеЕсли", Новый ТаблицаЗначений); - // Хранит блок "ИначеЕсли" оператора "Если". - // Пример: - //
-	// ...
-	// ИначеЕсли Сумма < 0 Тогда // поле "Выражение" хранит условие (выражение)
-	//     // поле "Тогда" хранит операторы в этом блоке
-	// ...
-	// 
- Поля = Парсер_Узлы.ОператорИначеЕсли.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Тогда"); // массив (один из #Операторы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорПока", Новый ТаблицаЗначений); - // Хранит оператор цикла "Пока". - // Пример: - //
-	// Пока Индекс > 0 Цикл // поле "Выражение" хранит условие (выражение)
-	//     // поле "Операторы" хранит операторы в этом блоке
-	// КонецЦикла
-	// 
- Поля = Парсер_Узлы.ОператорПока.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #Выражения) - Поля.Добавить("Операторы"); // массив (один из #Операторы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорДля", Новый ТаблицаЗначений); - // Хранит оператор цикла "Для". - // Пример: - //
-	// Для Индекс = 0      // поля "Идентификатор" и "Старт" хранят переменную и выражение инициализации.
-	//   По Длина - 1 Цикл // поле "Финиш" хранит выражение границы
-	//     // поле "Операторы" хранит операторы в этом блоке
-	// КонецЦикла
-	// 
- Поля = Парсер_Узлы.ОператорДля.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Идентификатор"); // структура (ВыражениеИдентификатор) - Поля.Добавить("Старт"); // структура (один из #Выражения) - Поля.Добавить("Финиш"); // структура (один из #Выражения) - Поля.Добавить("Операторы"); // массив (один из #Операторы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорДляКаждого", Новый ТаблицаЗначений); - // Хранит оператор цикла "Для Каждого". - // Пример: - //
-	// Для Каждого Элемент // поле "Идентификатор" хранит переменную.
-	//   Из Список Цикл    // поле "Коллекция" хранит выражение коллекции.
-	//     // поле "Операторы" хранит операторы в этом блоке
-	// КонецЦикла
-	// 
- Поля = Парсер_Узлы.ОператорДляКаждого.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Идентификатор"); // структура (ВыражениеИдентификатор) - Поля.Добавить("Коллекция"); // структура (один из #Выражения) - Поля.Добавить("Операторы"); // массив (один из #Операторы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорПопытка", Новый ТаблицаЗначений); - // Хранит оператор "Попытка" - // Пример: - //
-	// Попытка
-	//     // поле "Попытка" хранит операторы в этом блоке.
-	// Исключение
-	//     // поле "Исключение" хранит операторы в этом блоке
-	// КонецПопытки
-	// 
- Поля = Парсер_Узлы.ОператорПопытка.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Попытка"); // массив (один из #Операторы) - Поля.Добавить("Исключение"); // структура (ОператорИсключение) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорИсключение", Новый ТаблицаЗначений); - // Хранит блок "Исключение" - Поля = Парсер_Узлы.ОператорИсключение.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Операторы"); // массив (один из #Операторы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорПерейти", Новый ТаблицаЗначений); - // Хранит оператор "Перейти" - Поля = Парсер_Узлы.ОператорПерейти.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Метка"); // строка - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорМетка", Новый ТаблицаЗначений); - // Хранит оператор метки. - Поля = Парсер_Узлы.ОператорМетка.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Метка"); // строка - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорДобавитьОбработчик", Новый ТаблицаЗначений); - // Хранит оператор "ДобавитьОбработчик". - Поля = Парсер_Узлы.ОператорДобавитьОбработчик.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Событие"); // структура (ВыражениеИдентификатор) - Поля.Добавить("ОбработчикСобытия"); // структура (ВыражениеИдентификатор) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ОператорУдалитьОбработчик", Новый ТаблицаЗначений); - // Хранит оператор "УдалитьОбработчик". - Поля = Парсер_Узлы.ОператорУдалитьОбработчик.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Событие"); // структура (ВыражениеИдентификатор) - Поля.Добавить("ОбработчикСобытия"); // структура (ВыражениеИдентификатор) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - -КонецПроцедуры - -Процедура ИнициализироватьИнструкцииПрепроцессора() - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораЕсли", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #Если, - // Пример: - //
-	// ...
-	// #Если Сервер Тогда // поле "Выражение" хранит условие (выражение)
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораЕсли.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораИначеЕсли", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #ИначеЕсли - // Пример: - //
-	// ...
-	// #ИначеЕсли Клиент Тогда // поле "Выражение" хранит условие (выражение)
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораИначеЕсли.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораИначе", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #Иначе - Поля = Парсер_Узлы.ИнструкцияПрепроцессораИначе.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецЕсли", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #КонецЕсли - Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецЕсли.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораОбласть", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #Обрасть, - // Пример: - //
-	// ...
-	//#Область Интерфейс   // поле "Имя" хранит имя области
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораОбласть.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Имя"); // строка - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецОбласти", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #КонецОбласти, - // Пример: - //
-	// ...
-	//#КонецОбласти
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецОбласти.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораВставка", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #Вставка, - // Пример: - //
-	// ...
-	//#Вставка
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораВставка.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецВставки", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #КонецВставки, - // Пример: - //
-	// ...
-	//#КонецВставки
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецВставки.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораУдаление", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #Удаление, - // Пример: - //
-	// ...
-	//#Удаление
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораУдаление.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецУдаления", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #КонецУдаления, - // Пример: - //
-	// ...
-	//#КонецУдаления
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецУдаления.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ИнструкцияПрепроцессораИспользовать", Новый ТаблицаЗначений); - // Хранит информацию об инструкции препроцессора #Использовать, - // Пример: - //
-	// ...
-	//#Использовать osparser
-	// ...
-	// 
- Поля = Парсер_Узлы.ИнструкцияПрепроцессораИспользовать.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Путь"); // строка - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - -КонецПроцедуры - -Процедура ИнициализироватьВыраженияПрепроцессора() - - Парсер_Узлы.Вставить("ВыражениеПрепроцессораБинарное", Новый ТаблицаЗначений); - // Хранит бинарное выражение препроцессора. - // Пример: - //
-	// // бинарные выражения заключены в скобки {...}
-	// // поле "Операция.Токен" равно либо Токены.Или либо Токены.И:
-	// // поля "ЛевыйОперанд" и "ПравыйОперанд" содержат операнды-выражения препроцессора
-	// #Если {Сервер Или ВнешнееСоединение} Тогда
-	// ...
-	// 
- Поля = Парсер_Узлы.ВыражениеПрепроцессораБинарное.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("ЛевыйОперанд"); // структура (один из #ВыражениеПрепроцессора) - Поля.Добавить("Операция"); // один из ТаблицаТокенов - Поля.Добавить("ПравыйОперанд"); // структура (один из #ВыражениеПрепроцессора) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеПрепроцессораНе", Новый ТаблицаЗначений); - // Хранит выражение препроцессора, к которому применено логическое отрицание "Не". - // Пример: - //
-	// // выражение-отрицание заключено в скобки {...}
-	// #Если {Не ВебКлиент} Тогда
-	// ...
-	// 
- Поля = Парсер_Узлы.ВыражениеПрепроцессораНе.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеПрепроцессораСимвол", Новый ТаблицаЗначений); - // Узел хранит информацию о символе препроцессора. - // Поле Существует = Истина если такой символ существует. - // Пример: - //
-	// // символ заключен в скобки {...}
-	// #Если {Сервер} Тогда
-	// 
- Поля = Парсер_Узлы.ВыражениеПрепроцессораСимвол.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Символ"); // строка (один из PrepСимволs) - Поля.Добавить("Существует"); // булево - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - - Парсер_Узлы.Вставить("ВыражениеПрепроцессораСкобочное", Новый ТаблицаЗначений); - // Хранит скобочное выражение препроцессора. - // Пример: - //
-	// // скобочное выражение заключено в скобки {...}
-	// #Если {(Сервер Или ВнешнееСоединение)} Тогда
-	// 
- Поля = Парсер_Узлы.ВыражениеПрепроцессораСкобочное.Колонки; - Поля.Добавить("Тип"); // строка (один из Типы) - Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) - Поля.Добавить("Начало"); // один из ТаблицаТокенов - Поля.Добавить("Конец"); // один из ТаблицаТокенов - -КонецПроцедуры - -#КонецОбласти // Инициализация - -#Область Перечисления - -Функция КлючевыеСлова() Экспорт - Возврат Перечисление(Новый Структура, - "Если.If, Тогда.Then, ИначеЕсли.ElsIf, Иначе.Else, КонецЕсли.EndIf, - |Для.For, Каждого.Each, Из.In, По.To, Пока.While, Цикл.Do, КонецЦикла.EndDo, - |Процедура.Procedure, КонецПроцедуры.EndProcedure, Функция.Function, КонецФункции.EndFunction, - |Перем.Var, Знач.Val, Возврат.Return, Продолжить.Continue, Прервать.Break, - |И.And, Или.Or, Не.Not, ДобавитьОбработчик.AddHandler, УдалитьОбработчик.RemoveHandler, - |Попытка.Try, Исключение.Except, ВызватьИсключение.Raise, КонецПопытки.EndTry, - |Новый.New, Выполнить.Execute, Экспорт.Export, Перейти.Goto, - |Истина.True, Ложь.False, Неопределено.Undefined, Null" - ); -КонецФункции // КлючевыеСлова() - -Функция Токены(КлючевыеСлова = Неопределено) Экспорт - Перем Токены; - - Если КлючевыеСлова = Неопределено Тогда - КлючевыеСлова = КлючевыеСлова(); - КонецЕсли; - - Токены = Перечисление(Новый Структура(КлючевыеСлова), - - // Литералы - - "Идентификатор, Число, Строка, ДатаВремя, - // Элементы строк - |НачалоСтроки, ПродолжениеСтроки, ОкончаниеСтроки, - - // Операции - - // = <> < > - |ЗнакРавно, ЗнакНеРавно, ЗнакМеньше, ЗнакБольше, - // <= >= - |ЗнакМеньшеИлиРавно, ЗнакБольшеИлиРавно, - // + - * / % - |ЗнакСложения, ЗнакВычитания, ЗнакУмножения, ЗнакДеления, ЗнакОстатка, - // ( ) [ ] - |ЛеваяКруглаяСкобка, ПраваяКруглаяСкобка, ЛеваяКвадратнаяСкобка, ПраваяКвадратнаяСкобка, - // ? , . : ; - |ЗнакВопроса, Запятая, Точка, Двоеточие, ТочкаСЗапятой, - - // ИнструкцииПрепроцессора - |_Если, _ИначеЕсли, _Иначе, _КонецЕсли, _Область, _КонецОбласти, - |_Вставка, _КонецВставки, _Удаление, _КонецУдаления, _Использовать, - - // Другие - - // // ~ & & - |Комментарий, Метка, Аннотация, Директива, НачалоТекста, КонецТекста," - - ); - - Возврат Токены; -КонецФункции // Токены() - -Функция Типы() Экспорт - Возврат Перечисление(Новый Структура, - "Модуль, ЭлементОкружения, ОбъявлениеГлобальногоОбъекта, ОбъявлениеГлобальногоМетода, - |ОбъявлениеДирективы, ОбъявлениеАннотации, ОбъявлениеПеременнойМодуля, ОбъявлениеСпискаПеременныхМодуля, - |ОбъявлениеСпискаЛокальныхПеременных, ОбъявлениеЛокальнойПеременной, ОбъявлениеАвтоПеременной, - |ОбъявлениеПараметра, ОбъявлениеМетода, ОбъявлениеСигнатурыПроцедуры, ОбъявлениеСигнатурыФункции, - |ВыражениеЛитерал, ВыражениеПоле, ВыражениеИндекс, ВыражениеИдентификатор, - |ВыражениеУнарное, ВыражениеБинарное, ВыражениеНовый, ВыражениеТернарное, - |ВыражениеСкобочное, ВыражениеНе, ВыражениеСтроковое, - |ОператорПрисваивания, ОператорВозврат, ОператорПрервать, ОператорПродолжить, - |ОператорВызватьИсключение, ОператорВыполнить, ОператорПока, ОператорДля, ОператорДляКаждого, - |ОператорПопытка, ОператорИсключение, ОператорПерейти, ОператорМетка, - |ОператорВызоваПроцедуры, ОператорЕсли, ОператорИначеЕсли, ОператорИначе, - |ОператорДобавитьОбработчик, ОператорУдалитьОбработчик, - |ИнструкцияПрепроцессораЕсли, ИнструкцияПрепроцессораИначеЕсли, ИнструкцияПрепроцессораИначе, - |ИнструкцияПрепроцессораКонецЕсли, ИнструкцияПрепроцессораОбласть, ИнструкцияПрепроцессораКонецОбласти, - |ИнструкцияПрепроцессораВставка, ИнструкцияПрепроцессораКонецВставки, - |ИнструкцияПрепроцессораУдаление, ИнструкцияПрепроцессораКонецУдаления, - |ИнструкцияПрепроцессораИспользовать, - |ВыражениеПрепроцессораБинарное, ВыражениеПрепроцессораНе, - |ВыражениеПрепроцессораСимвол, ВыражениеПрепроцессораСкобочное" - ); -КонецФункции // Типы() - -Функция Директивы() Экспорт - Возврат Перечисление(Новый Структура, - "НаКлиенте.AtClient," - "НаСервере.AtServer," - "НаСервереБезКонтекста.AtServerNoContext," - "НаКлиентеНаСервереБезКонтекста.AtClientAtServerNoContext," - "НаКлиентеНаСервере.AtClientAtServer" - ); -КонецФункции // Директивы() - -Функция Аннотации() Экспорт - Возврат Перечисление(Новый Структура, - "Перед.Before," - "После.After," - "Вместо.Around," - "ИзменениеИКонтроль.ChangeAndValidate," - ); -КонецФункции // Аннотации() - -Функция ИнструкцииПрепроцессора() - Возврат Перечисление(Новый Структура, - "Если.If," - "ИначеЕсли.ElsIf," - "Иначе.Else," - "КонецЕсли.EndIf," - "Область.Region," - "КонецОбласти.EndRegion," - "Вставка.Insert," - "КонецВставки.EndInsert," - "Удаление.Delete," - "КонецУдаления.EndDelete," - "Использовать.Use," - ); -КонецФункции // ИнструкцииПрепроцессора() - -Функция СимволыПрепроцессора() Экспорт - Возврат Перечисление(Новый Структура, - "Клиент.Client," - "НаКлиенте.AtClient," - "НаСервере.AtServer," - "МобильноеПриложениеКлиент.MobileAppClient," - "МобильноеПриложениеСервер.MobileAppServer," - "ТолстыйКлиентОбычноеПриложение.ThickClientOrdinaryApplication," - "ТолстыйКлиентУправляемоеПриложение.ThickClientManagedApplication," - "Сервер.Server," - "ВнешнееСоединение.ExternalConnection," - "ТонкийКлиент.ThinClient," - "ВебКлиент.WebClient" - ); -КонецФункции // СимволыПрепроцессора() - -Функция Перечисление(Структура, Ключи) - Перем Элементы, Имя, Имена, Значение; - - Для Каждого Элементы Из СтрРазделить(Ключи, ",", Ложь) Цикл - Имена = СтрРазделить(Элементы, ".", Ложь); - Значение = СокрЛП(Имена[0]); - Для Каждого Имя Из Имена Цикл - Структура.Вставить(СокрЛП(Имя), Значение); - КонецЦикла; - КонецЦикла; - - Возврат Новый ФиксированнаяСтруктура(Структура); -КонецФункции // Перечисление() - -#КонецОбласти // Перечисления - -#Область Парсер - -Функция СледующийТокен() - Перем Начало, ПредыдущийСимвол, Комментарий, ДанныеТокена; - - Парсер_Значение = Неопределено; - - Если Прав(Парсер_Литерал, 1) = Символы_ПС Тогда - Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; - Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция - 1; - КонецЕсли; - - Пока Истина Цикл - - Комментарий = Ложь; - - // пропуск невидимых символов - Пока ПустаяСтрока(Парсер_Символ) И Парсер_Символ <> "" Цикл - Если Парсер_Символ = Символы_ПС Тогда - Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; - Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция; - КонецЕсли; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЦикла; - - Парсер_ПозицияНачалаТокена = Парсер_ТекущаяПозиция; - - Парсер_Токен = КартаТокенов[Парсер_Символ]; - Если Парсер_Токен = Буква Тогда - - // сканирование идентификатора - Начало = Парсер_ТекущаяПозиция; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - КонецЦикла; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - - // определение токена - Если КлючевыеСлова.Свойство(Парсер_Литерал, Парсер_Токен) Тогда - Если Парсер_Токен = Токены.Истина Тогда - Парсер_Значение = Истина; - ИначеЕсли Парсер_Токен = Токены.Ложь Тогда - Парсер_Значение = Ложь; - ИначеЕсли Парсер_Токен = Токены.Null Тогда - Парсер_Значение = Null; - КонецЕсли; - Иначе - Парсер_Токен = Токены.Идентификатор; - КонецЕсли; - - ИначеЕсли Парсер_Токен = Токены.НачалоСтроки Тогда - - Начало = Парсер_ТекущаяПозиция; - Парсер_Символ = """"; // уловка - Пока Парсер_Символ = """" Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Пока Парсер_Символ <> """" И Парсер_Символ <> Символы_ПС И Парсер_Символ <> "" Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЦикла; - Если Парсер_Символ <> "" Тогда - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЕсли; - КонецЦикла; - - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - Парсер_Значение = СтрЗаменить(Сред(Парсер_Литерал, 2, СтрДлина(Парсер_Литерал) - 2), """""", """"); - Если Прав(Парсер_Литерал, 1) = """" Тогда - Парсер_Токен = Токены.Строка; - КонецЕсли; - - ИначеЕсли Парсер_Токен = Токены.ПродолжениеСтроки Тогда - - Начало = Парсер_ТекущаяПозиция; - Парсер_Символ = """"; // уловка - Пока Парсер_Символ = """" Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Пока Парсер_Символ <> """" И Парсер_Символ <> Символы_ПС И Парсер_Символ <> "" Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЦикла; - Если Парсер_Символ <> "" Тогда - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЕсли; - КонецЦикла; - - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - Парсер_Значение = СтрЗаменить(Сред(Парсер_Литерал, 2, СтрДлина(Парсер_Литерал) - 2), """""", """"); - Если Прав(Парсер_Литерал, 1) = """" Тогда - Парсер_Токен = Токены.ОкончаниеСтроки; - КонецЕсли; - - ИначеЕсли Парсер_Токен = Цифра Тогда - - Начало = Парсер_ТекущаяПозиция; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] = Цифра Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - КонецЦикла; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Если Парсер_Символ = "." Тогда - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] = Цифра Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - КонецЦикла; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЕсли; - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - - Парсер_Значение = Число(Парсер_Литерал); - Парсер_Токен = Токены.Число; - - ИначеЕсли Парсер_Токен = Токены.ДатаВремя Тогда - - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Начало = Парсер_ТекущаяПозиция; - Парсер_ТекущаяПозиция = СтрНайти(Парсер_Исходник, "'", , Парсер_ТекущаяПозиция); - Если Парсер_ТекущаяПозиция = 0 Тогда - Парсер_Символ = ""; - Иначе - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Значение = КакДата(Парсер_Литерал); - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЕсли; - - ИначеЕсли Парсер_Токен = Неопределено Тогда - - ПредыдущийСимвол = Парсер_Символ; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - - Если ПредыдущийСимвол = "/" Тогда - - Если Парсер_Символ = "/" Тогда - // сканирование комментария - Начало = Парсер_ТекущаяПозиция + 1; - Если Начало < Парсер_ДлинаИсходника Тогда - Парсер_ТекущаяПозиция = СтрНайти(Парсер_Исходник, Символы_ПС, , Начало); - Иначе - Парсер_ТекущаяПозиция = 0; - КонецЕсли; - Если Парсер_ТекущаяПозиция = 0 Тогда - Парсер_ТекущаяПозиция = Парсер_ДлинаИсходника + 1; - Парсер_Символ = ""; - Иначе - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЕсли; - Парсер_ИндексТокена = Парсер_ИндексТокена + 1; - ДанныеТокена = Парсер_Токены.Добавить(); - ДанныеТокена.Индекс = Парсер_ИндексТокена; - ДанныеТокена.Токен = Токены.Комментарий; - ДанныеТокена.НомерСтроки = Парсер_НомерТекущейСтроки; - ДанныеТокена.НомерКолонки = Парсер_ПозицияНачалаТокена + 2 - Парсер_ПозицияТекущейСтроки; - ДанныеТокена.Позиция = Парсер_ПозицияНачалаТокена + 2; - ДанныеТокена.Длина = Парсер_ТекущаяПозиция - ДанныеТокена.Позиция; - Комментарий = Истина; - Иначе - Парсер_Токен = Токены.ЗнакДеления; - КонецЕсли; - - ИначеЕсли ПредыдущийСимвол = "<" Тогда - - Если Парсер_Символ = ">" Тогда - Парсер_Токен = Токены.ЗнакНеРавно; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - ИначеЕсли Парсер_Символ = "=" Тогда - Парсер_Токен = Токены.ЗнакМеньшеИлиРавно; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Иначе - Парсер_Токен = Токены.ЗнакМеньше; - КонецЕсли; - - ИначеЕсли ПредыдущийСимвол = ">" Тогда - - Если Парсер_Символ = "=" Тогда - Парсер_Токен = Токены.ЗнакБольшеИлиРавно; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Иначе - Парсер_Токен = Токены.ЗнакБольше; - КонецЕсли; - - ИначеЕсли ПредыдущийСимвол = "&" Тогда - - Если КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Буква Тогда - Ошибка(2, Неопределено, Истина); - КонецЕсли; - - // сканирование идентификатора - Начало = Парсер_ТекущаяПозиция; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - КонецЦикла; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - - Если Директивы.Свойство(Парсер_Литерал) Тогда - Парсер_Токен = Токены.Директива; - ИначеЕсли Аннотации.Свойство(Парсер_Литерал) Тогда - Парсер_Токен = Токены.Аннотация; - Иначе - Ошибка(3, Парсер_Литерал, Ложь); - Парсер_Токен = Токены.Директива; - КонецЕсли; - - ИначеЕсли ПредыдущийСимвол = "#" Тогда - - // пропуск невидимых символов - Пока ПустаяСтрока(Парсер_Символ) И Парсер_Символ <> "" Цикл - Если Парсер_Символ = Символы_ПС Тогда - Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; - Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция; - КонецЕсли; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЦикла; - - Если КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Буква Тогда - Ошибка(4, Неопределено, Истина); - КонецЕсли; - - // сканирование идентификатора - Начало = Парсер_ТекущаяПозиция; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - КонецЦикла; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - - // сопоставление токена - Если ИнструкцииПрепроцессора.Свойство(Парсер_Литерал, Парсер_Токен) Тогда - Парсер_Токен = "_" + Парсер_Токен; - Иначе - Ошибка(5, Парсер_Литерал, Истина); - КонецЕсли; - - ИначеЕсли ПредыдущийСимвол = "~" Тогда - - // пропуск невидимых символов - Пока ПустаяСтрока(Парсер_Символ) И Парсер_Символ <> "" Цикл - Если Парсер_Символ = Символы_ПС Тогда - Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; - Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция; - КонецЕсли; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - КонецЦикла; - - Если КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] = Неопределено Тогда - Парсер_Литерал = ""; - Иначе - // сканирование идентификатора - Начало = Парсер_ТекущаяПозиция; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - КонецЦикла; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); - КонецЕсли; - - Парсер_Токен = Токены.Метка; - - Иначе - - ВызватьИсключение "Неизвестный символ!"; - - КонецЕсли; - - Иначе - - Парсер_Литерал = Парсер_Символ; - Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; - Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); - - КонецЕсли; - - Если Не Комментарий Тогда - Прервать; - КонецЕсли; - - КонецЦикла; - - Парсер_ДанныеПредыдущегоТокена = Парсер_ДанныеТекущегоТокена; - - Парсер_ИндексТокена = Парсер_ИндексТокена + 1; - - Парсер_ДанныеТекущегоТокена = Парсер_Токены.Добавить(); - Парсер_ДанныеТекущегоТокена.Индекс = Парсер_ИндексТокена; - Парсер_ДанныеТекущегоТокена.Токен = Парсер_Токен; - Парсер_ДанныеТекущегоТокена.НомерСтроки = Парсер_НомерТекущейСтроки; - Парсер_ДанныеТекущегоТокена.НомерКолонки = Парсер_ПозицияНачалаТокена - Парсер_ПозицияТекущейСтроки; - Парсер_ДанныеТекущегоТокена.Позиция = Парсер_ПозицияНачалаТокена; - Парсер_ДанныеТекущегоТокена.Длина = Парсер_ТекущаяПозиция - Парсер_ДанныеТекущегоТокена.Позиция; - - Возврат Парсер_Токен; - -КонецФункции // СледующийТокен() - -Функция Окружение(ВнешнееОкружение = Неопределено) Экспорт - Возврат Новый Структура( - "ВнешнееОкружение," // неопределено, структура (Окружение) - "Переменные," // структура как соответствие[строка] (ЭлементОкружения) - "Методы," // структура как соответствие[строка] (ЭлементОкружения) - "АвтоПеременные", // массив (ОбъявлениеАвтоПеременной) - ВнешнееОкружение, Новый Структура, Новый Структура, Новый Массив); -КонецФункции // Окружение() - -Функция НайтиЭлементОкружения(Имя) - Перем Окружение, ЭлементОкружения; - Окружение = Парсер_Окружение; - Окружение.Переменные.Свойство(Имя, ЭлементОкружения); - Пока ЭлементОкружения = Неопределено И Окружение.ВнешнееОкружение <> Неопределено Цикл - Окружение = Окружение.ВнешнееОкружение; - Окружение.Переменные.Свойство(Имя, ЭлементОкружения); - КонецЦикла; - Возврат ЭлементОкружения; -КонецФункции // НайтиЭлементОкружения() - -Функция НайтиМетод(Имя) - Перем Окружение, Метод; - Окружение = Парсер_Окружение; - Окружение.Методы.Свойство(Имя, Метод); - Пока Метод = Неопределено И Окружение.ВнешнееОкружение <> Неопределено Цикл - Окружение = Окружение.ВнешнееОкружение; - Окружение.Методы.Свойство(Имя, Метод); - КонецЦикла; - Возврат Метод; -КонецФункции - -Функция ОткрытьОкружение() - Перем Окружение; - Окружение = Окружение(Парсер_Окружение); - Парсер_Окружение = Окружение; - Парсер_Переменные = Окружение.Переменные; - Возврат Окружение; -КонецФункции // ОткрытьОкружение() - -Функция ЗакрытьОкружение() - Перем Окружение; - Окружение = Парсер_Окружение.ВнешнееОкружение; - Парсер_Окружение = Окружение; - Если Окружение <> Неопределено Тогда - Парсер_Переменные = Окружение.Переменные; - КонецЕсли; - Возврат Окружение; -КонецФункции // ЗакрытьОкружение() - -Функция Узлы() Экспорт - Возврат Парсер_Узлы; -КонецФункции - -Функция Токенизировать(Исходник) Экспорт - Перем ПоследнийТокен; - - Парсер_Исходник = Исходник; - Парсер_ТекущаяПозиция = 0; - Парсер_НомерТекущейСтроки = 1; - Парсер_ПозицияНачалаТокена = 0; - Парсер_ПозицияТекущейСтроки = 0; - Парсер_ДлинаИсходника = СтрДлина(Исходник); - Парсер_Литерал = ""; - Парсер_Символ = Неопределено; - Парсер_Ошибки.Очистить(); - Парсер_Токены.Очистить(); - Парсер_ИндексТокена = 0; - Парсер_ДанныеТекущегоТокена = Парсер_Токены.Добавить(); - Парсер_ДанныеТекущегоТокена.Токен = Токены.НачалоТекста; - Парсер_Замены.Очистить(); - - Пока СледующийТокен() <> Токены.КонецТекста Цикл - КонецЦикла; - - ПоследнийТокен = Парсер_Токены[Парсер_Токены.Количество() - 1]; - ПоследнийТокен.Длина = 0; - - Возврат Парсер_Токены; - -КонецФункции - -Функция ТаблицаТокенов() Экспорт - Возврат Парсер_Токены; -КонецФункции - -// Служебный метод. Позволяет установить таблицу токенов напрямую без вызова Разобрать(). -// Это необходимо делать перед вызовом Посетить() при обработке кэшированных АСД, -// чтобы плагины и бакенды могли получить таблицу токенов из парсера. -Процедура УстановитьТаблицуТокенов(ТаблицаТокенов) Экспорт - Парсер_Токены = ТаблицаТокенов; -КонецПроцедуры - -Функция ТаблицаЗамен() Экспорт - Возврат Парсер_Замены; -КонецФункции - -Функция ВыполнитьЗамены() Экспорт - Перем Результат, ПозицияНачала, Индекс, Замена; - - Если Парсер_Замены.Количество() = 0 Тогда - Возврат Неопределено; - КонецЕсли; - - Результат = Новый Массив; - - Парсер_Замены.Сортировать("Позиция"); - - ПозицияНачала = 1; - - Для Индекс = 0 По Парсер_Замены.Количество() - 1 Цикл - - Замена = Парсер_Замены[Индекс]; - - Если Замена.Позиция < ПозицияНачала Тогда - КодОшибки = 19; - Ошибка = Парсер_Ошибки.Добавить(); - Ошибка.Источник = "ПарсерВстроенногоЯзыка"; - Ошибка.Код = КодОшибки; - Ошибка.Текст = СтрШаблон(Ошибки[КодОшибки] + ": `%1`", Замена.Текст); - Ошибка.ПозицияНачала = Замена.Позиция; - Ошибка.ПозицияКонца = Замена.Позиция + Замена.Длина; - Продолжить; - КонецЕсли; - - Результат.Добавить(Сред(Парсер_Исходник, ПозицияНачала, Замена.Позиция - ПозицияНачала)); - Результат.Добавить(Замена.Текст); - - ПозицияНачала = Замена.Позиция + Замена.Длина; - - КонецЦикла; - - Результат.Добавить(Сред(Парсер_Исходник, ПозицияНачала)); - - Возврат СтрСоединить(Результат); - -КонецФункции - -Функция Разобрать(Исходник, ВнешнееОкружение = Неопределено) Экспорт - Перем Объявления, Переменные, ОбъявлениеАвтоПеременной, ЭлементОкружения, Операторы, Модуль, ТочкиВызова, ИндексТокена, ПоследнийТокен; - - Парсер_Исходник = Исходник; - Парсер_ТекущаяПозиция = 0; - Парсер_НомерТекущейСтроки = 1; - Парсер_ПозицияТекущейСтроки = 0; - Парсер_ПозицияНачалаТокена = 0; - Парсер_Неизвестные = Новый Структура; - Парсер_ТочкиВызова = Новый Соответствие; - Парсер_ЭтоФункция = Ложь; - Парсер_ПеременныеРазрешены = Истина; - Парсер_Интерфейс = Новый Массив; - Парсер_ДлинаИсходника = СтрДлина(Исходник); - Парсер_Литерал = ""; - Парсер_Символ = Неопределено; - Парсер_Ошибки.Очистить(); - Парсер_Токены.Очистить(); - Парсер_ИндексТокена = 0; - Парсер_ДанныеТекущегоТокена = Парсер_Токены.Добавить(); - Парсер_ДанныеТекущегоТокена.Токен = Токены.НачалоТекста; - Парсер_Замены.Очистить(); - - Парсер_Окружение = ВнешнееОкружение; - ОткрытьОкружение(); - Парсер_Методы = Парсер_Окружение.Методы; - СледующийТокен(); - Переменные = Новый Массив; - Объявления = РазобратьОбъявленияМодуля(Переменные); - Операторы = РазобратьОператоры(); - Для Каждого ОбъявлениеАвтоПеременной Из Парсер_Окружение.АвтоПеременные Цикл - Переменные.Добавить(ОбъявлениеАвтоПеременной); - КонецЦикла; - Модуль = Парсер_Узлы.Модуль.Добавить(); - Модуль.Тип = Типы.Модуль; - Модуль.Объявления = Объявления; - Модуль.Переменные = Переменные; - Модуль.Операторы = Операторы; - Модуль.Интерфейс = Парсер_Интерфейс; - Если СтрогийРежим Тогда - Для Каждого ЭлементОкружения Из Парсер_Неизвестные Цикл - ТочкиВызова = Парсер_ТочкиВызова[ЭлементОкружения.Значение]; - Для Каждого ИндексТокена Из ТочкиВызова Цикл - Ошибка(6, ЭлементОкружения.Ключ, Ложь, ИндексТокена); - КонецЦикла; - КонецЦикла; - КонецЕсли; - Ожидать(Токены.КонецТекста); - ЗакрытьОкружение(); - - ПоследнийТокен = Парсер_Токены[Парсер_Токены.Количество() - 1]; - ПоследнийТокен.Длина = 0; - - Парсер_Неизвестные = Неопределено; - Парсер_Методы = Неопределено; - Парсер_СписокДиректив = Неопределено; - Парсер_СписокАннотаций = Неопределено; - Парсер_Интерфейс = Неопределено; - Парсер_Окружение = Неопределено; - Парсер_Переменные = Неопределено; - - Возврат Модуль; -КонецФункции // Разобрать() - -Функция ТаблицаОшибок() Экспорт - Возврат Парсер_Ошибки; -КонецФункции - -// Служебный метод. Позволяет установить таблицу ошибок напрямую без вызова Разобрать(). -// Это необходимо делать перед вызовом Посетить() при обработке кэшированных АСД, -// чтобы плагины и бакенды могли получить таблицу ошибок из парсера. -Процедура УстановитьТаблицуОшибок(ТаблицаОшибок) Экспорт - Парсер_Ошибки = ТаблицаОшибок; -КонецПроцедуры - -Функция Исходник() Экспорт - Возврат Парсер_Исходник; -КонецФункции - -// Служебный метод. Позволяет установить исходник напрямую без вызова Разобрать(). -// Это необходимо делать перед вызовом Посетить() при обработке кэшированных АСД, -// чтобы плагины и бакенды могли получить исходник из парсера. -Процедура УстановитьИсходник(Исходник) Экспорт - Парсер_Исходник = Исходник; -КонецПроцедуры - -#Область РазборВыражений - -Функция РазобратьВыражение() - Перем Выражение, Операция, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Выражение = РазобратьВыражениеИ(); - Пока Парсер_Токен = Токены.Или Цикл - Операция = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЛевыйОперанд = Выражение; - Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); - Выражение.Тип = Типы.ВыражениеБинарное; - Выражение.ЛевыйОперанд = ЛевыйОперанд; - Выражение.Операция = Операция; - Выражение.ПравыйОперанд = РазобратьВыражениеИ(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЦикла; - Возврат Выражение; -КонецФункции // РазобратьВыражение() - -Функция РазобратьВыражениеИ() - Перем Выражение, Операция, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Выражение = РазобратьВыражениеНе(); - Пока Парсер_Токен = Токены.И Цикл - Операция = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЛевыйОперанд = Выражение; - Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); - Выражение.Тип = Типы.ВыражениеБинарное; - Выражение.ЛевыйОперанд = ЛевыйОперанд; - Выражение.Операция = Операция; - Выражение.ПравыйОперанд = РазобратьВыражениеНе(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЦикла; - Возврат Выражение; -КонецФункции // РазобратьВыражениеИ() - -Функция РазобратьВыражениеНе() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Если Парсер_Токен = Токены.Не Тогда - СледующийТокен(); - Выражение = Парсер_Узлы.ВыражениеНе.Добавить(); - Выражение.Тип = Типы.ВыражениеНе; - Выражение.Выражение = РазобратьВыражениеОтношения(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - Иначе - Выражение = РазобратьВыражениеОтношения(); - КонецЕсли; - Возврат Выражение; -КонецФункции // РазобратьВыражениеНе() - -Функция РазобратьВыражениеОтношения() - Перем Выражение, Операция, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Выражение = РазобратьВыражениеАддитивное(); - Пока ОперацииСравнения.Найти(Парсер_Токен) <> Неопределено Цикл - Операция = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЛевыйОперанд = Выражение; - Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); - Выражение.Тип = Типы.ВыражениеБинарное; - Выражение.ЛевыйОперанд = ЛевыйОперанд; - Выражение.Операция = Операция; - Выражение.ПравыйОперанд = РазобратьВыражениеАддитивное(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЦикла; - Возврат Выражение; -КонецФункции // РазобратьВыражениеОтношения() - -Функция РазобратьВыражениеАддитивное() - Перем Выражение, Операция, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Выражение = РазобратьВыражениеМультипликативное(); - Пока ОперацииАддитивные.Найти(Парсер_Токен) <> Неопределено Цикл - Операция = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЛевыйОперанд = Выражение; - Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); - Выражение.Тип = Типы.ВыражениеБинарное; - Выражение.ЛевыйОперанд = ЛевыйОперанд; - Выражение.Операция = Операция; - Выражение.ПравыйОперанд = РазобратьВыражениеМультипликативное(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЦикла; - Возврат Выражение; -КонецФункции // РазобратьВыражениеАддитивное() - -Функция РазобратьВыражениеМультипликативное() - Перем Выражение, Операция, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Выражение = РазобратьВыражениеУнарное(); - Пока ОперацииМультипликативные.Найти(Парсер_Токен) <> Неопределено Цикл - Операция = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЛевыйОперанд = Выражение; - Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); - Выражение.Тип = Типы.ВыражениеБинарное; - Выражение.ЛевыйОперанд = ЛевыйОперанд; - Выражение.Операция = Операция; - Выражение.ПравыйОперанд = РазобратьВыражениеУнарное(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЦикла; - Возврат Выражение; -КонецФункции // РазобратьВыражениеМультипликативное() - -Функция РазобратьВыражениеУнарное() - Перем Операция, Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Операция = Парсер_ДанныеТекущегоТокена; - Если ОперацииАддитивные.Найти(Парсер_Токен) <> Неопределено Тогда - СледующийТокен(); - Выражение = Парсер_Узлы.ВыражениеУнарное.Добавить(); - Выражение.Тип = Типы.ВыражениеУнарное; - Выражение.Операция = Операция; - Выражение.Операнд = РазобратьОперанд(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - ИначеЕсли Парсер_Токен = Токены.КонецТекста Тогда - Выражение = Неопределено; - Иначе - Выражение = РазобратьОперанд(); - КонецЕсли; - Возврат Выражение; -КонецФункции // РазобратьВыражениеУнарное() - -Функция РазобратьОперанд() - Перем Операнд; - Если Парсер_Токен = Токены.Строка Или Парсер_Токен = Токены.НачалоСтроки Тогда - Операнд = РазобратьВыражениеСтроковое(); - ИначеЕсли ЛитералКромеСтроки.Найти(Парсер_Токен) <> Неопределено Тогда - Операнд = Парсер_Узлы.ВыражениеЛитерал.Добавить(); - Операнд.Тип = Типы.ВыражениеЛитерал; - Операнд.Вид = Парсер_Токен; - Операнд.Значение = Парсер_Значение; - Операнд.Начало = Парсер_ДанныеТекущегоТокена; - Операнд.Конец = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены.Идентификатор Тогда - Операнд = РазобратьВыражениеИдентификатор(); - ИначеЕсли Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда - Операнд = РазобратьВыражениеСкобочное(); - ИначеЕсли Парсер_Токен = Токены.Новый Тогда - Операнд = РазобратьВыражениеНовый(); - ИначеЕсли Парсер_Токен = Токены.ЗнакВопроса Тогда - Операнд = РазобратьВыражениеТернарное(); - Иначе - Ошибка(7, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - Возврат Операнд; -КонецФункции // РазобратьОперанд() - -Функция РазобратьВыражениеСтроковое() - Перем СписокВыражений, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СписокВыражений = Новый Массив; - Пока Истина Цикл - Если Парсер_Токен = Токены.Строка Тогда - Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); - Узел.Тип = Типы.ВыражениеЛитерал; - Узел.Вид = Парсер_Токен; - Узел.Значение = Парсер_Значение; - Узел.Начало = Парсер_ДанныеТекущегоТокена; - Узел.Конец = Парсер_ДанныеТекущегоТокена;; - СписокВыражений.Добавить(Узел); - СледующийТокен(); - Пока Парсер_Токен = Токены.Строка Цикл - Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); - Узел.Тип = Типы.ВыражениеЛитерал; - Узел.Вид = Парсер_Токен; - Узел.Значение = Парсер_Значение; - Узел.Начало = Парсер_ДанныеТекущегоТокена; - Узел.Конец = Парсер_ДанныеТекущегоТокена;; - СписокВыражений.Добавить(Узел); - СледующийТокен(); - КонецЦикла; - ИначеЕсли Парсер_Токен = Токены.НачалоСтроки Тогда - Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); - Узел.Тип = Типы.ВыражениеЛитерал; - Узел.Вид = Парсер_Токен; - Узел.Значение = Парсер_Значение; - Узел.Начало = Парсер_ДанныеТекущегоТокена; - Узел.Конец = Парсер_ДанныеТекущегоТокена;; - СписокВыражений.Добавить(Узел); - СледующийТокен(); - Пока Парсер_Токен = Токены.ПродолжениеСтроки Цикл - Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); - Узел.Тип = Типы.ВыражениеЛитерал; - Узел.Вид = Парсер_Токен; - Узел.Значение = Парсер_Значение; - Узел.Начало = Парсер_ДанныеТекущегоТокена; - Узел.Конец = Парсер_ДанныеТекущегоТокена;; - СписокВыражений.Добавить(Узел); - СледующийТокен(); - КонецЦикла; - Если Парсер_Токен <> Токены.ОкончаниеСтроки Тогда - Ошибка(1, """", Истина, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); - Узел.Тип = Типы.ВыражениеЛитерал; - Узел.Вид = Парсер_Токен; - Узел.Значение = Парсер_Значение; - Узел.Начало = Парсер_ДанныеТекущегоТокена; - Узел.Конец = Парсер_ДанныеТекущегоТокена;; - СписокВыражений.Добавить(Узел); - СледующийТокен(); - Иначе - Прервать; - КонецЕсли; - КонецЦикла; - Узел = Парсер_Узлы.ВыражениеСтроковое.Добавить(); - Узел.Тип = Типы.ВыражениеСтроковое; - Узел.Элементы = СписокВыражений; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьВыражениеСтроковое() - -Функция РазобратьВыражениеНовый() - Перем Имя, Аргументы, Хвост, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Если Парсер_Токен = Токены.Идентификатор Тогда - Имя = Парсер_Литерал; - Аргументы = ПустойМассив; - СледующийТокен(); - КонецЕсли; - Хвост = ПустойМассив; - Если Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда - СледующийТокен(); - Если Парсер_Токен <> Токены.ПраваяКруглаяСкобка Тогда - Аргументы = РазобратьАргументы(); - Ожидать(Токены.ПраваяКруглаяСкобка); - КонецЕсли; - СледующийТокен(); - Если Парсер_Токен = Токены.Точка Тогда - Хвост = РазобратьХвост(); - КонецЕсли; - КонецЕсли; - Если Имя = Неопределено Тогда - Если Аргументы = Неопределено Тогда - Ошибка(8, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); - ИначеЕсли Аргументы.Количество() > 2 Тогда - Ошибка(9, Неопределено, Истина, Начало, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - КонецЕсли; - Узел = Парсер_Узлы.ВыражениеНовый.Добавить(); - Узел.Тип = Типы.ВыражениеНовый; - Узел.Имя = Имя; - Узел.Аргументы = Аргументы; - Узел.Хвост = Хвост; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьВыражениеНовый() - -Функция РазобратьВыражениеИдентификатор(Знач НоваяПеременнаяРазрешена = Ложь, НоваяПеременная = Неопределено, ЭтоВызов = Неопределено) - Перем Имя, ЭлементОкружения, Хвост, Аргументы, НачалоАвтоПеременной, ТочкиВызова, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Имя = Парсер_Литерал; - НачалоАвтоПеременной = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Если Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда - Если СледующийТокен() = Токены.ПраваяКруглаяСкобка Тогда - Аргументы = ПустойМассив; - Иначе - Аргументы = РазобратьАргументы(); - КонецЕсли; - Ожидать(Токены.ПраваяКруглаяСкобка); - СледующийТокен(); - ЭлементОкружения = НайтиМетод(Имя); - Если ЭлементОкружения = Неопределено Тогда - Если Парсер_Неизвестные.Свойство(Имя, ЭлементОкружения) Тогда - ТочкиВызова = Парсер_ТочкиВызова[ЭлементОкружения]; - ТочкиВызова.Добавить(НачалоАвтоПеременной); - Иначе - ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); - ЭлементОкружения.Тип = Типы.ЭлементОкружения; - ЭлементОкружения.Имя = Имя; - ЭлементОкружения.Объявление = Неопределено; - Парсер_Неизвестные.Вставить(Имя, ЭлементОкружения); - ТочкиВызова = Новый Массив; - ТочкиВызова.Добавить(НачалоАвтоПеременной); - Парсер_ТочкиВызова[ЭлементОкружения] = ТочкиВызова; - КонецЕсли; - КонецЕсли; - ЭтоВызов = Истина; - Хвост = РазобратьХвост(ЭтоВызов); - Иначе - ЭтоВызов = Ложь; - Хвост = РазобратьХвост(ЭтоВызов); - Если Хвост.Количество() > 0 Тогда - НоваяПеременнаяРазрешена = Ложь; - КонецЕсли; - ЭлементОкружения = НайтиЭлементОкружения(Имя); - Если ЭлементОкружения = Неопределено Тогда - Если НоваяПеременнаяРазрешена Тогда - ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); - ЭлементОкружения.Тип = Типы.ЭлементОкружения; - ЭлементОкружения.Имя = Имя; - ЭлементОкружения.Объявление = Парсер_Узлы.ОбъявлениеАвтоПеременной.Добавить(); - ЭлементОкружения.Объявление.Тип = Типы.ОбъявлениеАвтоПеременной; - ЭлементОкружения.Объявление.Имя = Имя; - ЭлементОкружения.Объявление.Начало = НачалоАвтоПеременной; - ЭлементОкружения.Объявление.Конец = НачалоАвтоПеременной;; - НоваяПеременная = ЭлементОкружения; - Иначе - ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); - ЭлементОкружения.Тип = Типы.ЭлементОкружения; - ЭлементОкружения.Имя = Имя; - ЭлементОкружения.Объявление = Неопределено; - Если СтрогийРежим Тогда - Ошибка(10, Имя, Ложь, Начало); - КонецЕсли; - КонецЕсли; - КонецЕсли; - КонецЕсли; - Узел = Парсер_Узлы.ВыражениеИдентификатор.Добавить(); - Узел.Тип = Типы.ВыражениеИдентификатор; - Узел.Голова = ЭлементОкружения; - Узел.Хвост = Хвост; - Узел.Аргументы = Аргументы; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьВыражениеИдентификатор() - -Функция РазобратьХвост(Вызов = Неопределено) - Перем Хвост, Имя, Аргументы, Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Хвост = Новый Массив; - Пока Истина Цикл - Если Парсер_Токен = Токены.Точка Тогда - СледующийТокен(); - Если КартаБуквЦифр[Лев(Парсер_Литерал, 1)] <> Буква Или Не КлючевыеСлова.Свойство(Парсер_Литерал) Тогда - Ожидать(Токены.Идентификатор); - КонецЕсли; - Имя = Парсер_Литерал; - Если СледующийТокен() = Токены.ЛеваяКруглаяСкобка Тогда - Если СледующийТокен() = Токены.ПраваяКруглаяСкобка Тогда - Аргументы = ПустойМассив; - Иначе - Аргументы = РазобратьАргументы(); - КонецЕсли; - Ожидать(Токены.ПраваяКруглаяСкобка); - СледующийТокен(); - Вызов = Истина; - Иначе - Аргументы = Неопределено; - Вызов = Ложь; - КонецЕсли; - Узел = Парсер_Узлы.ВыражениеПоле.Добавить(); - Узел.Тип = Типы.ВыражениеПоле; - Узел.Имя = Имя; - Узел.Аргументы = Аргументы; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена;; - Хвост.Добавить(Узел); - ИначеЕсли Парсер_Токен = Токены.ЛеваяКвадратнаяСкобка Тогда - Вызов = Ложь; - Если СледующийТокен() = Токены.ПраваяКвадратнаяСкобка Тогда - Ошибка(11, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - Выражение = РазобратьВыражение(); - Ожидать(Токены.ПраваяКвадратнаяСкобка); - СледующийТокен(); - Узел = Парсер_Узлы.ВыражениеИндекс.Добавить(); - Узел.Тип = Типы.ВыражениеИндекс; - Узел.Выражение = Выражение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена;; - Хвост.Добавить(Узел); - Иначе - Прервать; - КонецЕсли; - КонецЦикла; - Возврат Хвост; -КонецФункции // РазобратьХвост() - -Функция РазобратьАргументы() - Перем СписокВыражений; - СписокВыражений = Новый Массив; - Пока Истина Цикл - Если ТокеныНачалаВыражения.Найти(Парсер_Токен) <> Неопределено Тогда - СписокВыражений.Добавить(РазобратьВыражение()); - Иначе - СписокВыражений.Добавить(Неопределено); - КонецЕсли; - Если Парсер_Токен = Токены.Запятая Тогда - СледующийТокен(); - Иначе - Прервать; - КонецЕсли; - КонецЦикла; - Возврат СписокВыражений; -КонецФункции // РазобратьАргументы() - -Функция РазобратьВыражениеТернарное() - Перем Выражение, ТогдаОператоры, ИначеОператоры, Хвост, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Ожидать(Токены.ЛеваяКруглаяСкобка); - СледующийТокен(); - Выражение = РазобратьВыражение(); - Ожидать(Токены.Запятая); - СледующийТокен(); - ТогдаОператоры = РазобратьВыражение(); - Ожидать(Токены.Запятая); - СледующийТокен(); - ИначеОператоры = РазобратьВыражение(); - Ожидать(Токены.ПраваяКруглаяСкобка); - Если СледующийТокен() = Токены.Точка Тогда - Хвост = РазобратьХвост(); - Иначе - Хвост = ПустойМассив; - КонецЕсли; - Узел = Парсер_Узлы.ВыражениеТернарное.Добавить(); - Узел.Тип = Типы.ВыражениеТернарное; - Узел.Выражение = Выражение; - Узел.Тогда = ТогдаОператоры; - Узел.Иначе = ИначеОператоры; - Узел.Хвост = Хвост; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьВыражениеТернарное() - -Функция РазобратьВыражениеСкобочное() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Выражение = РазобратьВыражение(); - Ожидать(Токены.ПраваяКруглаяСкобка); - СледующийТокен(); - Узел = Парсер_Узлы.ВыражениеСкобочное.Добавить(); - Узел.Тип = Типы.ВыражениеСкобочное; - Узел.Выражение = Выражение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьВыражениеСкобочное() - -#КонецОбласти // РазборВыражений - -#Область РазборОбъявлений - -Функция РазобратьОбъявленияМодуля(Переменные) - Перем Объявления, ОбъявлениеДирективы; - Объявления = Новый Массив; - Пока Истина Цикл - Парсер_СписокДиректив = Новый Массив; - Парсер_СписокАннотаций = Новый Массив; - Пока Истина Цикл - Если Парсер_Токен = Токены.Директива Тогда - ОбъявлениеДирективы = Парсер_Узлы.ОбъявлениеДирективы.Добавить(); - ОбъявлениеДирективы.Тип = Типы.ОбъявлениеДирективы; - ОбъявлениеДирективы.Директива = Директивы[Парсер_Литерал]; - ОбъявлениеДирективы.Начало = Парсер_ДанныеТекущегоТокена; - ОбъявлениеДирективы.Конец = Парсер_ДанныеТекущегоТокена; - Парсер_СписокДиректив.Добавить(ОбъявлениеДирективы); - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены.Аннотация Тогда - Аннотация = Аннотации[Парсер_Литерал]; - НачалоАннотации = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Ожидать(Токены.ЛеваяКруглаяСкобка); - СледующийТокен(); - Ожидать(Токены.Строка); - ИмяМетода = Парсер_Значение; - СледующийТокен(); - Ожидать(Токены.ПраваяКруглаяСкобка); - ОбъявлениеАннотации = Парсер_Узлы.ОбъявлениеАннотации.Добавить(); - ОбъявлениеАннотации.Тип = Типы.ОбъявлениеАннотации; - ОбъявлениеАннотации.Аннотация = Аннотация; - ОбъявлениеАннотации.ИмяМетода = ИмяМетода; - ОбъявлениеАннотации.Начало = НачалоАннотации; - ОбъявлениеАннотации.Конец = Парсер_ДанныеТекущегоТокена; - Парсер_СписокАннотаций.Добавить(ОбъявлениеАннотации); - СледующийТокен(); - Иначе - Прервать; - КонецЕсли; - КонецЦикла; - Если Парсер_Токен = Токены.Перем И Парсер_ПеременныеРазрешены Тогда - Объявления.Добавить(РазобратьОбъявлениеСпискаПеременныхМодуля(Переменные)); - ИначеЕсли Парсер_Токен = Токены.Функция Тогда - Парсер_ЭтоФункция = Истина; - Объявления.Добавить(РазобратьОбъявлениеМетода()); - Парсер_ЭтоФункция = Ложь; - Парсер_ПеременныеРазрешены = Ложь; - ИначеЕсли Парсер_Токен = Токены.Процедура Тогда - Объявления.Добавить(РазобратьОбъявлениеМетода()); - Парсер_ПеременныеРазрешены = Ложь; - ИначеЕсли Парсер_Токен = Токены._Область Тогда - Объявления.Добавить(РазобратьИнструкциюПрепроцессораОбласть()); - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены._КонецОбласти Тогда - Объявления.Добавить(РазобратьИнструкциюПрепроцессораКонецОбласти()); - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены._Если Тогда - Объявления.Добавить(РазобратьИнструкциюПрепроцессораЕсли()); - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены._ИначеЕсли Тогда - Объявления.Добавить(РазобратьИнструкциюПрепроцессораИначеЕсли()); - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены._Иначе Тогда - Объявления.Добавить(РазобратьИнструкциюПрепроцессораИначе()); - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены._КонецЕсли Тогда - Объявления.Добавить(РазобратьИнструкциюПрепроцессораКонецЕсли()); - СледующийТокен(); - ИначеЕсли Парсер_Токен = Токены._Использовать Тогда - Объявления.Добавить(РазобратьИнструкциюПрепроцессораИспользовать()); - СледующийТокен(); - Иначе - Прервать; - КонецЕсли; - КонецЦикла; - Возврат Объявления; -КонецФункции // РазобратьОбъявленияМодуля() - -Функция РазобратьОбъявлениеСпискаПеременныхМодуля(Переменные) - Перем ОбъявленияПеременных, ОбъявлениеПеременной, Объявление, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ОбъявленияПеременных = Новый Массив; - ОбъявлениеПеременной = РазобратьОбъявлениеПеременнойМодуля(); - ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); - Переменные.Добавить(ОбъявлениеПеременной); - Пока Парсер_Токен = Токены.Запятая Цикл - СледующийТокен(); - ОбъявлениеПеременной = РазобратьОбъявлениеПеременнойМодуля(); - ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); - Переменные.Добавить(ОбъявлениеПеременной); - КонецЦикла; - Объявление = Парсер_Узлы.ОбъявлениеСпискаПеременныхМодуля.Добавить(); - Объявление.Тип = Типы.ОбъявлениеСпискаПеременныхМодуля; - Объявление.Директивы = Парсер_СписокДиректив; - Объявление.Объявления = ОбъявленияПеременных; - Объявление.Начало = Начало; - Объявление.Конец = Парсер_ДанныеПредыдущегоТокена; - Ожидать(Токены.ТочкаСЗапятой); - СледующийТокен(); - Пока Парсер_Токен = Токены.ТочкаСЗапятой Цикл - СледующийТокен(); - КонецЦикла; - Возврат Объявление; -КонецФункции // РазобратьОбъявлениеСпискаПеременныхМодуля() - -Функция РазобратьОбъявлениеПеременнойМодуля() - Перем Имя, ОбъявлениеПеременнойМодуля, ЭлементОкружения, ЕстьЭкспорт, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Ожидать(Токены.Идентификатор); - Имя = Парсер_Литерал; - Если СледующийТокен() = Токены.Экспорт Тогда - ЕстьЭкспорт = Истина; - СледующийТокен(); - Иначе - ЕстьЭкспорт = Ложь; - КонецЕсли; - ОбъявлениеПеременнойМодуля = Парсер_Узлы.ОбъявлениеПеременнойМодуля.Добавить(); - ОбъявлениеПеременнойМодуля.Тип = Типы.ОбъявлениеПеременнойМодуля; - ОбъявлениеПеременнойМодуля.Имя = Имя; - ОбъявлениеПеременнойМодуля.Директивы = Парсер_СписокДиректив; - ОбъявлениеПеременнойМодуля.Экспорт = ЕстьЭкспорт; - ОбъявлениеПеременнойМодуля.Начало = Начало; - ОбъявлениеПеременнойМодуля.Конец = Парсер_ДанныеПредыдущегоТокена; - Если Парсер_Переменные.Свойство(Имя) Тогда - Ошибка(12, Имя, СтрогийРежим, Начало); - КонецЕсли; - ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); - ЭлементОкружения.Тип = Типы.ЭлементОкружения; - ЭлементОкружения.Имя = Имя; - ЭлементОкружения.Объявление = ОбъявлениеПеременнойМодуля; - Парсер_Переменные.Вставить(Имя, ЭлементОкружения); - Если ЕстьЭкспорт Тогда - Парсер_Интерфейс.Добавить(ЭлементОкружения); - КонецЕсли; - Возврат ОбъявлениеПеременнойМодуля; -КонецФункции // РазобратьОбъявлениеПеременнойМодуля() - -Функция РазобратьОбъявлениеСпискаЛокальныхПеременных(Переменные) - Перем ОбъявленияПеременных, ОбъявлениеПеременной, Объявление, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ОбъявленияПеременных = Новый Массив; - ОбъявлениеПеременной = РазобратьОбъявлениеЛокальнойПеременной(); - ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); - Переменные.Добавить(ОбъявлениеПеременной); - Пока Парсер_Токен = Токены.Запятая Цикл - СледующийТокен(); - ОбъявлениеПеременной = РазобратьОбъявлениеЛокальнойПеременной(); - ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); - Переменные.Добавить(ОбъявлениеПеременной); - КонецЦикла; - Объявление = Парсер_Узлы.ОбъявлениеСпискаЛокальныхПеременных.Добавить(); - Объявление.Тип = Типы.ОбъявлениеСпискаЛокальныхПеременных; - Объявление.Объявления = ОбъявленияПеременных; - Объявление.Начало = Начало; - Объявление.Конец = Парсер_ДанныеПредыдущегоТокена; - Ожидать(Токены.ТочкаСЗапятой); - СледующийТокен(); - Пока Парсер_Токен = Токены.ТочкаСЗапятой Цикл - СледующийТокен(); - КонецЦикла; - Возврат Объявление; -КонецФункции // РазобратьОбъявлениеСпискаЛокальныхПеременных() - -Функция РазобратьОбъявлениеЛокальнойПеременной() - Перем Имя, ОбъявлениеЛокальнойПеременной, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Ожидать(Токены.Идентификатор); - Имя = Парсер_Литерал; - ОбъявлениеЛокальнойПеременной = Парсер_Узлы.ОбъявлениеЛокальнойПеременной.Добавить(); - ОбъявлениеЛокальнойПеременной.Тип = Типы.ОбъявлениеЛокальнойПеременной; - ОбъявлениеЛокальнойПеременной.Имя = Имя; - ОбъявлениеЛокальнойПеременной.Начало = Начало; - ОбъявлениеЛокальнойПеременной.Конец = Начало; - Если Парсер_Переменные.Свойство(Имя) Тогда - Ошибка(12, Имя, СтрогийРежим, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); - ЭлементОкружения.Тип = Типы.ЭлементОкружения; - ЭлементОкружения.Имя = Имя; - ЭлементОкружения.Объявление = ОбъявлениеЛокальнойПеременной;; - Парсер_Переменные.Вставить(Имя, ЭлементОкружения); - СледующийТокен(); - Возврат ОбъявлениеЛокальнойПеременной; -КонецФункции // РазобратьОбъявлениеЛокальнойПеременной() - -Функция РазобратьОбъявлениеМетода() - Перем Сигнатура, ЭлементОкружения, Имя, Переменные, Параметры, ЕстьЭкспорт, Операторы, Объявления, ОбъявлениеАвтоПеременной, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - ЕстьЭкспорт = Ложь; - СледующийТокен(); - Ожидать(Токены.Идентификатор); - Имя = Парсер_Литерал; - СледующийТокен(); - ОткрытьОкружение(); - Параметры = РазобратьПараметры(); - Если Парсер_Токен = Токены.Экспорт Тогда - ЕстьЭкспорт = Истина; - СледующийТокен(); - КонецЕсли; - Если Парсер_ЭтоФункция Тогда - Сигнатура = Парсер_Узлы.ОбъявлениеСигнатурыФункции.Добавить(); - Сигнатура.Тип = Типы.ОбъявлениеСигнатурыФункции; - Сигнатура.Имя = Имя; - Сигнатура.Директивы = Парсер_СписокДиректив; - Сигнатура.Аннотации = Парсер_СписокАннотаций; - Сигнатура.Параметры = Параметры; - Сигнатура.Экспорт = ЕстьЭкспорт; - Сигнатура.Начало = Начало; - Сигнатура.Конец = Парсер_ДанныеПредыдущегоТокена; - Иначе - Сигнатура = Парсер_Узлы.ОбъявлениеСигнатурыПроцедуры.Добавить(); - Сигнатура.Тип = Типы.ОбъявлениеСигнатурыПроцедуры; - Сигнатура.Имя = Имя; - Сигнатура.Директивы = Парсер_СписокДиректив; - Сигнатура.Аннотации = Парсер_СписокАннотаций; - Сигнатура.Параметры = Параметры; - Сигнатура.Экспорт = ЕстьЭкспорт; - Сигнатура.Начало = Начало; - Сигнатура.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЕсли; - Если Парсер_Неизвестные.Свойство(Имя, ЭлементОкружения) Тогда - Парсер_Неизвестные.Удалить(Имя); - ЭлементОкружения.Объявление = Сигнатура; - Иначе - ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); - ЭлементОкружения.Тип = Типы.ЭлементОкружения; - ЭлементОкружения.Имя = Имя; - ЭлементОкружения.Объявление = Сигнатура; - КонецЕсли; - Если НайтиМетод(Имя) <> Неопределено Тогда - Ошибка(13, Имя, СтрогийРежим, Парсер_Токены[Начало.Индекс + 1]); - КонецЕсли; - Парсер_Методы.Вставить(Имя, ЭлементОкружения); - Если ЕстьЭкспорт Тогда - Парсер_Интерфейс.Добавить(ЭлементОкружения); - КонецЕсли; - Объявления = Новый Массив; - Переменные = Новый Массив; - Пока Парсер_Токен = Токены.Перем Цикл - Объявления.Добавить(РазобратьОбъявлениеСпискаЛокальныхПеременных(Переменные)); - КонецЦикла; - Операторы = РазобратьОператоры(); - Если Парсер_ЭтоФункция Тогда - Ожидать(Токены.КонецФункции); - Иначе - Ожидать(Токены.КонецПроцедуры); - КонецЕсли; - Для Каждого ОбъявлениеАвтоПеременной Из Парсер_Окружение.АвтоПеременные Цикл - Переменные.Добавить(ОбъявлениеАвтоПеременной); - КонецЦикла; - ЗакрытьОкружение(); - СледующийТокен(); - Узел = Парсер_Узлы.ОбъявлениеМетода.Добавить(); - Узел.Тип = Типы.ОбъявлениеМетода; - Узел.Сигнатура = Сигнатура; - Узел.Переменные = Переменные; - Узел.Объявления = Объявления; - Узел.Операторы = Операторы; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОбъявлениеМетода() - -Функция РазобратьПараметры() - Перем Параметры; - Ожидать(Токены.ЛеваяКруглаяСкобка); - СледующийТокен(); - Если Парсер_Токен = Токены.ПраваяКруглаяСкобка Тогда - Параметры = ПустойМассив; - Иначе - Параметры = Новый Массив; - Параметры.Добавить(РазобратьОбъявлениеПараметра()); - Пока Парсер_Токен = Токены.Запятая Цикл - СледующийТокен(); - Параметры.Добавить(РазобратьОбъявлениеПараметра()); - КонецЦикла; - КонецЕсли; - Ожидать(Токены.ПраваяКруглаяСкобка); - СледующийТокен(); - Возврат Параметры; -КонецФункции // РазобратьПараметры() - -Функция РазобратьОбъявлениеПараметра() - Перем Имя, ОбъявлениеПараметра, ПоЗначению, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Если Парсер_Токен = Токены.Знач Тогда - ПоЗначению = Истина; - СледующийТокен(); - Иначе - ПоЗначению = Ложь; - КонецЕсли; - Ожидать(Токены.Идентификатор); - Имя = Парсер_Литерал; - Если СледующийТокен() = Токены.ЗнакРавно Тогда - СледующийТокен(); - ОбъявлениеПараметра = Парсер_Узлы.ОбъявлениеПараметра.Добавить(); - ОбъявлениеПараметра.Тип = Типы.ОбъявлениеПараметра; - ОбъявлениеПараметра.Имя = Имя; - ОбъявлениеПараметра.ПоЗначению = ПоЗначению; - ОбъявлениеПараметра.Значение = РазобратьВыражениеУнарное(); - ОбъявлениеПараметра.Начало = Начало; - ОбъявлениеПараметра.Конец = Парсер_ДанныеПредыдущегоТокена; - Иначе - ОбъявлениеПараметра = Парсер_Узлы.ОбъявлениеПараметра.Добавить(); - ОбъявлениеПараметра.Тип = Типы.ОбъявлениеПараметра; - ОбъявлениеПараметра.Имя = Имя; - ОбъявлениеПараметра.ПоЗначению = ПоЗначению; - ОбъявлениеПараметра.Значение = Неопределено; - ОбъявлениеПараметра.Начало = Начало; - ОбъявлениеПараметра.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЕсли; - Если Парсер_Переменные.Свойство(Имя) Тогда - Ошибка(12, Имя, СтрогийРежим, Начало); - КонецЕсли; - ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); - ЭлементОкружения.Тип = Типы.ЭлементОкружения; - ЭлементОкружения.Имя = Имя; - ЭлементОкружения.Объявление = ОбъявлениеПараметра;; - Парсер_Переменные.Вставить(Имя, ЭлементОкружения); - Возврат ОбъявлениеПараметра; -КонецФункции // РазобратьОбъявлениеПараметра() - -#КонецОбласти // РазборОбъявлений - -#Область РазборОператоров - -Функция РазобратьОператоры() - Перем Операторы, Оператор; - Операторы = Новый Массив; - Оператор = РазобратьОператор(); - Если Оператор <> Неопределено Тогда - Операторы.Добавить(Оператор); - КонецЕсли; - Пока Истина Цикл - Если Парсер_Токен = Токены.ТочкаСЗапятой Тогда - СледующийТокен(); - ИначеЕсли Лев(Парсер_Токен, 1) <> "_" Тогда // если не препроцессор - Прервать; - КонецЕсли; - Оператор = РазобратьОператор(); - Если Оператор <> Неопределено Тогда - Операторы.Добавить(Оператор); - КонецЕсли; - КонецЦикла; - Возврат Операторы; -КонецФункции // РазобратьОператоры() - -Функция РазобратьОператор() - Перем Оператор; - Если Парсер_Токен = Токены.Идентификатор Тогда - Оператор = РазобратьОператорПрисваиванияИлиВызоваПроцедуры(); - ИначеЕсли Парсер_Токен = Токены.Если Тогда - Оператор = РазобратьОператорЕсли(); - ИначеЕсли Парсер_Токен = Токены.Попытка Тогда - Оператор = РазобратьОператорПопытка(); - ИначеЕсли Парсер_Токен = Токены.Пока Тогда - Оператор = РазобратьОператорПока(); - ИначеЕсли Парсер_Токен = Токены.Для Тогда - Если СледующийТокен() = Токены.Каждого Тогда - Оператор = РазобратьОператорДляКаждого(); - Иначе - Оператор = РазобратьОператорДля(); - КонецЕсли; - ИначеЕсли Парсер_Токен = Токены.Возврат Тогда - Оператор = РазобратьОператорВозврат(); - ИначеЕсли Парсер_Токен = Токены.Прервать Тогда - Оператор = РазобратьОператорПрервать(); - ИначеЕсли Парсер_Токен = Токены.Продолжить Тогда - Оператор = РазобратьОператорПродолжить(); - ИначеЕсли Парсер_Токен = Токены.ВызватьИсключение Тогда - Оператор = РазобратьОператорВызватьИсключение(); - ИначеЕсли Парсер_Токен = Токены.Выполнить Тогда - Оператор = РазобратьОператорВыполнить(); - ИначеЕсли Парсер_Токен = Токены.Перейти Тогда - Оператор = РазобратьОператорПерейти(); - ИначеЕсли Парсер_Токен = Токены.Метка Тогда - Оператор = РазобратьОператорМетка(); - ИначеЕсли Парсер_Токен = Токены.ДобавитьОбработчик Тогда - Оператор = РазобратьОператорДобавитьОбработчик(); - ИначеЕсли Парсер_Токен = Токены.УдалитьОбработчик Тогда - Оператор = РазобратьОператорУдалитьОбработчик(); - ИначеЕсли Парсер_Токен = Токены._Область Тогда - Оператор = РазобратьИнструкциюПрепроцессораОбласть(); - ИначеЕсли Парсер_Токен = Токены._КонецОбласти Тогда - Оператор = РазобратьИнструкциюПрепроцессораКонецОбласти(); - ИначеЕсли Парсер_Токен = Токены._Если Тогда - Оператор = РазобратьИнструкциюПрепроцессораЕсли(); - ИначеЕсли Парсер_Токен = Токены._ИначеЕсли Тогда - Оператор = РазобратьИнструкциюПрепроцессораИначеЕсли(); - ИначеЕсли Парсер_Токен = Токены._Иначе Тогда - Оператор = РазобратьИнструкциюПрепроцессораИначе(); - ИначеЕсли Парсер_Токен = Токены._КонецЕсли Тогда - Оператор = РазобратьИнструкциюПрепроцессораКонецЕсли(); - ИначеЕсли Парсер_Токен = Токены._Вставка Тогда - Оператор = РазобратьИнструкциюПрепроцессораВставка(); - ИначеЕсли Парсер_Токен = Токены._КонецВставки Тогда - Оператор = РазобратьИнструкциюПрепроцессораКонецВставки(); - ИначеЕсли Парсер_Токен = Токены._Удаление Тогда - Оператор = РазобратьИнструкциюПрепроцессораУдаление(); - ИначеЕсли Парсер_Токен = Токены._КонецУдаления Тогда - Оператор = РазобратьИнструкциюПрепроцессораКонецУдаления(); - ИначеЕсли Парсер_Токен = Токены.ТочкаСЗапятой Тогда - // NOP - КонецЕсли; - Возврат Оператор; -КонецФункции // РазобратьОператор() - -Функция РазобратьОператорВызватьИсключение() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Если ТокеныНачалаВыражения.Найти(СледующийТокен()) <> Неопределено Тогда - Выражение = РазобратьВыражение(); - КонецЕсли; - Узел = Парсер_Узлы.ОператорВызватьИсключение.Добавить(); - Узел.Тип = Типы.ОператорВызватьИсключение; - Узел.Выражение = Выражение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорВызватьИсключение() - -Функция РазобратьОператорВыполнить() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Узел = Парсер_Узлы.ОператорВыполнить.Добавить(); - Узел.Тип = Типы.ОператорВыполнить; - Узел.Выражение = РазобратьВыражение(); - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорВыполнить() - -Функция РазобратьОператорПрисваиванияИлиВызоваПроцедуры() - Перем ЛевыйОперанд, ЭтоВызов, ПравыйОперанд, Оператор, НоваяПеременная, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - ЛевыйОперанд = РазобратьВыражениеИдентификатор(Истина, НоваяПеременная, ЭтоВызов); - Если ЭтоВызов Тогда - Оператор = Парсер_Узлы.ОператорВызоваПроцедуры.Добавить(); - Оператор.Тип = Типы.ОператорВызоваПроцедуры; - Оператор.Идентификатор = ЛевыйОперанд; - Оператор.Начало = Начало; - Оператор.Конец = Парсер_ДанныеПредыдущегоТокена; - Иначе - Ожидать(Токены.ЗнакРавно); - СледующийТокен(); - ПравыйОперанд = РазобратьВыражение(); - Если НоваяПеременная <> Неопределено Тогда - Парсер_Переменные.Вставить(НоваяПеременная.Имя, НоваяПеременная); - Парсер_Окружение.АвтоПеременные.Добавить(НоваяПеременная.Объявление); - КонецЕсли; - Оператор = Парсер_Узлы.ОператорПрисваивания.Добавить(); - Оператор.Тип = Типы.ОператорПрисваивания; - Оператор.ЛевыйОперанд = ЛевыйОперанд; - Оператор.ПравыйОперанд = ПравыйОперанд; - Оператор.Начало = Начало; - Оператор.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЕсли; - Возврат Оператор; -КонецФункции // РазобратьОператорПрисваиванияИлиВызоваПроцедуры() - -Функция РазобратьОператорЕсли() - Перем Выражение, ТогдаОператоры, ОператорИначе, СписокИначеЕсли, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Выражение = РазобратьВыражение(); - Ожидать(Токены.Тогда); - СледующийТокен(); - ТогдаОператоры = РазобратьОператоры(); - Если Парсер_Токен = Токены.ИначеЕсли Тогда - СписокИначеЕсли = Новый Массив; - Пока Парсер_Токен = Токены.ИначеЕсли Цикл - СписокИначеЕсли.Добавить(РазобратьОператорИначеЕсли()); - КонецЦикла; - КонецЕсли; - Если Парсер_Токен = Токены.Иначе Тогда - ОператорИначе = РазобратьОператорИначе(); - КонецЕсли; - Ожидать(Токены.КонецЕсли); - СледующийТокен(); - Узел = Парсер_Узлы.ОператорЕсли.Добавить(); - Узел.Тип = Типы.ОператорЕсли; - Узел.Выражение = Выражение; - Узел.Тогда = ТогдаОператоры; - Узел.ИначеЕсли = СписокИначеЕсли; - Узел.Иначе = ОператорИначе; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорЕсли() - -Функция РазобратьОператорИначеЕсли() - Перем ЕслиВыражение, ТогдаОператоры, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЕслиВыражение = РазобратьВыражение(); - Ожидать(Токены.Тогда); - СледующийТокен(); - ТогдаОператоры = РазобратьОператоры(); - Узел = Парсер_Узлы.ОператорИначеЕсли.Добавить(); - Узел.Тип = Типы.ОператорИначеЕсли; - Узел.Выражение = ЕслиВыражение; - Узел.Тогда = ТогдаОператоры; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорИначеЕсли() - -Функция РазобратьОператорИначе() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Узел = Парсер_Узлы.ОператорИначе.Добавить(); - Узел.Тип = Типы.ОператорИначе; - Узел.Операторы = РазобратьОператоры(); - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорИначе() - -Функция РазобратьОператорПопытка() - Перем Операторы, ОператорИсключение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Операторы = РазобратьОператоры(); - Ожидать(Токены.Исключение); - ОператорИсключение = РазобратьОператорИсключение(); - Ожидать(Токены.КонецПопытки); - СледующийТокен(); - Узел = Парсер_Узлы.ОператорПопытка.Добавить(); - Узел.Тип = Типы.ОператорПопытка; - Узел.Попытка = Операторы; - Узел.Исключение = ОператорИсключение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорПопытка() - -Функция РазобратьОператорИсключение() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Узел = Парсер_Узлы.ОператорИсключение.Добавить(); - Узел.Тип = Типы.ОператорИсключение; - Узел.Операторы = РазобратьОператоры(); - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорИсключение() - -Функция РазобратьОператорПока() - Перем Выражение, Операторы, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Выражение = РазобратьВыражение(); - Ожидать(Токены.Цикл); - СледующийТокен(); - Операторы = РазобратьОператоры(); - Ожидать(Токены.КонецЦикла); - СледующийТокен(); - Узел = Парсер_Узлы.ОператорПока.Добавить(); - Узел.Тип = Типы.ОператорПока; - Узел.Выражение = Выражение; - Узел.Операторы = Операторы; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорПока() - -Функция РазобратьОператорДля() - Перем ВыражениеИдентификатор, ЭтоВызов, Начало, Операторы, ИндексТокенаПеременной, НоваяПеременная, Старт, Финиш; - Начало = Парсер_ДанныеПредыдущегоТокена; - Ожидать(Токены.Идентификатор); - ИндексТокенаПеременной = Парсер_ДанныеТекущегоТокена; - ВыражениеИдентификатор = РазобратьВыражениеИдентификатор(Истина, НоваяПеременная, ЭтоВызов); - Если ЭтоВызов Тогда - Ошибка(14, Неопределено, Истина, ИндексТокенаПеременной); - КонецЕсли; - Ожидать(Токены.ЗнакРавно); - СледующийТокен(); - Старт = РазобратьВыражение(); - Ожидать(Токены.По); - СледующийТокен(); - Финиш = РазобратьВыражение(); - Если НоваяПеременная <> Неопределено Тогда - Парсер_Переменные.Вставить(НоваяПеременная.Имя, НоваяПеременная); - Парсер_Окружение.АвтоПеременные.Добавить(НоваяПеременная.Объявление); - КонецЕсли; - Ожидать(Токены.Цикл); - СледующийТокен(); - Операторы = РазобратьОператоры(); - Ожидать(Токены.КонецЦикла); - СледующийТокен(); - Узел = Парсер_Узлы.ОператорДля.Добавить(); - Узел.Тип = Типы.ОператорДля; - Узел.Идентификатор = ВыражениеИдентификатор; - Узел.Старт = Старт; - Узел.Финиш = Финиш; - Узел.Операторы = Операторы; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорДля() - -Функция РазобратьОператорДляКаждого() - Перем ВыражениеИдентификатор, ЭтоВызов, Коллекция, Операторы, ИндексТокенаПеременной, НоваяПеременная, Начало; - Начало = Парсер_ДанныеПредыдущегоТокена; - СледующийТокен(); - Ожидать(Токены.Идентификатор); - ИндексТокенаПеременной = Парсер_ДанныеТекущегоТокена; - ВыражениеИдентификатор = РазобратьВыражениеИдентификатор(Истина, НоваяПеременная, ЭтоВызов); - Если ЭтоВызов Тогда - Ошибка(14, Неопределено, Истина, ИндексТокенаПеременной); - КонецЕсли; - Ожидать(Токены.Из); - СледующийТокен(); - Коллекция = РазобратьВыражение(); - Если НоваяПеременная <> Неопределено Тогда - Парсер_Переменные.Вставить(НоваяПеременная.Имя, НоваяПеременная); - Парсер_Окружение.АвтоПеременные.Добавить(НоваяПеременная.Объявление); - КонецЕсли; - Ожидать(Токены.Цикл); - СледующийТокен(); - Операторы = РазобратьОператоры(); - Ожидать(Токены.КонецЦикла); - СледующийТокен(); - Узел = Парсер_Узлы.ОператорДляКаждого.Добавить(); - Узел.Тип = Типы.ОператорДляКаждого; - Узел.Идентификатор = ВыражениеИдентификатор; - Узел.Коллекция = Коллекция; - Узел.Операторы = Операторы; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорДляКаждого() - -Функция РазобратьОператорПерейти() - Перем Метка, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Ожидать(Токены.Метка); - Метка = Парсер_Литерал; - СледующийТокен(); - Узел = Парсер_Узлы.ОператорПерейти.Добавить(); - Узел.Тип = Типы.ОператорПерейти; - Узел.Метка = Метка; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорПерейти() - -Функция РазобратьОператорВозврат() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Если Парсер_ЭтоФункция Тогда - Выражение = РазобратьВыражение(); - КонецЕсли; - Узел = Парсер_Узлы.ОператорВозврат.Добавить(); - Узел.Тип = Типы.ОператорВозврат; - Узел.Выражение = Выражение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорВозврат() - -Функция РазобратьОператорПрервать() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Узел = Парсер_Узлы.ОператорПрервать.Добавить(); - Узел.Тип = Типы.ОператорПрервать; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорПрервать() - -Функция РазобратьОператорПродолжить() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Узел = Парсер_Узлы.ОператорПродолжить.Добавить(); - Узел.Тип = Типы.ОператорПродолжить; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорПродолжить() - -Функция РазобратьОператорМетка() - Перем Метка, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Метка = Парсер_Литерал; - СледующийТокен(); - Ожидать(Токены.Двоеточие); - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ОператорМетка.Добавить(); - Узел.Тип = Типы.ОператорМетка; - Узел.Метка = Метка; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорМетка() - -Функция РазобратьОператорДобавитьОбработчик() - Перем Событие, ОбработчикСобытия, ЭтоВызов, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Ожидать(Токены.Идентификатор); - Событие = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); - Если ЭтоВызов Тогда - Ошибка(15, Неопределено, Истина, Начало); - КонецЕсли; - Ожидать(Токены.Запятая); - СледующийТокен(); - Ожидать(Токены.Идентификатор); - ОбработчикСобытия = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); - Если ЭтоВызов Тогда - Ошибка(16, Неопределено, Истина, Начало); - КонецЕсли; - Узел = Парсер_Узлы.ОператорДобавитьОбработчик.Добавить(); - Узел.Тип = Типы.ОператорДобавитьОбработчик; - Узел.Событие = Событие; - Узел.ОбработчикСобытия = ОбработчикСобытия; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорДобавитьОбработчик() - -Функция РазобратьОператорУдалитьОбработчик() - Перем Событие, ОбработчикСобытия, ЭтоВызов, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Ожидать(Токены.Идентификатор); - Событие = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); - Если ЭтоВызов Тогда - Ошибка(15, Неопределено, Истина, Начало); - КонецЕсли; - Ожидать(Токены.Запятая); - СледующийТокен(); - Ожидать(Токены.Идентификатор); - ОбработчикСобытия = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); - Если ЭтоВызов Тогда - Ошибка(16, Неопределено, Истина, Начало); - КонецЕсли; - Узел = Парсер_Узлы.ОператорУдалитьОбработчик.Добавить(); - Узел.Тип = Типы.ОператорУдалитьОбработчик; - Узел.Событие = Событие; - Узел.ОбработчикСобытия = ОбработчикСобытия; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьОператорУдалитьОбработчик() - -#КонецОбласти // РазборОператоров - -#Область РазборПрепроцессора - - // Выражения - -Функция РазобратьВыражениеПрепроцессора() - Перем Выражение, Операция, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Выражение = РазобратьВыражениеПрепроцессораИ(); - Пока Парсер_Токен = Токены.Или Цикл - Операция = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЛевыйОперанд = Выражение; - Выражение = Парсер_Узлы.ВыражениеПрепроцессораБинарное.Добавить(); - Выражение.Тип = Типы.ВыражениеПрепроцессораБинарное; - Выражение.ЛевыйОперанд = ЛевыйОперанд; - Выражение.Операция = Операция; - Выражение.ПравыйОперанд = РазобратьВыражениеПрепроцессораИ(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЦикла; - Возврат Выражение; -КонецФункции // РазобратьВыражениеПрепроцессора() - -Функция РазобратьВыражениеПрепроцессораИ() - Перем Выражение, Операция, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Выражение = РазобратьВыражениеПрепроцессораНе(); - Пока Парсер_Токен = Токены.И Цикл - Операция = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - ЛевыйОперанд = Выражение; - Выражение = Парсер_Узлы.ВыражениеПрепроцессораБинарное.Добавить(); - Выражение.Тип = Типы.ВыражениеПрепроцессораБинарное; - Выражение.ЛевыйОперанд = ЛевыйОперанд; - Выражение.Операция = Операция; - Выражение.ПравыйОперанд = РазобратьВыражениеПрепроцессораНе(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - КонецЦикла; - Возврат Выражение; -КонецФункции // РазобратьВыражениеПрепроцессораИ() - -Функция РазобратьВыражениеПрепроцессораНе() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Если Парсер_Токен = Токены.Не Тогда - СледующийТокен(); - Выражение = Парсер_Узлы.ВыражениеПрепроцессораНе.Добавить(); - Выражение.Тип = Типы.ВыражениеПрепроцессораНе; - Выражение.Выражение = РазобратьВыражениеПрепроцессораОперанд(); - Выражение.Начало = Начало; - Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; - Иначе - Выражение = РазобратьВыражениеПрепроцессораОперанд(); - КонецЕсли; - Возврат Выражение; -КонецФункции // РазобратьВыражениеПрепроцессораНе() - -Функция РазобратьВыражениеПрепроцессораОперанд() - Перем Операнд; - Если Парсер_Токен = Токены.Идентификатор Тогда - Операнд = РазобратьВыражениеПрепроцессораСимвол(); - ИначеЕсли Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда - Операнд = РазобратьВыражениеПрепроцессораСкобочное(); - Иначе - Ошибка(7, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - Возврат Операнд; -КонецФункции - -Функция РазобратьВыражениеПрепроцессораСимвол() - Перем Символ, СимволСуществует; - СимволСуществует = СимволыПрепроцессора.Свойство(Парсер_Литерал); - Символ = Парсер_Узлы.ВыражениеПрепроцессораСимвол.Добавить(); - Символ.Тип = Типы.ВыражениеПрепроцессораСимвол; - Символ.Символ = Парсер_Литерал; - Символ.Существует = СимволСуществует; - Символ.Начало = Парсер_ДанныеТекущегоТокена; - Символ.Конец = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Возврат Символ; -КонецФункции // РазобратьВыражениеПрепроцессораСимвол() - -Функция РазобратьВыражениеПрепроцессораСкобочное() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Выражение = РазобратьВыражениеПрепроцессора(); - Ожидать(Токены.ПраваяКруглаяСкобка); - СледующийТокен(); - Узел = Парсер_Узлы.ВыражениеПрепроцессораСкобочное.Добавить(); - Узел.Тип = Типы.ВыражениеПрепроцессораСкобочное; - Узел.Выражение = Выражение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьВыражениеПрепроцессораСкобочное() - -// Инструкции - -Функция РазобратьИнструкциюПрепроцессораЕсли() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Выражение = РазобратьВыражениеПрепроцессора(); - Ожидать(Токены.Тогда); - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораЕсли.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораЕсли; - Узел.Выражение = Выражение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораЕсли() - -Функция РазобратьИнструкциюПрепроцессораИначеЕсли() - Перем Выражение, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Выражение = РазобратьВыражениеПрепроцессора(); - Ожидать(Токены.Тогда); - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораИначеЕсли.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораИначеЕсли; - Узел.Выражение = Выражение; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеПредыдущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораИначеЕсли() - -Функция РазобратьИнструкциюПрепроцессораИначе() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораИначе.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораИначе; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораИначе() - -Функция РазобратьИнструкциюПрепроцессораКонецЕсли() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецЕсли.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораКонецЕсли; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораКонецЕсли() - -Функция РазобратьИнструкциюПрепроцессораОбласть() - Перем Имя, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Ожидать(Токены.Идентификатор); - Имя = Парсер_Литерал; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораОбласть.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораОбласть; - Узел.Имя = Имя; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораОбласть() - -Функция РазобратьИнструкциюПрепроцессораКонецОбласти() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецОбласти.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораКонецОбласти; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораКонецОбласти() - -Функция РазобратьИнструкциюПрепроцессораВставка() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораВставка.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораВставка; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораВставка() - -Функция РазобратьИнструкциюПрепроцессораКонецВставки() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецВставки.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораКонецВставки; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораКонецВставки() - -Функция РазобратьИнструкциюПрепроцессораУдаление() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораУдаление.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораУдаление; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораУдаление() - -Функция РазобратьИнструкциюПрепроцессораКонецУдаления() - Перем Начало; - Начало = Парсер_ДанныеТекущегоТокена; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецУдаления.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораКонецУдаления; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораКонецУдаления() - -Функция РазобратьИнструкциюПрепроцессораИспользовать() - Перем Путь, Начало; - Начало = Парсер_ДанныеТекущегоТокена; - СледующийТокен(); - Если Парсер_НомерТекущейСтроки <> Начало.НомерСтроки Тогда - Ошибка(20, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - Если Парсер_Токен = Токены.Число Тогда - Путь = Парсер_Литерал; - Если КартаБуквЦифр[Парсер_Символ] = Буква Тогда - СледующийТокен(); - Путь = Путь + Парсер_Литерал; - КонецЕсли; - ИначеЕсли Парсер_Токен = Токены.Идентификатор - Или Парсер_Токен = Токены.Строка Тогда - Путь = Парсер_Литерал; - Иначе - Ошибка(20, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); - КонецЕсли; - Парсер_Токен = Токены.ТочкаСЗапятой; // уловка - Узел = Парсер_Узлы.ИнструкцияПрепроцессораИспользовать.Добавить(); - Узел.Тип = Типы.ИнструкцияПрепроцессораИспользовать; - Узел.Путь = Путь; - Узел.Начало = Начало; - Узел.Конец = Парсер_ДанныеТекущегоТокена; - Возврат Узел; -КонецФункции // РазобратьИнструкциюПрепроцессораИспользовать() - -#КонецОбласти // РазборПрепроцессора - -#КонецОбласти // Парсер - -#Область СлужебныеМетоды - -Функция Доступность(Клиент, ВнешнееСоединение, МобильноеПриложение, МобильныйКлиент, МобильныйСервер, Сервер, ТолстыйКлиент, ТонкийКлиент, ВебКлиент, Интеграция) Экспорт - Возврат Новый Структура( - "Клиент, ВнешнееСоединение, МобильноеПриложение, МобильныйКлиент, МобильныйСервер, Сервер, ТолстыйКлиент, ТонкийКлиент, ВебКлиент, Интеграция", - Клиент, ВнешнееСоединение, МобильноеПриложение, МобильныйКлиент, МобильныйСервер, Сервер, ТолстыйКлиент, ТонкийКлиент, ВебКлиент, Интеграция - ); -КонецФункции - -Функция КакДата(ЛитералДаты) - Перем Список, Символ, Позиция, ДатаСтрокой, Дата; - Список = Новый Массив; - Для Позиция = 1 По СтрДлина(ЛитералДаты) Цикл - Символ = Сред(ЛитералДаты, Позиция, 1); - Если КартаБуквЦифр[Символ] = Цифра Тогда - Список.Добавить(Символ); - КонецЕсли; - КонецЦикла; - ДатаСтрокой = СтрСоединить(Список); - Если ДатаСтрокой = "00000000" - Или ДатаСтрокой = "000000000000" - Или ДатаСтрокой = "00000000000000" Тогда - Возврат '00010101'; - КонецЕсли; - Попытка - Дата = Дата(ДатаСтрокой); - Исключение - Ошибка(18, ЛитералДаты, Истина); - КонецПопытки; - Возврат Дата; -КонецФункции // КакДата() - -Процедура Ожидать(Токен) - Если Парсер_Токен <> Токен Тогда - Ошибка(1, Токен, Истина, Парсер_ДанныеТекущегоТокена); - КонецЕсли; -КонецПроцедуры // Ожидать() - -Процедура Ошибка(Код, Аргумент, Остановить, Начало = Неопределено, Конец = Неопределено) - Перем Ошибка, ТокенНачала, ТокенКонца; - Ошибка = Парсер_Ошибки.Добавить(); - Ошибка.Источник = "ПарсерВстроенногоЯзыка"; - Ошибка.Код = Код; - Ошибка.Текст = Ошибки[Код] + ?(Аргумент = Неопределено, "", ": " + Аргумент); - Если Начало = Неопределено Тогда - ТокенНачала = Новый Структура; - ТокенНачала.Вставить("Токен", Неопределено); - ТокенНачала.Вставить("НомерСтроки", Парсер_НомерТекущейСтроки); - ТокенНачала.Вставить("НомерКолонки", Парсер_ПозицияНачалаТокена - Парсер_ПозицияТекущейСтроки); - ТокенНачала.Вставить("Позиция", Парсер_ПозицияНачалаТокена); - ТокенНачала.Вставить("Длина", Парсер_ТекущаяПозиция - Парсер_ПозицияНачалаТокена); - Иначе - ТокенНачала = Начало; - КонецЕсли; - Если Конец = Неопределено Тогда - ТокенКонца = ТокенНачала; - Иначе - ТокенКонца = Конец; - КонецЕсли; - Ошибка.ПозицияНачала = Мин(ТокенНачала.Позиция, Парсер_ДлинаИсходника); - Ошибка.НомерСтрокиНачала = ТокенНачала.НомерСтроки; - Ошибка.НомерКолонкиНачала = ТокенНачала.НомерКолонки; - Ошибка.ПозицияКонца = Мин(ТокенКонца.Позиция + ТокенКонца.Длина, Парсер_ДлинаИсходника + 1); - Ошибка.НомерСтрокиКонца = ТокенКонца.НомерСтроки; - Ошибка.НомерКолонкиКонца = ТокенКонца.НомерКолонки; - Если Остановить Тогда - ВызватьИсключение Ошибка.Текст; - КонецЕсли; -КонецПроцедуры // Ошибка() - -#КонецОбласти // СлужебныеМетоды - -#Область Посетитель - -Процедура Подключить(Знач Плагины) Экспорт - Перем Плагин, Список, ИмяПроцедуры; - Если ТипЗнч(Плагины) <> Тип("Массив") Тогда - Плагин = Плагины; - Плагины = Новый Массив; - Плагины.Добавить(Плагин); - КонецЕсли; - Посетитель_Плагины = Плагины; - Посетитель_Подписки = Подписки(); - Для Каждого Плагин Из Плагины Цикл - Список = Неопределено; - Для Каждого ИмяПроцедуры Из Плагин.Подписки() Цикл - Если Посетитель_Подписки.Свойство(ИмяПроцедуры, Список) Тогда - Список.Добавить(Плагин); - КонецЕсли; - КонецЦикла; - КонецЦикла; -КонецПроцедуры // Подключить() - -Функция Стек() Экспорт - Возврат Посетитель_Стек; -КонецФункции - -Функция Счетчики() Экспорт - Возврат Посетитель_Счетчики; -КонецФункции - -Процедура ДобавитьНаСтек(Узел) - Посетитель_Стек.Добавить(Узел); - Посетитель_Счетчики[Узел.Тип] = Посетитель_Счетчики[Узел.Тип] + 1; -КонецПроцедуры // ДобавитьНаСтек() - -Процедура УдалитьСоСтека() - Перем Узел, Вершина; - Вершина = Посетитель_Стек.ВГраница(); - Узел = Посетитель_Стек[Вершина]; - Посетитель_Счетчики[Узел.Тип] = Посетитель_Счетчики[Узел.Тип] - 1; - Посетитель_Стек.Удалить(Вершина); -КонецПроцедуры // УдалитьСоСтека() - -Функция Подписки() - Перем Подписки, Элемент; - - Подписки = Новый Структура( - "ПосетитьМодуль, ПокинутьМодуль," - "ПосетитьОбъявления, ПокинутьОбъявления," - "ПосетитьОператоры, ПокинутьОператоры," - "ПосетитьОбъявлениеСпискаПеременныхМодуля, ПокинутьОбъявлениеСпискаПеременныхМодуля," - "ПосетитьОбъявлениеПеременнойМодуля, ПокинутьОбъявлениеПеременнойМодуля," - "ПосетитьОбъявлениеСпискаЛокальныхПеременных, ПокинутьОбъявлениеСпискаЛокальныхПеременных," - "ПосетитьОбъявлениеЛокальнойПеременной, ПокинутьОбъявлениеЛокальнойПеременной," - "ПосетитьОбъявлениеПараметра, ПокинутьОбъявлениеПараметра," - "ПосетитьОбъявлениеМетода, ПокинутьОбъявлениеМетода," - "ПосетитьСигнатуру, ПокинутьСигнатуру," - "ПосетитьВыражение, ПокинутьВыражение," // вызываются один раз для корня выражения - "ПосетитьВыражениеЛитерал, ПокинутьВыражениеЛитерал," - "ПосетитьВыражениеИдентификатор, ПокинутьВыражениеИдентификатор," - "ПосетитьВыражениеУнарное, ПокинутьВыражениеУнарное," - "ПосетитьВыражениеБинарное, ПокинутьВыражениеБинарное," - "ПосетитьВыражениеНовый, ПокинутьВыражениеНовый," - "ПосетитьВыражениеТернарное, ПокинутьВыражениеТернарное," - "ПосетитьВыражениеСкобочное, ПокинутьВыражениеСкобочное," - "ПосетитьВыражениеНе, ПокинутьВыражениеНе," - "ПосетитьВыражениеСтроковое, ПокинутьВыражениеСтроковое," - "ПосетитьОператорПрисваивания, ПокинутьОператорПрисваивания," - "ПосетитьОператорВозврат, ПокинутьОператорВозврат," - "ПосетитьОператорПрервать, ПокинутьОператорПрервать," - "ПосетитьОператорПродолжить, ПокинутьОператорПродолжить," - "ПосетитьОператорВызватьИсключение, ПокинутьОператорВызватьИсключение," - "ПосетитьОператорВыполнить, ПокинутьОператорВыполнить," - "ПосетитьОператорВызоваПроцедуры, ПокинутьОператорВызоваПроцедуры," - "ПосетитьОператорЕсли, ПокинутьОператорЕсли," - "ПосетитьОператорИначеЕсли, ПокинутьОператорИначеЕсли," - "ПосетитьОператорИначе, ПокинутьОператорИначе," - "ПосетитьОператорПока, ПокинутьОператорПока," - "ПосетитьОператорДля, ПокинутьОператорДля," - "ПосетитьОператорДляКаждого, ПокинутьОператорДляКаждого," - "ПосетитьОператорПопытка, ПокинутьОператорПопытка," - "ПосетитьОператорИсключение, ПокинутьОператорИсключение," - "ПосетитьОператорПерейти, ПокинутьОператорПерейти," - "ПосетитьОператорМетка, ПокинутьОператорМетка," - "ПосетитьОператорДобавитьОбработчик, ПокинутьОператорДобавитьОбработчик," - "ПосетитьОператорУдалитьОбработчик, ПокинутьОператорУдалитьОбработчик," - "ПосетитьИнструкциюПрепроцессора, ПокинутьИнструкциюПрепроцессора," - "ПосетитьВыражениеПрепроцессора, ПокинутьВыражениеПрепроцессора," - "ПосетитьВыражениеПрепроцессораБинарное, ПокинутьВыражениеПрепроцессораБинарное," - "ПосетитьВыражениеПрепроцессораНе, ПокинутьВыражениеПрепроцессораНе," - "ПосетитьВыражениеПрепроцессораСимвол, ПокинутьВыражениеПрепроцессораСимвол," - "ПосетитьВыражениеПрепроцессораСкобочное, ПокинутьВыражениеПрепроцессораСкобочное" - ); - - Для Каждого Элемент Из Подписки Цикл - Подписки[Элемент.Ключ] = Новый Массив; - КонецЦикла; - - Возврат Подписки; -КонецФункции // Подписки() - -Процедура Посетить(Модуль, Параметры = Неопределено) Экспорт - Перем Плагин, Подписка, Элемент, ПараметрыПлагина; - Если Параметры = Неопределено Тогда - Параметры = Новый Соответствие; - КонецЕсли; - Посетитель_Стек = Новый Массив; - Посетитель_Счетчики = Новый Структура; - Для Каждого Элемент Из Типы Цикл - Посетитель_Счетчики.Вставить(Элемент.Ключ, 0); - КонецЦикла; - Для Каждого Плагин Из Посетитель_Плагины Цикл - Попытка - // 1С - на платформе обработка не может быть ключом соответствия, но свойство ЭтотОбъект может - // ¯\_(ツ)_/¯ - ПараметрыПлагина = Параметры[Плагин.ЭтотОбъект]; - Исключение - // onescript - ПараметрыПлагина = Параметры[Плагин]; - КонецПопытки; - Плагин.Открыть(ЭтотОбъект, ПараметрыПлагина); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьМодуль Цикл - Подписка.ПосетитьМодуль(Модуль); - КонецЦикла; - ДобавитьНаСтек(Модуль); - ПосетитьОбъявления(Модуль.Объявления); - ПосетитьОператоры(Модуль.Операторы); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьМодуль Цикл - Подписка.ПокинутьМодуль(Модуль); - КонецЦикла; -КонецПроцедуры // Посетить() - -Процедура ПосетитьОбъявления(Объявления) - Перем Объявление, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявления Цикл - Подписка.ПосетитьОбъявления(Объявления); - КонецЦикла; - Для Каждого Объявление Из Объявления Цикл - ПосетитьОбъявлениеПоТипу(Объявление); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявления Цикл - Подписка.ПокинутьОбъявления(Объявления); - КонецЦикла; -КонецПроцедуры // ПосетитьОбъявления() - -Процедура ПосетитьОператоры(Операторы) - Перем Оператор, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператоры Цикл - Подписка.ПосетитьОператоры(Операторы); - КонецЦикла; - Для Каждого Оператор Из Операторы Цикл - ПосетитьОператорПоТипу(Оператор); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператоры Цикл - Подписка.ПокинутьОператоры(Операторы); - КонецЦикла; -КонецПроцедуры // ПосетитьОператоры() - -#Область ПосещениеОбъявлений - -Процедура ПосетитьОбъявлениеПоТипу(Объявление) - Перем Тип; - Тип = Объявление.Тип; - Если Тип = Типы.ОбъявлениеСпискаПеременныхМодуля Тогда - ПосетитьОбъявлениеСпискаПеременныхМодуля(Объявление); - ИначеЕсли Тип = Типы.ОбъявлениеЛокальнойПеременной Тогда - ПосетитьОбъявлениеЛокальнойПеременной(Объявление); - ИначеЕсли Тип = Типы.ОбъявлениеМетода Тогда - ПосетитьОбъявлениеМетода(Объявление); - ИначеЕсли Тип = Типы.ИнструкцияПрепроцессораОбласть - Или Тип = Типы.ИнструкцияПрепроцессораКонецОбласти - Или Тип = Типы.ИнструкцияПрепроцессораЕсли - Или Тип = Типы.ИнструкцияПрепроцессораИначеЕсли - Или Тип = Типы.ИнструкцияПрепроцессораИначе - Или Тип = Типы.ИнструкцияПрепроцессораКонецЕсли - Или Тип = Типы.ИнструкцияПрепроцессораИспользовать Тогда - ПосетитьИнструкциюПрепроцессора(Объявление); - КонецЕсли; -КонецПроцедуры // ПосетитьОбъявлениеПоТипу() - -Процедура ПосетитьОбъявлениеСпискаПеременныхМодуля(ОбъявлениеСпискаПеременныхМодуля) - Перем Подписка, ОбъявлениеПеременнойМодуля; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеСпискаПеременныхМодуля Цикл - Подписка.ПосетитьОбъявлениеСпискаПеременныхМодуля(ОбъявлениеСпискаПеременныхМодуля); - КонецЦикла; - ДобавитьНаСтек(ОбъявлениеСпискаПеременныхМодуля); - Для Каждого ОбъявлениеПеременнойМодуля Из ОбъявлениеСпискаПеременныхМодуля.Объявления Цикл - ПосетитьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля); - КонецЦикла; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеСпискаПеременныхМодуля Цикл - Подписка.ПокинутьОбъявлениеСпискаПеременныхМодуля(ОбъявлениеСпискаПеременныхМодуля); - КонецЦикла; -КонецПроцедуры // ПосетитьОбъявлениеСпискаПеременныхМодуля() - -Процедура ПосетитьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеПеременнойМодуля Цикл - Подписка.ПосетитьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеПеременнойМодуля Цикл - Подписка.ПокинутьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля); - КонецЦикла; -КонецПроцедуры // ПосетитьОбъявлениеПеременнойМодуля() - -Процедура ПосетитьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных) - Перем Подписка, ОбъявлениеЛокальнойПеременной; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеСпискаЛокальныхПеременных Цикл - Подписка.ПосетитьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных); - КонецЦикла; - ДобавитьНаСтек(ОбъявлениеСпискаЛокальныхПеременных); - Для Каждого ОбъявлениеЛокальнойПеременной Из ОбъявлениеСпискаЛокальныхПеременных.Объявления Цикл - ПосетитьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной); - КонецЦикла; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеСпискаЛокальныхПеременных Цикл - Подписка.ПокинутьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных); - КонецЦикла; -КонецПроцедуры // ПосетитьОбъявлениеСпискаЛокальныхПеременных() - -Процедура ПосетитьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеЛокальнойПеременной Цикл - Подписка.ПосетитьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеЛокальнойПеременной Цикл - Подписка.ПокинутьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной); - КонецЦикла; -КонецПроцедуры // ПосетитьОбъявлениеЛокальнойПеременной() - -Процедура ПосетитьОбъявлениеПараметра(ОбъявлениеПараметра) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеПараметра Цикл - Подписка.ПосетитьОбъявлениеПараметра(ОбъявлениеПараметра); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеПараметра Цикл - Подписка.ПокинутьОбъявлениеПараметра(ОбъявлениеПараметра); - КонецЦикла; -КонецПроцедуры // ПосетитьОбъявлениеПараметра() - -Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) - Перем Подписка, ОбъявлениеСпискаЛокальныхПеременных; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеМетода Цикл - Подписка.ПосетитьОбъявлениеМетода(ОбъявлениеМетода); - КонецЦикла; - ДобавитьНаСтек(ОбъявлениеМетода); - ПосетитьСигнатуру(ОбъявлениеМетода.Сигнатура); - Для Каждого ОбъявлениеСпискаЛокальныхПеременных Из ОбъявлениеМетода.Объявления Цикл - ПосетитьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных); - КонецЦикла; - ПосетитьОператоры(ОбъявлениеМетода.Операторы); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеМетода Цикл - Подписка.ПокинутьОбъявлениеМетода(ОбъявлениеМетода); - КонецЦикла; -КонецПроцедуры // ПосетитьОбъявлениеМетода() - -Процедура ПосетитьСигнатуру(Сигнатура) - Перем Подписка, ОбъявлениеПараметра; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьСигнатуру Цикл - Подписка.ПосетитьСигнатуру(Сигнатура); - КонецЦикла; - ДобавитьНаСтек(Сигнатура); - Для Каждого ОбъявлениеПараметра Из Сигнатура.Параметры Цикл - ПосетитьОбъявлениеПараметра(ОбъявлениеПараметра); - КонецЦикла; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьСигнатуру Цикл - Подписка.ПокинутьСигнатуру(Сигнатура); - КонецЦикла; -КонецПроцедуры // ПосетитьСигнатуру() - -#КонецОбласти // ПосещениеОбъявлений - -#Область ПосещениеВыражений - -Процедура ПосетитьВыражение(Выражение) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражение Цикл - Подписка.ПосетитьВыражение(Выражение); - КонецЦикла; - ПосетитьВыражениеПоТипу(Выражение); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражение Цикл - Подписка.ПокинутьВыражение(Выражение); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражение() - -Процедура ПосетитьВыражениеПоТипу(Выражение) - Перем Тип; - Тип = Выражение.Тип; - Если Тип = Типы.ВыражениеЛитерал Тогда - ПосетитьВыражениеЛитерал(Выражение); - ИначеЕсли Тип = Типы.ВыражениеИдентификатор Тогда - ПосетитьВыражениеИдентификатор(Выражение); - ИначеЕсли Тип = Типы.ВыражениеУнарное Тогда - ПосетитьВыражениеУнарное(Выражение); - ИначеЕсли Тип = Типы.ВыражениеБинарное Тогда - ПосетитьВыражениеБинарное(Выражение); - ИначеЕсли Тип = Типы.ВыражениеНовый Тогда - ПосетитьВыражениеНовый(Выражение); - ИначеЕсли Тип = Типы.ВыражениеТернарное Тогда - ПосетитьВыражениеТернарное(Выражение); - ИначеЕсли Тип = Типы.ВыражениеСкобочное Тогда - ПосетитьВыражениеСкобочное(Выражение); - ИначеЕсли Тип = Типы.ВыражениеНе Тогда - ПосетитьВыражениеНе(Выражение); - ИначеЕсли Тип = Типы.ВыражениеСтроковое Тогда - ПосетитьВыражениеСтроковое(Выражение); - КонецЕсли; -КонецПроцедуры // ПосетитьВыражениеПоТипу() - -Процедура ПосетитьВыражениеЛитерал(ВыражениеЛитерал) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеЛитерал Цикл - Подписка.ПосетитьВыражениеЛитерал(ВыражениеЛитерал); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеЛитерал Цикл - Подписка.ПокинутьВыражениеЛитерал(ВыражениеЛитерал); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеЛитерал() - -Процедура ПосетитьВыражениеИдентификатор(ВыражениеИдентификатор) - Перем Элемент, Выражение, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеИдентификатор Цикл - Подписка.ПосетитьВыражениеИдентификатор(ВыражениеИдентификатор); - КонецЦикла; - ДобавитьНаСтек(ВыражениеИдентификатор); - Если ВыражениеИдентификатор.Аргументы <> Неопределено Тогда - Для Каждого Выражение Из ВыражениеИдентификатор.Аргументы Цикл - Если Выражение <> Неопределено Тогда - ПосетитьВыражениеПоТипу(Выражение); - КонецЕсли; - КонецЦикла; - КонецЕсли; - Для Каждого Элемент Из ВыражениеИдентификатор.Хвост Цикл - Если Элемент.Тип = Типы.ВыражениеПоле Тогда - Если Элемент.Аргументы <> Неопределено Тогда - Для Каждого Выражение Из Элемент.Аргументы Цикл - Если Выражение <> Неопределено Тогда - ПосетитьВыражениеПоТипу(Выражение); - КонецЕсли; - КонецЦикла; - КонецЕсли; - ИначеЕсли Элемент.Тип = Типы.ВыражениеИндекс Тогда - ПосетитьВыражениеПоТипу(Элемент.Выражение); - Иначе - ВызватьИсключение "нарушение протокола"; - КонецЕсли; - КонецЦикла; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеИдентификатор Цикл - Подписка.ПокинутьВыражениеИдентификатор(ВыражениеИдентификатор); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеИдентификатор() - -Процедура ПосетитьВыражениеУнарное(ВыражениеУнарное) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеУнарное Цикл - Подписка.ПосетитьВыражениеУнарное(ВыражениеУнарное); - КонецЦикла; - ДобавитьНаСтек(ВыражениеУнарное); - ПосетитьВыражениеПоТипу(ВыражениеУнарное.Операнд); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеУнарное Цикл - Подписка.ПокинутьВыражениеУнарное(ВыражениеУнарное); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеУнарное() - -Процедура ПосетитьВыражениеБинарное(ВыражениеБинарное) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеБинарное Цикл - Подписка.ПосетитьВыражениеБинарное(ВыражениеБинарное); - КонецЦикла; - ДобавитьНаСтек(ВыражениеБинарное); - ПосетитьВыражениеПоТипу(ВыражениеБинарное.ЛевыйОперанд); - ПосетитьВыражениеПоТипу(ВыражениеБинарное.ПравыйОперанд); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеБинарное Цикл - Подписка.ПокинутьВыражениеБинарное(ВыражениеБинарное); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеБинарное() - -Процедура ПосетитьВыражениеНовый(ВыражениеНовый) - Перем Выражение, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеНовый Цикл - Подписка.ПосетитьВыражениеНовый(ВыражениеНовый); - КонецЦикла; - ДобавитьНаСтек(ВыражениеНовый); - Для Каждого Выражение Из ВыражениеНовый.Аргументы Цикл - Если Выражение <> Неопределено Тогда - ПосетитьВыражениеПоТипу(Выражение); - КонецЕсли; - КонецЦикла; - Для Каждого Элемент Из ВыражениеНовый.Хвост Цикл - Если Элемент.Тип = Типы.ВыражениеПоле Тогда - Если Элемент.Аргументы <> Неопределено Тогда - Для Каждого Выражение Из Элемент.Аргументы Цикл - Если Выражение <> Неопределено Тогда - ПосетитьВыражениеПоТипу(Выражение); - КонецЕсли; - КонецЦикла; - КонецЕсли; - ИначеЕсли Элемент.Тип = Типы.ВыражениеИндекс Тогда - ПосетитьВыражениеПоТипу(Элемент.Выражение); - Иначе - ВызватьИсключение "нарушение протокола"; - КонецЕсли; - КонецЦикла; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеНовый Цикл - Подписка.ПокинутьВыражениеНовый(ВыражениеНовый); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеНовый() - -Процедура ПосетитьВыражениеТернарное(ВыражениеТернарное) - Перем Элемент, Выражение, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеТернарное Цикл - Подписка.ПосетитьВыражениеТернарное(ВыражениеТернарное); - КонецЦикла; - ДобавитьНаСтек(ВыражениеТернарное); - ПосетитьВыражениеПоТипу(ВыражениеТернарное.Выражение); - ПосетитьВыражениеПоТипу(ВыражениеТернарное.Тогда); - ПосетитьВыражениеПоТипу(ВыражениеТернарное.Иначе); - Для Каждого Элемент Из ВыражениеТернарное.Хвост Цикл - Если Элемент.Тип = Типы.ВыражениеПоле Тогда - Если Элемент.Аргументы <> Неопределено Тогда - Для Каждого Выражение Из Элемент.Аргументы Цикл - Если Выражение <> Неопределено Тогда - ПосетитьВыражениеПоТипу(Выражение); - КонецЕсли; - КонецЦикла; - КонецЕсли; - ИначеЕсли Элемент.Тип = Типы.ВыражениеИндекс Тогда - ПосетитьВыражениеПоТипу(Элемент.Выражение); - Иначе - ВызватьИсключение "нарушение протокола"; - КонецЕсли; - КонецЦикла; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеТернарное Цикл - Подписка.ПокинутьВыражениеТернарное(ВыражениеТернарное); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеТернарное() - -Процедура ПосетитьВыражениеСкобочное(ВыражениеСкобочное) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеСкобочное Цикл - Подписка.ПосетитьВыражениеСкобочное(ВыражениеСкобочное); - КонецЦикла; - ДобавитьНаСтек(ВыражениеСкобочное); - ПосетитьВыражениеПоТипу(ВыражениеСкобочное.Выражение); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеСкобочное Цикл - Подписка.ПокинутьВыражениеСкобочное(ВыражениеСкобочное); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеСкобочное() - -Процедура ПосетитьВыражениеНе(ВыражениеНе) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеНе Цикл - Подписка.ПосетитьВыражениеНе(ВыражениеНе); - КонецЦикла; - ДобавитьНаСтек(ВыражениеНе); - ПосетитьВыражениеПоТипу(ВыражениеНе.Выражение); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеНе Цикл - Подписка.ПокинутьВыражениеНе(ВыражениеНе); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеНе() - -Процедура ПосетитьВыражениеСтроковое(ВыражениеСтроковое) - Перем Выражение, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеСтроковое Цикл - Подписка.ПосетитьВыражениеСтроковое(ВыражениеСтроковое); - КонецЦикла; - ДобавитьНаСтек(ВыражениеСтроковое); - Для Каждого Выражение Из ВыражениеСтроковое.Элементы Цикл - ПосетитьВыражениеЛитерал(Выражение); - КонецЦикла; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеСтроковое Цикл - Подписка.ПокинутьВыражениеСтроковое(ВыражениеСтроковое); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеСтроковое() - -#КонецОбласти // ПосещениеВыражений - -#Область ПосещениеОператоров - -Процедура ПосетитьОператорПоТипу(Оператор) - Перем Тип; - Тип = Оператор.Тип; - Если Тип = Типы.ОператорПрисваивания Тогда - ПосетитьОператорПрисваивания(Оператор); - ИначеЕсли Тип = Типы.ОператорВозврат Тогда - ПосетитьОператорВозврат(Оператор); - ИначеЕсли Тип = Типы.ОператорПрервать Тогда - ПосетитьОператорПрервать(Оператор); - ИначеЕсли Тип = Типы.ОператорПродолжить Тогда - ПосетитьОператорПродолжить(Оператор); - ИначеЕсли Тип = Типы.ОператорВызватьИсключение Тогда - ПосетитьОператорВызватьИсключение(Оператор); - ИначеЕсли Тип = Типы.ОператорВыполнить Тогда - ПосетитьОператорВыполнить(Оператор); - ИначеЕсли Тип = Типы.ОператорВызоваПроцедуры Тогда - ПосетитьОператорВызоваПроцедуры(Оператор); - ИначеЕсли Тип = Типы.ОператорЕсли Тогда - ПосетитьОператорЕсли(Оператор); - ИначеЕсли Тип = Типы.ОператорПока Тогда - ПосетитьОператорПока(Оператор); - ИначеЕсли Тип = Типы.ОператорДля Тогда - ПосетитьОператорДля(Оператор); - ИначеЕсли Тип = Типы.ОператорДляКаждого Тогда - ПосетитьОператорДляКаждого(Оператор); - ИначеЕсли Тип = Типы.ОператорПопытка Тогда - ПосетитьОператорПопытка(Оператор); - ИначеЕсли Тип = Типы.ОператорПерейти Тогда - ПосетитьОператорПерейти(Оператор); - ИначеЕсли Тип = Типы.ОператорМетка Тогда - ПосетитьОператорМетка(Оператор); - ИначеЕсли Тип = Типы.ОператорДобавитьОбработчик Тогда - ПосетитьОператорДобавитьОбработчик(Оператор); - ИначеЕсли Тип = Типы.ОператорУдалитьОбработчик Тогда - ПосетитьОператорУдалитьОбработчик(Оператор); - ИначеЕсли Тип = Типы.ИнструкцияПрепроцессораОбласть - Или Тип = Типы.ИнструкцияПрепроцессораКонецОбласти - Или Тип = Типы.ИнструкцияПрепроцессораЕсли - Или Тип = Типы.ИнструкцияПрепроцессораИначеЕсли - Или Тип = Типы.ИнструкцияПрепроцессораИначе - Или Тип = Типы.ИнструкцияПрепроцессораКонецЕсли - Или Тип = Типы.ИнструкцияПрепроцессораВставка - Или Тип = Типы.ИнструкцияПрепроцессораКонецВставки - Или Тип = Типы.ИнструкцияПрепроцессораУдаление - Или Тип = Типы.ИнструкцияПрепроцессораКонецУдаления Тогда - ПосетитьИнструкциюПрепроцессора(Оператор); - КонецЕсли; -КонецПроцедуры // ПосетитьОператорПоТипу() - -Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПрисваивания Цикл - Подписка.ПосетитьОператорПрисваивания(ОператорПрисваивания); - КонецЦикла; - ДобавитьНаСтек(ОператорПрисваивания); - ПосетитьВыражениеИдентификатор(ОператорПрисваивания.ЛевыйОперанд); - ПосетитьВыражение(ОператорПрисваивания.ПравыйОперанд); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПрисваивания Цикл - Подписка.ПокинутьОператорПрисваивания(ОператорПрисваивания); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорПрисваивания() - -Процедура ПосетитьОператорВозврат(ОператорВозврат) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВозврат Цикл - Подписка.ПосетитьОператорВозврат(ОператорВозврат); - КонецЦикла; - ДобавитьНаСтек(ОператорВозврат); - Если ОператорВозврат.Выражение <> Неопределено Тогда - ПосетитьВыражение(ОператорВозврат.Выражение); - КонецЕсли; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВозврат Цикл - Подписка.ПокинутьОператорВозврат(ОператорВозврат); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорВозврат() - -Процедура ПосетитьОператорПрервать(ОператорПрервать) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПрервать Цикл - Подписка.ПосетитьОператорПрервать(ОператорПрервать); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПрервать Цикл - Подписка.ПокинутьОператорПрервать(ОператорПрервать); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорПрервать() - -Процедура ПосетитьОператорПродолжить(ОператорПродолжить) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПродолжить Цикл - Подписка.ПосетитьОператорПродолжить(ОператорПродолжить); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПродолжить Цикл - Подписка.ПокинутьОператорПродолжить(ОператорПродолжить); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорПродолжить() - -Процедура ПосетитьОператорВызватьИсключение(ОператорВызватьИсключение) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВызватьИсключение Цикл - Подписка.ПосетитьОператорВызватьИсключение(ОператорВызватьИсключение); - КонецЦикла; - ДобавитьНаСтек(ОператорВызватьИсключение); - Если ОператорВызватьИсключение.Выражение <> Неопределено Тогда - ПосетитьВыражение(ОператорВызватьИсключение.Выражение); - КонецЕсли; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВызватьИсключение Цикл - Подписка.ПокинутьОператорВызватьИсключение(ОператорВызватьИсключение); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорВызватьИсключение() - -Процедура ПосетитьОператорВыполнить(ОператорВыполнить) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВыполнить Цикл - Подписка.ПосетитьОператорВыполнить(ОператорВыполнить); - КонецЦикла; - ДобавитьНаСтек(ОператорВыполнить); - ПосетитьВыражение(ОператорВыполнить.Выражение); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВыполнить Цикл - Подписка.ПокинутьОператорВыполнить(ОператорВыполнить); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорВыполнить() - -Процедура ПосетитьОператорВызоваПроцедуры(ОператорВызоваПроцедуры) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВызоваПроцедуры Цикл - Подписка.ПосетитьОператорВызоваПроцедуры(ОператорВызоваПроцедуры); - КонецЦикла; - ДобавитьНаСтек(ОператорВызоваПроцедуры); - ПосетитьВыражениеИдентификатор(ОператорВызоваПроцедуры.Идентификатор); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВызоваПроцедуры Цикл - Подписка.ПокинутьОператорВызоваПроцедуры(ОператорВызоваПроцедуры); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорВызоваПроцедуры() - -Процедура ПосетитьОператорЕсли(ОператорЕсли) - Перем ОператорИначеЕсли, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорЕсли Цикл - Подписка.ПосетитьОператорЕсли(ОператорЕсли); - КонецЦикла; - ДобавитьНаСтек(ОператорЕсли); - ПосетитьВыражение(ОператорЕсли.Выражение); - ПосетитьОператоры(ОператорЕсли.Тогда); - Если ОператорЕсли.ИначеЕсли <> Неопределено Тогда - Для Каждого ОператорИначеЕсли Из ОператорЕсли.ИначеЕсли Цикл - ПосетитьОператорИначеЕсли(ОператорИначеЕсли); - КонецЦикла; - КонецЕсли; - Если ОператорЕсли.Иначе <> Неопределено Тогда - ПосетитьОператорИначе(ОператорЕсли.Иначе); - КонецЕсли; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорЕсли Цикл - Подписка.ПокинутьОператорЕсли(ОператорЕсли); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорЕсли() - -Процедура ПосетитьОператорИначеЕсли(ОператорИначеЕсли) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорИначеЕсли Цикл - Подписка.ПосетитьОператорИначеЕсли(ОператорИначеЕсли); - КонецЦикла; - ДобавитьНаСтек(ОператорИначеЕсли); - ПосетитьВыражение(ОператорИначеЕсли.Выражение); - ПосетитьОператоры(ОператорИначеЕсли.Тогда); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорИначеЕсли Цикл - Подписка.ПокинутьОператорИначеЕсли(ОператорИначеЕсли); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорИначеЕсли() - -Процедура ПосетитьОператорИначе(ОператорИначе) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорИначе Цикл - Подписка.ПосетитьОператорИначе(ОператорИначе); - КонецЦикла; - ДобавитьНаСтек(ОператорИначе); - ПосетитьОператоры(ОператорИначе.Операторы); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорИначе Цикл - Подписка.ПокинутьОператорИначе(ОператорИначе); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорИначе() - -Процедура ПосетитьОператорПока(ОператорПока) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПока Цикл - Подписка.ПосетитьОператорПока(ОператорПока); - КонецЦикла; - ДобавитьНаСтек(ОператорПока); - ПосетитьВыражение(ОператорПока.Выражение); - ПосетитьОператоры(ОператорПока.Операторы); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПока Цикл - Подписка.ПокинутьОператорПока(ОператорПока); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорПока() - -Процедура ПосетитьОператорДля(ОператорДля) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорДля Цикл - Подписка.ПосетитьОператорДля(ОператорДля); - КонецЦикла; - ДобавитьНаСтек(ОператорДля); - ПосетитьВыражениеИдентификатор(ОператорДля.Идентификатор); - ПосетитьВыражение(ОператорДля.Старт); - ПосетитьВыражение(ОператорДля.Финиш); - ПосетитьОператоры(ОператорДля.Операторы); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорДля Цикл - Подписка.ПокинутьОператорДля(ОператорДля); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорДля() - -Процедура ПосетитьОператорДляКаждого(ОператорДляКаждого) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорДляКаждого Цикл - Подписка.ПосетитьОператорДляКаждого(ОператорДляКаждого); - КонецЦикла; - ДобавитьНаСтек(ОператорДляКаждого); - ПосетитьВыражениеИдентификатор(ОператорДляКаждого.Идентификатор); - ПосетитьВыражение(ОператорДляКаждого.Коллекция); - ПосетитьОператоры(ОператорДляКаждого.Операторы); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорДляКаждого Цикл - Подписка.ПокинутьОператорДляКаждого(ОператорДляКаждого); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорДляКаждого() - -Процедура ПосетитьОператорПопытка(ОператорПопытка) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПопытка Цикл - Подписка.ПосетитьОператорПопытка(ОператорПопытка); - КонецЦикла; - ДобавитьНаСтек(ОператорПопытка); - ПосетитьОператоры(ОператорПопытка.Попытка); - ПосетитьОператорИсключение(ОператорПопытка.Исключение); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПопытка Цикл - Подписка.ПокинутьОператорПопытка(ОператорПопытка); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорПопытка() - -Процедура ПосетитьОператорИсключение(ОператорИсключение) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорИсключение Цикл - Подписка.ПосетитьОператорИсключение(ОператорИсключение); - КонецЦикла; - ДобавитьНаСтек(ОператорИсключение); - ПосетитьОператоры(ОператорИсключение.Операторы); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорИсключение Цикл - Подписка.ПокинутьОператорИсключение(ОператорИсключение); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорИсключение() - -Процедура ПосетитьОператорПерейти(ОператорПерейти) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПерейти Цикл - Подписка.ПосетитьОператорПерейти(ОператорПерейти); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПерейти Цикл - Подписка.ПокинутьОператорПерейти(ОператорПерейти); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорПерейти() - -Процедура ПосетитьОператорМетка(ОператорМетка) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорМетка Цикл - Подписка.ПосетитьОператорМетка(ОператорМетка); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорМетка Цикл - Подписка.ПокинутьОператорМетка(ОператорМетка); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорМетка() - -Процедура ПосетитьОператорДобавитьОбработчик(ОператорДобавитьОбработчик) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорДобавитьОбработчик Цикл - Подписка.ПосетитьОператорДобавитьОбработчик(ОператорДобавитьОбработчик); - КонецЦикла; - ДобавитьНаСтек(ОператорДобавитьОбработчик); - ПосетитьВыражениеИдентификатор(ОператорДобавитьОбработчик.Событие); - ПосетитьВыражениеИдентификатор(ОператорДобавитьОбработчик.ОбработчикСобытия); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорДобавитьОбработчик Цикл - Подписка.ПокинутьОператорДобавитьОбработчик(ОператорДобавитьОбработчик); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорДобавитьОбработчик() - -Процедура ПосетитьОператорУдалитьОбработчик(ОператорУдалитьОбработчик) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорУдалитьОбработчик Цикл - Подписка.ПосетитьОператорУдалитьОбработчик(ОператорУдалитьОбработчик); - КонецЦикла; - ДобавитьНаСтек(ОператорУдалитьОбработчик); - ПосетитьВыражениеИдентификатор(ОператорУдалитьОбработчик.Событие); - ПосетитьВыражениеИдентификатор(ОператорУдалитьОбработчик.ОбработчикСобытия); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорУдалитьОбработчик Цикл - Подписка.ПокинутьОператорУдалитьОбработчик(ОператорУдалитьОбработчик); - КонецЦикла; -КонецПроцедуры // ПосетитьОператорУдалитьОбработчик() - -#КонецОбласти // ПосещениеОператоров - -#Область ПосещениеВыраженийПрепроцессора - -Процедура ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессора) - Перем Тип, Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессора Цикл - Подписка.ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессора); - КонецЦикла; - Тип = ВыражениеПрепроцессора.Тип; - Если Тип = Типы.ВыражениеПрепроцессораСимвол Тогда - ПосетитьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессора); - ИначеЕсли Тип = Типы.ВыражениеПрепроцессораБинарное Тогда - ПосетитьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессора); - ИначеЕсли Тип = Типы.ВыражениеПрепроцессораНе Тогда - ПосетитьВыражениеПрепроцессораНе(ВыражениеПрепроцессора); - ИначеЕсли Тип = Типы.ВыражениеПрепроцессораСкобочное Тогда - ПосетитьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессора); - КонецЕсли; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессора Цикл - Подписка.ПокинутьВыражениеПрепроцессора(ВыражениеПрепроцессора); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеПрепроцессора() - -Процедура ПосетитьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессораСимвол) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораСимвол Цикл - Подписка.ПосетитьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессораСимвол); - КонецЦикла; - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораСимвол Цикл - Подписка.ПокинутьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессораСимвол); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеПрепроцессораСимвол() - -Процедура ПосетитьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессораБинарное) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораБинарное Цикл - Подписка.ПосетитьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессораБинарное); - КонецЦикла; - ДобавитьНаСтек(ВыражениеПрепроцессораБинарное); - ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораБинарное.ЛевыйОперанд); - ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораБинарное.ПравыйОперанд); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораБинарное Цикл - Подписка.ПокинутьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессораБинарное); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеПрепроцессораБинарное() - -Процедура ПосетитьВыражениеПрепроцессораНе(ВыражениеПрепроцессораНе) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораНе Цикл - Подписка.ПосетитьВыражениеПрепроцессораНе(ВыражениеПрепроцессораНе); - КонецЦикла; - ДобавитьНаСтек(ВыражениеПрепроцессораНе); - ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораНе.Выражение); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораНе Цикл - Подписка.ПокинутьВыражениеПрепроцессораНе(ВыражениеПрепроцессораНе); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеПрепроцессораНе() - -Процедура ПосетитьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессораСкобочное) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораСкобочное Цикл - Подписка.ПосетитьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессораСкобочное); - КонецЦикла; - ДобавитьНаСтек(ВыражениеПрепроцессораСкобочное); - ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораСкобочное.Выражение); - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораСкобочное Цикл - Подписка.ПокинутьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессораСкобочное); - КонецЦикла; -КонецПроцедуры // ПосетитьВыражениеПрепроцессораСкобочное() - -Процедура ПосетитьИнструкциюПрепроцессора(ИнструкцияПрепроцессора) - Перем Подписка; - Для Каждого Подписка Из Посетитель_Подписки.ПосетитьИнструкциюПрепроцессора Цикл - Подписка.ПосетитьИнструкциюПрепроцессора(ИнструкцияПрепроцессора); - КонецЦикла; - ДобавитьНаСтек(ИнструкцияПрепроцессора); - Если ИнструкцияПрепроцессора.Владелец().Колонки.Найти("Выражение") <> Неопределено Тогда - ПосетитьВыражениеПрепроцессора(ИнструкцияПрепроцессора.Выражение); - КонецЕсли; - УдалитьСоСтека(); - Для Каждого Подписка Из Посетитель_Подписки.ПокинутьИнструкциюПрепроцессора Цикл - Подписка.ПокинутьИнструкциюПрепроцессора(ИнструкцияПрепроцессора); - КонецЦикла; -КонецПроцедуры // ПосетитьИнструкциюПрепроцессора() - -#КонецОбласти // ПосещениеВыраженийПрепроцессора - -#КонецОбласти // Посетитель - -Функция Пуск(Исходник, Знач Плагины, Параметры = Неопределено, Окружение = Неопределено) Экспорт - Перем Результаты, Плагин; - Подключить(Плагины); - Посетить(Разобрать(Исходник, Окружение), Параметры); - Результаты = Новый Массив; - Для Каждого Плагин Из Посетитель_Плагины Цикл - Результаты.Добавить(Плагин.Закрыть()); - КонецЦикла; - Очистить(); - Возврат Результаты; -КонецФункции // Пуск() - -Процедура Очистить() Экспорт - Парсер_Токены.Очистить(); - Для Каждого Элемент Из Парсер_Узлы Цикл - Элемент.Значение.ЗаполнитьЗначения(Неопределено); - Элемент.Значение.Очистить(); - КонецЦикла; -КонецПроцедуры // Очистить() - -Инициализировать(); + +// MIT License + +// Copyright (c) 2020 Tsukanov Alexander + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#Область Константы + +Перем КлючевыеСлова; // перечисление +Перем Токены; // перечисление +Перем Типы; // перечисление +Перем Директивы; // перечисление +Перем Аннотации; // перечисление +Перем ИнструкцииПрепроцессора; // перечисление +Перем СимволыПрепроцессора; // перечисление +Перем Ошибки; // массив (строка) +Перем ЛитералКромеСтроки; // массив (один из Токены) +Перем ОперацииСравнения; // массив (один из Токены) +Перем ОперацииАддитивные; // массив (один из Токены) +Перем ОперацииМультипликативные; // массив (один из Токены) +Перем ТокеныНачалаВыражения; // массив (один из Токены) +Перем ПустойМассив; // массив +Перем КартаТокенов; // соответствие[строка] (строка) +Перем КартаБуквЦифр; // соответствие[строка] (строка) +Перем Буква, Цифра; // строка +Перем Символы_ПС; // строка + +#КонецОбласти // Константы + +#Область Параметры + +Перем СтрогийРежим Экспорт; + +#КонецОбласти // Параметры + +#Область СостояниеПарсера + +Перем Парсер_Исходник; // строка +Перем Парсер_ДлинаИсходника; // число +Перем Парсер_НомерТекущейСтроки; // число +Перем Парсер_ТекущаяПозиция; // число +Перем Парсер_ПозицияНачалаТокена; // число +Перем Парсер_Символ; // строка +Перем Парсер_Токен; // строка (один из Токены) +Перем Парсер_Литерал; // строка +Перем Парсер_Значение; // число, строка, дата, булево, неопределено, null +Перем Парсер_Окружение; // структура (Окружение) +Перем Парсер_Переменные; // структура как соответствие[строка] (ЭлементОкружения) +Перем Парсер_Методы; // структура как соответствие[строка] (ЭлементОкружения) +Перем Парсер_Неизвестные; // структура как соответствие[строка] (ЭлементОкружения) +Перем Парсер_ТочкиВызова; // соответствие[ЭлементОкружения] (число) +Перем Парсер_ЭтоФункция; // булево +Перем Парсер_ЭтоАсинх; // булево +Перем Парсер_ПеременныеРазрешены; // булево +Перем Парсер_СписокДиректив; // массив (ОбъявлениеДирективы) +Перем Парсер_СписокАннотаций; // массив (ОбъявлениеАннотации) +Перем Парсер_Интерфейс; // массив (ЭлементОкружения) +Перем Парсер_Ошибки; // таблица +Перем Парсер_Замены; // таблица +Перем Парсер_Токены; // таблица +Перем Парсер_ПозицияТекущейСтроки; // число +Перем Парсер_ИндексТокена; // число +Перем Парсер_ДанныеТекущегоТокена; // один из ТаблицаТокенов +Перем Парсер_ДанныеПредыдущегоТокена; // один из ТаблицаТокенов +Перем Парсер_Узлы; // структура как соответствие[строка] (таблица значений) + +#КонецОбласти // СостояниеПарсера + +#Область СостояниеПосетителя + +Перем Посетитель_Плагины; // массив (Обработка) +Перем Посетитель_Подписки; // структура как соответствие[строка] (массив) +Перем Посетитель_Стек; // структура +Перем Посетитель_Счетчики; // структура как соответствие[строка] (число) + +#КонецОбласти // СостояниеПосетителя + +#Область Инициализация + +Процедура Инициализировать() + Перем Буквы, Индекс, Символ; + + ИнициализироватьПеречисления(); + ИнициализироватьУзлы(); + + ЛитералКромеСтроки = Новый Массив; + ЛитералКромеСтроки.Добавить(Токены.Число); + ЛитералКромеСтроки.Добавить(Токены.ДатаВремя); + ЛитералКромеСтроки.Добавить(Токены.Истина); + ЛитералКромеСтроки.Добавить(Токены.Ложь); + ЛитералКромеСтроки.Добавить(Токены.Неопределено); + ЛитералКромеСтроки.Добавить(Токены.Null); + + ОперацииСравнения = Новый Массив; + ОперацииСравнения.Добавить(Токены.ЗнакРавно); + ОперацииСравнения.Добавить(Токены.ЗнакНеРавно); + ОперацииСравнения.Добавить(Токены.ЗнакМеньше); + ОперацииСравнения.Добавить(Токены.ЗнакБольше); + ОперацииСравнения.Добавить(Токены.ЗнакМеньшеИлиРавно); + ОперацииСравнения.Добавить(Токены.ЗнакБольшеИлиРавно); + + ОперацииАддитивные = Новый Массив; + ОперацииАддитивные.Добавить(Токены.ЗнакСложения); + ОперацииАддитивные.Добавить(Токены.ЗнакВычитания); + + ОперацииМультипликативные = Новый Массив; + ОперацииМультипликативные.Добавить(Токены.ЗнакУмножения); + ОперацииМультипликативные.Добавить(Токены.ЗнакДеления); + ОперацииМультипликативные.Добавить(Токены.ЗнакОстатка); + + ТокеныНачалаВыражения = Новый Массив; + ТокеныНачалаВыражения.Добавить(Токены.ЗнакСложения); + ТокеныНачалаВыражения.Добавить(Токены.ЗнакВычитания); + ТокеныНачалаВыражения.Добавить(Токены.Не); + ТокеныНачалаВыражения.Добавить(Токены.Идентификатор); + ТокеныНачалаВыражения.Добавить(Токены.ЛеваяКруглаяСкобка); + ТокеныНачалаВыражения.Добавить(Токены.Число); + ТокеныНачалаВыражения.Добавить(Токены.Строка); + ТокеныНачалаВыражения.Добавить(Токены.НачалоСтроки); + ТокеныНачалаВыражения.Добавить(Токены.ДатаВремя); + ТокеныНачалаВыражения.Добавить(Токены.ЗнакВопроса); + ТокеныНачалаВыражения.Добавить(Токены.Новый); + ТокеныНачалаВыражения.Добавить(Токены.Истина); + ТокеныНачалаВыражения.Добавить(Токены.Ложь); + ТокеныНачалаВыражения.Добавить(Токены.Неопределено); + ТокеныНачалаВыражения.Добавить(Токены.Null); + + ПустойМассив = Новый Массив; + + Символы_ПС = Символы.ПС; + + Буква = "Буква"; + Цифра = "Цифра"; + + КартаТокенов = Новый Соответствие; + КартаБуквЦифр = Новый Соответствие; + + Буквы = ( + "abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" + + "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" + ); + Индекс = 1; + Символ = "_"; + Пока Символ <> "" Цикл + КартаТокенов[Символ] = Буква; + КартаБуквЦифр[Символ] = Буква; + Символ = Сред(Буквы, Индекс, 1); + Индекс = Индекс + 1; + КонецЦикла; + + Для Индекс = 0 По 9 Цикл + КартаТокенов[Строка(Индекс)] = Цифра; + КартаБуквЦифр[Строка(Индекс)] = Цифра; + КонецЦикла; + + КартаТокенов[""""] = Токены.НачалоСтроки; + КартаТокенов["|"] = Токены.ПродолжениеСтроки; + КартаТокенов["'"] = Токены.ДатаВремя; + КартаТокенов["="] = Токены.ЗнакРавно; + КартаТокенов["+"] = Токены.ЗнакСложения; + КартаТокенов["-"] = Токены.ЗнакВычитания; + КартаТокенов["*"] = Токены.ЗнакУмножения; + КартаТокенов["%"] = Токены.ЗнакОстатка; + КартаТокенов["("] = Токены.ЛеваяКруглаяСкобка; + КартаТокенов[")"] = Токены.ПраваяКруглаяСкобка; + КартаТокенов["["] = Токены.ЛеваяКвадратнаяСкобка; + КартаТокенов["]"] = Токены.ПраваяКвадратнаяСкобка; + КартаТокенов["?"] = Токены.ЗнакВопроса; + КартаТокенов[","] = Токены.Запятая; + КартаТокенов["."] = Токены.Точка; + КартаТокенов[":"] = Токены.Двоеточие; + КартаТокенов[";"] = Токены.ТочкаСЗапятой; + КартаТокенов[""] = Токены.КонецТекста; + + Ошибки = Новый Массив(21); + Ошибки[00] = Неопределено; // ошибки регистрируемые плагинами + Ошибки[01] = "Ожидалось"; + Ошибки[02] = "Ожидалась директива"; + Ошибки[03] = "Неизвестная директива"; + Ошибки[04] = "Ожидалась инструкция препроцессора"; + Ошибки[05] = "Неизвестная инструкция препроцессора"; + Ошибки[06] = "Не обнаружено объявление метода"; + Ошибки[07] = "Ожидался операнд"; + Ошибки[08] = "Ожидался конструктор"; + Ошибки[09] = "Ожидалось не более двух аргументов"; + Ошибки[10] = "Не обнаружено объявление идентификатора"; + Ошибки[11] = "Ожидалось выражение"; + Ошибки[12] = "Повторное объявление идентификатора"; + Ошибки[13] = "Повторное объявление метода"; + Ошибки[14] = "Ожидалась переменная"; + Ошибки[15] = "Имя события указано неправильно"; + Ошибки[16] = "Имя метода указано неправильно"; + Ошибки[17] = "Ожидался символ препроцессора"; + Ошибки[18] = "Ошибка в литерале даты"; + Ошибки[19] = "Не удалось выполнить замену"; + Ошибки[20] = "Ожидалось имя или путь"; + + СтрогийРежим = Ложь; + + Парсер_Ошибки = Новый ТаблицаЗначений; + // основные поля + Парсер_Ошибки.Колонки.Добавить("Источник", Новый ОписаниеТипов("Строка")); + Парсер_Ошибки.Колонки.Добавить("Код", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("Текст", Новый ОписаниеТипов("Строка")); + Парсер_Ошибки.Колонки.Добавить("ПозицияНачала", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("НомерСтрокиНачала", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("НомерКолонкиНачала", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("ПозицияКонца", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("НомерСтрокиКонца", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("НомерКолонкиКонца", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("ЕстьЗамена", Новый ОписаниеТипов("Булево")); + // дополнительные поля + Парсер_Ошибки.Колонки.Добавить("МинутНаИсправление", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("Серьезность", Новый ОписаниеТипов("Строка")); + Парсер_Ошибки.Колонки.Добавить("Приоритет", Новый ОписаниеТипов("Число")); + Парсер_Ошибки.Колонки.Добавить("Правило", Новый ОписаниеТипов("Строка")); + Парсер_Ошибки.Колонки.Добавить("Тип", Новый ОписаниеТипов("Строка")); + + Парсер_Токены = Новый ТаблицаЗначений; + Парсер_Токены.Колонки.Добавить("Индекс", Новый ОписаниеТипов("Число")); + Парсер_Токены.Колонки.Добавить("Токен", Новый ОписаниеТипов("Строка")); + Парсер_Токены.Колонки.Добавить("НомерСтроки", Новый ОписаниеТипов("Число")); + Парсер_Токены.Колонки.Добавить("НомерКолонки", Новый ОписаниеТипов("Число")); + Парсер_Токены.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число")); + Парсер_Токены.Колонки.Добавить("Длина", Новый ОписаниеТипов("Число")); + + Парсер_Замены = Новый ТаблицаЗначений; + Парсер_Замены.Колонки.Добавить("Источник", Новый ОписаниеТипов("Строка")); + Парсер_Замены.Колонки.Добавить("Текст", Новый ОписаниеТипов("Строка")); + Парсер_Замены.Колонки.Добавить("Позиция", Новый ОписаниеТипов("Число")); + Парсер_Замены.Колонки.Добавить("Длина", Новый ОписаниеТипов("Число")); + +КонецПроцедуры // Инициализировать() + +Процедура ИнициализироватьПеречисления() + КлючевыеСлова = КлючевыеСлова(); + Токены = Токены(КлючевыеСлова); + Типы = Типы(); + Директивы = Директивы(); + Аннотации = Аннотации(); + ИнструкцииПрепроцессора = ИнструкцииПрепроцессора(); + СимволыПрепроцессора = СимволыПрепроцессора(); +КонецПроцедуры // ИнициализироватьПеречисления() + +Процедура ИнициализироватьУзлы() + + Парсер_Узлы = Новый Структура; + + Парсер_Узлы.Вставить("Модуль", Новый ТаблицаЗначений); + // Корень AST. Узел хранит информацию о модуле в целом. + Поля = Парсер_Узлы.Модуль.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Объявления"); // массив (один из #Объявления) + Поля.Добавить("Переменные"); // массив (ОбъявлениеПеременнойМодуля, ОбъявлениеАвтоПеременной) + Поля.Добавить("Операторы"); // массив (один из #Операторы) + Поля.Добавить("Интерфейс"); // массив (ЭлементОкружения) + + Парсер_Узлы.Вставить("ЭлементОкружения", Новый ТаблицаЗначений); + // Узел хранит информацию об объекте области видимости. + // Поле Объявление хранит объявление данного объекта (неопределено = объявление не обнаружено). + Поля = Парсер_Узлы.ЭлементОкружения.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Объявление"); // неопределено, структура (один из #Объявления) + + ИнициализироватьОбъявления(); + ИнициализироватьВыражения(); + ИнициализироватьОператоры(); + ИнициализироватьИнструкцииПрепроцессора(); + ИнициализироватьВыраженияПрепроцессора(); + +КонецПроцедуры // ИнициализироватьУзлы() + +Процедура ИнициализироватьОбъявления() + + Парсер_Узлы.Вставить("ОбъявлениеДирективы", Новый ТаблицаЗначений); + // Хранит информацию об объявлении директивы. + // Пример: + //
+	// &НаКлиенте
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеДирективы.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Директива"); // строка (один из Директивы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеАннотации", Новый ТаблицаЗначений); + // Хранит информацию об объявлении аннотации. + // Пример: + //
+	// &Перед("ЗаполнитьТовары")
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеАннотации.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Аннотация"); // строка (один из Аннотации) + Поля.Добавить("ИмяМетода"); // строка + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеСпискаПеременныхМодуля", Новый ТаблицаЗначений); + // Хранит информацию об инструкции объявления переменных уровня модуля. + // Пример: + //
+	// &НаКлиенте            // поле "Директивы"
+	// Перем П1 Экспорт, П2; // поле "Объявления"
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеСпискаПеременныхМодуля.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) + Поля.Добавить("Объявления"); // массив (ОбъявлениеПеременнойМодуля) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеПеременнойМодуля", Новый ТаблицаЗначений); + // Хранит информацию об объявлении переменной уровня модуля. + // Пример: + // Объявления переменных заключены в скобки {...} + //
+	// &НаКлиенте
+	// Перем {П1 Экспорт}, {П2};
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеПеременнойМодуля.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) + Поля.Добавить("Экспорт"); // булево + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеСпискаЛокальныхПеременных", Новый ТаблицаЗначений); + // Хранит информацию об инструкции объявления переменных уровня метода. + // Пример: + //
+	// Перем П1, П2; // поле "Объявления"
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеСпискаЛокальныхПеременных.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Объявления"); // массив (ОбъявлениеЛокальнойПеременной) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеЛокальнойПеременной", Новый ТаблицаЗначений); + // Хранит информацию об объявлении локальной переменной. + // Пример: + // Объявления переменных заключены в скобки {...} + //
+	// Перем {П1}, {П2};
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеЛокальнойПеременной.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеАвтоПеременной", Новый ТаблицаЗначений); + // Хранит информацию об объявлении авто-переменной. + // Пример: + // Объявления переменных заключены в скобки {...} + //
+	// {Макс} = 0;
+	// Для {Индекс} = 0 По Массив.ВГраница() Цикл
+	//	{Структура} = Массив[Индекс];
+	// 	Для Каждого {Элемент} Из Структура Цикл
+	//		Если Макс < Элемент.Значение Тогда
+	// 			Макс = Элемент.Значение;
+	// 		КонецЕсли;
+	// 	КонецЦикла;
+	// КонецЦикла
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеАвтоПеременной.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеПараметра", Новый ТаблицаЗначений); + // Хранит информацию об объявлении параметра. + // Пример: + // Объявления параметров заключены в скобки {...} + //
+	// Процедура Тест({П1}, {Знач П2 = Неопределено})
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеПараметра.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("ПоЗначению"); // булево + Поля.Добавить("Значение"); // неопределено, структура (ВыражениеУнарное, ВыражениеЛитерал) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеМетода", Новый ТаблицаЗначений); + // Хранит информацию об объявлении метода. + // Сигнатура метода хранится в поле Сигнатура. + // Пример: + //
+	// &НаКлиенте
+	// Функция Тест() Экспорт
+	//     Перем П1, П2; // поле "Объявления" хранит объявления списков переменных.
+	//                   // каждый элемент объявления (например П2) добавляется в поле "Переменные".
+	//     П1 = 2;       // операторы собираются в поле Операторы
+	//     П3 = П1 + 2;  // Авто-переменные (П2) добавляются в поле "Переменные".
+	// КонецФункции
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеМетода.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Сигнатура"); // структура (ОбъявлениеСигнатурыПроцедуры, ОбъявлениеСигнатурыФункции) + Поля.Добавить("Переменные"); // массив (ОбъявлениеЛокальнойПеременной, ОбъявлениеАвтоПеременной) + Поля.Добавить("Объявления"); // массив (ОбъявлениеСпискаЛокальныхПеременных) + Поля.Добавить("Операторы"); // массив (один из #Операторы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеСигнатурыПроцедуры", Новый ТаблицаЗначений); + // Хранит информацию о сигнатуре объявления процедуры. + // Пример: + //
+	// &НаКлиенте
+	// Процедура Тест(П1, П2) Экспорт
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеСигнатурыПроцедуры.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) + Поля.Добавить("Аннотации"); // массив (ОбъявлениеАннотации) + Поля.Добавить("Параметры"); // массив (ОбъявлениеПараметра) + Поля.Добавить("Экспорт"); // булево + Поля.Добавить("Асинх"); // булево + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеСигнатурыФункции", Новый ТаблицаЗначений); + // Хранит информацию о сигнатуре объявления функции. + // Пример: + //
+	// &НаКлиенте
+	// Функция Тест(П1, П2) Экспорт
+	// 
+ Поля = Парсер_Узлы.ОбъявлениеСигнатурыФункции.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Директивы"); // массив (ОбъявлениеДирективы) + Поля.Добавить("Аннотации"); // массив (ОбъявлениеАннотации) + Поля.Добавить("Параметры"); // массив (ОбъявлениеПараметра) + Поля.Добавить("Экспорт"); // булево + Поля.Добавить("Асинх"); // булево + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОбъявлениеГлобальногоОбъекта", Новый ТаблицаЗначений); + // Хранит информацию о глобальном объекте. + Поля = Парсер_Узлы.ОбъявлениеГлобальногоОбъекта.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Доступность"); // структура (Доступность) + + Парсер_Узлы.Вставить("ОбъявлениеГлобальногоМетода", Новый ТаблицаЗначений); + // Хранит информацию о глобальном методе. + Поля = Парсер_Узлы.ОбъявлениеГлобальногоМетода.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Функция"); // булево + Поля.Добавить("Параметры"); // структура + Поля.Добавить("Доступность"); // структура (Доступность) + +КонецПроцедуры + +Процедура ИнициализироватьВыражения() + + Парсер_Узлы.Вставить("ВыражениеЛитерал", Новый ТаблицаЗначений); + // Хранит информацию о литерале примитивного типа. + Поля = Парсер_Узлы.ВыражениеЛитерал.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Вид"); // строка (один из Токены) + Поля.Добавить("Значение"); // неопределено, строка, число, булево, дата, null + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеПоле", Новый ТаблицаЗначений); + // Хранит информацию об обращении к полю объекта через точку. + // В поле Имя содержится имя поля. + // В поле Аргументы содержатся аргументы вызова (если это вызов). + // Пример: + //
+	// // обращения через точку заключены в скобки {...}
+	// Значение = Объект{.Поле}
+	// Значение = Объект{.Добавить(П1, П2)}
+	// 
+ Поля = Парсер_Узлы.ВыражениеПоле.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Аргументы"); // неопределено, массив (неопределено, один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеИндекс", Новый ТаблицаЗначений); + // Хранит информацию об обращении к элементу объекта по индексу. + // Пример: + //
+	// // обращение по индексу заключено в скобки {...}
+	// Значение = Объект{[Ключ]}
+	// 
+ Поля = Парсер_Узлы.ВыражениеИндекс.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеИдентификатор", Новый ТаблицаЗначений); + // Хранит информацию об обращении к идентификатору. + // В поле Голова содержится объект области видимости соответствующий идентификатору. + // В поле Хвост содержится последовательность обращений через точку и по индексу. + // В поле Аргументы содержатся аргументы вызова (если это вызов). + // Пример: + //
+	// // идентификатор заключен в скобки {...}
+	// // поле "Голова" будет содержать объект переменной "Запрос";
+	// // поле "Хвост" будет содержать три обращения;
+	// // поле "Аргументы" будет равно Неопределено, т.к. обращение к "Запрос" не является вызовом.
+	// Возврат {Запрос.Выполнить().Выгрузить()[0]};
+	// 
+ Поля = Парсер_Узлы.ВыражениеИдентификатор.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Голова"); // структура (ЭлементОкружения) + Поля.Добавить("Хвост"); // массив (ВыражениеПоле, ВыражениеИндекс) + Поля.Добавить("Аргументы"); // неопределено, массив (неопределено, один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеУнарное", Новый ТаблицаЗначений); + // Хранит унарное выражение. + // Пример: + //
+	// // унарные выражения заключены в скобки {...}
+	// // поле "Операция.Токен" равно либо Токены.ЗнакСложения, либо Токены.ЗнакВычитания
+	// // поле "Операнд" хранит операнд-выражение
+	// Значение = {-Сумма} * 2;
+	// Значение = {+Сумма};
+	// Значение = {-(Сумма1 + Сумма2)} / 2;
+	// 
+ Поля = Парсер_Узлы.ВыражениеУнарное.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Операция"); // один из ТаблицаТокенов + Поля.Добавить("Операнд"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеБинарное", Новый ТаблицаЗначений); + // Хранит бинарное выражение. + // Пример: + //
+	// // бинарные выражения заключены в скобки {...}
+	// // поле "Операция.Токен" равно одному из допустимых операторов:
+	// // - логических (кроме "Не")
+	// // - реляционных
+	// // - арифметических
+	// // поля "ЛевыйОперанд" и "ПравыйОперанд" содержат операнды-выражения
+	// Если {Не Отмена И Продолжить} Тогда
+	//     Значение = {Сумма1 + {Сумма2 * Коэффициент}};
+	// КонецЕсли;
+	// 
+ Поля = Парсер_Узлы.ВыражениеБинарное.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("ЛевыйОперанд"); // структура (один из #Выражения) + Поля.Добавить("Операция"); // один из ТаблицаТокенов + Поля.Добавить("ПравыйОперанд"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеНовый", Новый ТаблицаЗначений); + // Хранит выражение "Новый". + // Для совместимости с OneScript поддерживается + // обращение к конструктору через точку (поле Хвост) + // Пример: + //
+	// // выражения "Новый" заключены в скобки {...}
+	// // в этом варианте поле "Имя" хранит имя типа "Массив",
+	// // а поле "Аргументы" хранит массив из одного выражения
+	// Параметры = {Новый Массив(1)};
+	// Параметры[0] = 10;
+	// // в этом варианте поле "Имя" равно Неопределено,
+	// // а поле "Аргументы" хранит массив из двух выражений
+	// Массив = {Новый (Тип("Массив"), Параметры)};
+	// 
+ // Инвариант: если (ВыражениеНовый.Имя = Неопределено) то (0 < ВыражениеНовый.Аргументы.Количество() <= 2) + Поля = Парсер_Узлы.ВыражениеНовый.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // неопределено, строка + Поля.Добавить("Аргументы"); // массив (один из #Выражения) + Поля.Добавить("Хвост"); // массив (ВыражениеПоле, ВыражениеИндекс) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеТернарное", Новый ТаблицаЗначений); + // Хранит тернарное выражение "?(,,)". + // Пример: + //
+	// Значение = ?(Ложь,   // поле "Выражение"
+	//     Неопределено,    // поле "Тогда"
+	//     Новый Массив     // поле "Иначе"
+	// ).Количество();      // поле "Хвост"
+	// 
+ Поля = Парсер_Узлы.ВыражениеТернарное.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Тогда"); // структура (один из #Выражения) + Поля.Добавить("Иначе"); // структура (один из #Выражения) + Поля.Добавить("Хвост"); // массив (ВыражениеПоле, ВыражениеИндекс) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеСкобочное", Новый ТаблицаЗначений); + // Хранит скобочное выражение. + // Пример: + //
+	// // скобочное выражение заключено в скобки {...}
+	// Сумма = {(Сумма1 + Сумма2)} * Количество;
+	// 
+ Поля = Парсер_Узлы.ВыражениеСкобочное.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеНе", Новый ТаблицаЗначений); + // Хранит выражение, к которому применено логическое отрицание "Не". + // Пример: + //
+	// // выражение-отрицание заключено в скобки {...}
+	// НеРавны = {Не Сумма1 = Сумма2};
+	// 
+ Поля = Парсер_Узлы.ВыражениеНе.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеСтроковое", Новый ТаблицаЗначений); + // Хранит строковое выражение. + // Поле "Элементы" хранит упорядоченный список частей строки. + // Пример: + //
+	// Строка1 = "Часть1" "Часть2"; // эта строка состоит из двух частей типа Типы.Строка
+	// Строка2 =                    // эта строка состоит из пяти частей типа:
+	// "Начало строки               // Типы.НачалоСтроки
+	// | продолжение строки         // Типы.ПродолжениеСтроки
+	// | еще продолжение строки     // Типы.ПродолжениеСтроки
+	// | окончание строки"          // Типы.ОкончаниеСтроки
+	// "еще часть";                 // Типы.Строка
+	// 
+ Поля = Парсер_Узлы.ВыражениеСтроковое.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Элементы"); // массив (ВыражениеЛитерал) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеЖдать", Новый ТаблицаЗначений); + // Хранит выражение "Ждать". + // Пример: + //
+	// Результат = {Ждать ПредупреждениеАсинх(Текст)};
+	// 
+ Поля = Парсер_Узлы.ВыражениеЖдать.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + +КонецПроцедуры + +Процедура ИнициализироватьОператоры() + + Парсер_Узлы.Вставить("ОператорПрисваивания", Новый ТаблицаЗначений); + // Хранит оператор присваивания. + Поля = Парсер_Узлы.ОператорПрисваивания.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("ЛевыйОперанд"); // структура (ВыражениеИдентификатор) + Поля.Добавить("ПравыйОперанд"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорВозврат", Новый ТаблицаЗначений); + // Хранит оператор "Возврат". + // Поле "Выражение" равно Неопределено если это возврат из процедуры. + Поля = Парсер_Узлы.ОператорВозврат.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // неопределено, структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорПрервать", Новый ТаблицаЗначений); + // Хранит оператор "Прервать". + Поля = Парсер_Узлы.ОператорПрервать.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорПродолжить", Новый ТаблицаЗначений); + // Хранит оператор "Продолжить". + Поля = Парсер_Узлы.ОператорПродолжить.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорВызватьИсключение", Новый ТаблицаЗначений); + // Хранит оператор "ВызватьИсключение". + // Поле "Выражение" равно Неопределено если это вариант оператора без выражения. + Поля = Парсер_Узлы.ОператорВызватьИсключение.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // неопределено, структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорВыполнить", Новый ТаблицаЗначений); + // Хранит оператор "Выполнить". + Поля = Парсер_Узлы.ОператорВыполнить.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорВызоваПроцедуры", Новый ТаблицаЗначений); + // Хранит вызов процедуры или функции как процедуры. + Поля = Парсер_Узлы.ОператорВызоваПроцедуры.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Идентификатор"); // структура (ВыражениеИдентификатор) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорЕсли", Новый ТаблицаЗначений); + // Хранит оператор "Если". + // Пример: + //
+	// Если Сумма > 0 Тогда // поле "Выражение" хранит условие (выражение)
+	//     // поле "Тогда" хранит операторы в этом блоке
+	// ИначеЕсли Сумма = 0 Тогда
+	//     // поле-массив "ИначеЕсли" хранит последовательность блоков ИначеЕсли
+	// Иначе
+	//     // поле "Иначе" хранит операторы в этом блоке
+	// КонецЕсли
+	// 
+ // Поля "ИначеЕсли" и "Иначе" равны Неопределено если + // соответствующие блоки отсутствуют в исходном коде. + Поля = Парсер_Узлы.ОператорЕсли.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Тогда"); // массив (один из #Операторы) + Поля.Добавить("ИначеЕсли"); // неопределено, массив (ОператорИначеЕсли) + Поля.Добавить("Иначе"); // неопределено, структура (ОператорИначе) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорИначе", Новый ТаблицаЗначений); + // Хранит блок "Иначе" + Поля = Парсер_Узлы.ОператорИначе.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Операторы"); // массив (один из #Операторы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорИначеЕсли", Новый ТаблицаЗначений); + // Хранит блок "ИначеЕсли" оператора "Если". + // Пример: + //
+	// ...
+	// ИначеЕсли Сумма < 0 Тогда // поле "Выражение" хранит условие (выражение)
+	//     // поле "Тогда" хранит операторы в этом блоке
+	// ...
+	// 
+ Поля = Парсер_Узлы.ОператорИначеЕсли.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Тогда"); // массив (один из #Операторы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорПока", Новый ТаблицаЗначений); + // Хранит оператор цикла "Пока". + // Пример: + //
+	// Пока Индекс > 0 Цикл // поле "Выражение" хранит условие (выражение)
+	//     // поле "Операторы" хранит операторы в этом блоке
+	// КонецЦикла
+	// 
+ Поля = Парсер_Узлы.ОператорПока.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #Выражения) + Поля.Добавить("Операторы"); // массив (один из #Операторы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорДля", Новый ТаблицаЗначений); + // Хранит оператор цикла "Для". + // Пример: + //
+	// Для Индекс = 0      // поля "Идентификатор" и "Старт" хранят переменную и выражение инициализации.
+	//   По Длина - 1 Цикл // поле "Финиш" хранит выражение границы
+	//     // поле "Операторы" хранит операторы в этом блоке
+	// КонецЦикла
+	// 
+ Поля = Парсер_Узлы.ОператорДля.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Идентификатор"); // структура (ВыражениеИдентификатор) + Поля.Добавить("Старт"); // структура (один из #Выражения) + Поля.Добавить("Финиш"); // структура (один из #Выражения) + Поля.Добавить("Операторы"); // массив (один из #Операторы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорДляКаждого", Новый ТаблицаЗначений); + // Хранит оператор цикла "Для Каждого". + // Пример: + //
+	// Для Каждого Элемент // поле "Идентификатор" хранит переменную.
+	//   Из Список Цикл    // поле "Коллекция" хранит выражение коллекции.
+	//     // поле "Операторы" хранит операторы в этом блоке
+	// КонецЦикла
+	// 
+ Поля = Парсер_Узлы.ОператорДляКаждого.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Идентификатор"); // структура (ВыражениеИдентификатор) + Поля.Добавить("Коллекция"); // структура (один из #Выражения) + Поля.Добавить("Операторы"); // массив (один из #Операторы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорПопытка", Новый ТаблицаЗначений); + // Хранит оператор "Попытка" + // Пример: + //
+	// Попытка
+	//     // поле "Попытка" хранит операторы в этом блоке.
+	// Исключение
+	//     // поле "Исключение" хранит операторы в этом блоке
+	// КонецПопытки
+	// 
+ Поля = Парсер_Узлы.ОператорПопытка.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Попытка"); // массив (один из #Операторы) + Поля.Добавить("Исключение"); // структура (ОператорИсключение) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорИсключение", Новый ТаблицаЗначений); + // Хранит блок "Исключение" + Поля = Парсер_Узлы.ОператорИсключение.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Операторы"); // массив (один из #Операторы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорПерейти", Новый ТаблицаЗначений); + // Хранит оператор "Перейти" + Поля = Парсер_Узлы.ОператорПерейти.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Метка"); // строка + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорМетка", Новый ТаблицаЗначений); + // Хранит оператор метки. + Поля = Парсер_Узлы.ОператорМетка.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Метка"); // строка + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорДобавитьОбработчик", Новый ТаблицаЗначений); + // Хранит оператор "ДобавитьОбработчик". + Поля = Парсер_Узлы.ОператорДобавитьОбработчик.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Событие"); // структура (ВыражениеИдентификатор) + Поля.Добавить("ОбработчикСобытия"); // структура (ВыражениеИдентификатор) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ОператорУдалитьОбработчик", Новый ТаблицаЗначений); + // Хранит оператор "УдалитьОбработчик". + Поля = Парсер_Узлы.ОператорУдалитьОбработчик.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Событие"); // структура (ВыражениеИдентификатор) + Поля.Добавить("ОбработчикСобытия"); // структура (ВыражениеИдентификатор) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + +КонецПроцедуры + +Процедура ИнициализироватьИнструкцииПрепроцессора() + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораЕсли", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #Если, + // Пример: + //
+	// ...
+	// #Если Сервер Тогда // поле "Выражение" хранит условие (выражение)
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораЕсли.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораИначеЕсли", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #ИначеЕсли + // Пример: + //
+	// ...
+	// #ИначеЕсли Клиент Тогда // поле "Выражение" хранит условие (выражение)
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораИначеЕсли.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораИначе", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #Иначе + Поля = Парсер_Узлы.ИнструкцияПрепроцессораИначе.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецЕсли", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #КонецЕсли + Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецЕсли.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораОбласть", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #Обрасть, + // Пример: + //
+	// ...
+	//#Область Интерфейс   // поле "Имя" хранит имя области
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораОбласть.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Имя"); // строка + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецОбласти", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #КонецОбласти, + // Пример: + //
+	// ...
+	//#КонецОбласти
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецОбласти.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораВставка", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #Вставка, + // Пример: + //
+	// ...
+	//#Вставка
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораВставка.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецВставки", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #КонецВставки, + // Пример: + //
+	// ...
+	//#КонецВставки
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецВставки.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораУдаление", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #Удаление, + // Пример: + //
+	// ...
+	//#Удаление
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораУдаление.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораКонецУдаления", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #КонецУдаления, + // Пример: + //
+	// ...
+	//#КонецУдаления
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораКонецУдаления.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ИнструкцияПрепроцессораИспользовать", Новый ТаблицаЗначений); + // Хранит информацию об инструкции препроцессора #Использовать, + // Пример: + //
+	// ...
+	//#Использовать osparser
+	// ...
+	// 
+ Поля = Парсер_Узлы.ИнструкцияПрепроцессораИспользовать.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Путь"); // строка + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + +КонецПроцедуры + +Процедура ИнициализироватьВыраженияПрепроцессора() + + Парсер_Узлы.Вставить("ВыражениеПрепроцессораБинарное", Новый ТаблицаЗначений); + // Хранит бинарное выражение препроцессора. + // Пример: + //
+	// // бинарные выражения заключены в скобки {...}
+	// // поле "Операция.Токен" равно либо Токены.Или либо Токены.И:
+	// // поля "ЛевыйОперанд" и "ПравыйОперанд" содержат операнды-выражения препроцессора
+	// #Если {Сервер Или ВнешнееСоединение} Тогда
+	// ...
+	// 
+ Поля = Парсер_Узлы.ВыражениеПрепроцессораБинарное.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("ЛевыйОперанд"); // структура (один из #ВыражениеПрепроцессора) + Поля.Добавить("Операция"); // один из ТаблицаТокенов + Поля.Добавить("ПравыйОперанд"); // структура (один из #ВыражениеПрепроцессора) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеПрепроцессораНе", Новый ТаблицаЗначений); + // Хранит выражение препроцессора, к которому применено логическое отрицание "Не". + // Пример: + //
+	// // выражение-отрицание заключено в скобки {...}
+	// #Если {Не ВебКлиент} Тогда
+	// ...
+	// 
+ Поля = Парсер_Узлы.ВыражениеПрепроцессораНе.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеПрепроцессораСимвол", Новый ТаблицаЗначений); + // Узел хранит информацию о символе препроцессора. + // Поле Существует = Истина если такой символ существует. + // Пример: + //
+	// // символ заключен в скобки {...}
+	// #Если {Сервер} Тогда
+	// 
+ Поля = Парсер_Узлы.ВыражениеПрепроцессораСимвол.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Символ"); // строка (один из PrepСимволs) + Поля.Добавить("Существует"); // булево + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + + Парсер_Узлы.Вставить("ВыражениеПрепроцессораСкобочное", Новый ТаблицаЗначений); + // Хранит скобочное выражение препроцессора. + // Пример: + //
+	// // скобочное выражение заключено в скобки {...}
+	// #Если {(Сервер Или ВнешнееСоединение)} Тогда
+	// 
+ Поля = Парсер_Узлы.ВыражениеПрепроцессораСкобочное.Колонки; + Поля.Добавить("Тип"); // строка (один из Типы) + Поля.Добавить("Выражение"); // структура (один из #ВыражениеПрепроцессора) + Поля.Добавить("Начало"); // один из ТаблицаТокенов + Поля.Добавить("Конец"); // один из ТаблицаТокенов + +КонецПроцедуры + +#КонецОбласти // Инициализация + +#Область Перечисления + +Функция КлючевыеСлова() Экспорт + Возврат Перечисление(Новый Структура, + "Если.If, Тогда.Then, ИначеЕсли.ElsIf, Иначе.Else, КонецЕсли.EndIf, + |Для.For, Каждого.Each, Из.In, По.To, Пока.While, Цикл.Do, КонецЦикла.EndDo, + |Процедура.Procedure, КонецПроцедуры.EndProcedure, Функция.Function, КонецФункции.EndFunction, + |Перем.Var, Знач.Val, Возврат.Return, Продолжить.Continue, Прервать.Break, + |И.And, Или.Or, Не.Not, ДобавитьОбработчик.AddHandler, УдалитьОбработчик.RemoveHandler, + |Попытка.Try, Исключение.Except, ВызватьИсключение.Raise, КонецПопытки.EndTry, + |Новый.New, Выполнить.Execute, Экспорт.Export, Перейти.Goto, + |Асинх.Async, Ждать.Await, + |Истина.True, Ложь.False, Неопределено.Undefined, Null" + ); +КонецФункции // КлючевыеСлова() + +Функция Токены(КлючевыеСлова = Неопределено) Экспорт + Перем Токены; + + Если КлючевыеСлова = Неопределено Тогда + КлючевыеСлова = КлючевыеСлова(); + КонецЕсли; + + Токены = Перечисление(Новый Структура(КлючевыеСлова), + + // Литералы + + "Идентификатор, Число, Строка, ДатаВремя, + // Элементы строк + |НачалоСтроки, ПродолжениеСтроки, ОкончаниеСтроки, + + // Операции + + // = <> < > + |ЗнакРавно, ЗнакНеРавно, ЗнакМеньше, ЗнакБольше, + // <= >= + |ЗнакМеньшеИлиРавно, ЗнакБольшеИлиРавно, + // + - * / % + |ЗнакСложения, ЗнакВычитания, ЗнакУмножения, ЗнакДеления, ЗнакОстатка, + // ( ) [ ] + |ЛеваяКруглаяСкобка, ПраваяКруглаяСкобка, ЛеваяКвадратнаяСкобка, ПраваяКвадратнаяСкобка, + // ? , . : ; + |ЗнакВопроса, Запятая, Точка, Двоеточие, ТочкаСЗапятой, + + // ИнструкцииПрепроцессора + |_Если, _ИначеЕсли, _Иначе, _КонецЕсли, _Область, _КонецОбласти, + |_Вставка, _КонецВставки, _Удаление, _КонецУдаления, _Использовать, + + // Другие + + // // ~ & & + |Комментарий, Метка, Аннотация, Директива, НачалоТекста, КонецТекста," + + ); + + Возврат Токены; +КонецФункции // Токены() + +Функция Типы() Экспорт + Возврат Перечисление(Новый Структура, + "Модуль, ЭлементОкружения, ОбъявлениеГлобальногоОбъекта, ОбъявлениеГлобальногоМетода, + |ОбъявлениеДирективы, ОбъявлениеАннотации, ОбъявлениеПеременнойМодуля, ОбъявлениеСпискаПеременныхМодуля, + |ОбъявлениеСпискаЛокальныхПеременных, ОбъявлениеЛокальнойПеременной, ОбъявлениеАвтоПеременной, + |ОбъявлениеПараметра, ОбъявлениеМетода, ОбъявлениеСигнатурыПроцедуры, ОбъявлениеСигнатурыФункции, + |ВыражениеЛитерал, ВыражениеПоле, ВыражениеИндекс, ВыражениеИдентификатор, + |ВыражениеУнарное, ВыражениеБинарное, ВыражениеНовый, ВыражениеТернарное, + |ВыражениеСкобочное, ВыражениеНе, ВыражениеСтроковое, + |ВыражениеЖдать, + |ОператорПрисваивания, ОператорВозврат, ОператорПрервать, ОператорПродолжить, + |ОператорВызватьИсключение, ОператорВыполнить, ОператорПока, ОператорДля, ОператорДляКаждого, + |ОператорПопытка, ОператорИсключение, ОператорПерейти, ОператорМетка, + |ОператорВызоваПроцедуры, ОператорЕсли, ОператорИначеЕсли, ОператорИначе, + |ОператорДобавитьОбработчик, ОператорУдалитьОбработчик, + |ИнструкцияПрепроцессораЕсли, ИнструкцияПрепроцессораИначеЕсли, ИнструкцияПрепроцессораИначе, + |ИнструкцияПрепроцессораКонецЕсли, ИнструкцияПрепроцессораОбласть, ИнструкцияПрепроцессораКонецОбласти, + |ИнструкцияПрепроцессораВставка, ИнструкцияПрепроцессораКонецВставки, + |ИнструкцияПрепроцессораУдаление, ИнструкцияПрепроцессораКонецУдаления, + |ИнструкцияПрепроцессораИспользовать, + |ВыражениеПрепроцессораБинарное, ВыражениеПрепроцессораНе, + |ВыражениеПрепроцессораСимвол, ВыражениеПрепроцессораСкобочное" + ); +КонецФункции // Типы() + +Функция Директивы() Экспорт + Возврат Перечисление(Новый Структура, + "НаКлиенте.AtClient," + "НаСервере.AtServer," + "НаСервереБезКонтекста.AtServerNoContext," + "НаКлиентеНаСервереБезКонтекста.AtClientAtServerNoContext," + "НаКлиентеНаСервере.AtClientAtServer" + ); +КонецФункции // Директивы() + +Функция Аннотации() Экспорт + Возврат Перечисление(Новый Структура, + "Перед.Before," + "После.After," + "Вместо.Around," + "ИзменениеИКонтроль.ChangeAndValidate," + ); +КонецФункции // Аннотации() + +Функция ИнструкцииПрепроцессора() + Возврат Перечисление(Новый Структура, + "Если.If," + "ИначеЕсли.ElsIf," + "Иначе.Else," + "КонецЕсли.EndIf," + "Область.Region," + "КонецОбласти.EndRegion," + "Вставка.Insert," + "КонецВставки.EndInsert," + "Удаление.Delete," + "КонецУдаления.EndDelete," + "Использовать.Use," + ); +КонецФункции // ИнструкцииПрепроцессора() + +Функция СимволыПрепроцессора() Экспорт + Возврат Перечисление(Новый Структура, + "Клиент.Client," + "НаКлиенте.AtClient," + "НаСервере.AtServer," + "МобильноеПриложениеКлиент.MobileAppClient," + "МобильноеПриложениеСервер.MobileAppServer," + "ТолстыйКлиентОбычноеПриложение.ThickClientOrdinaryApplication," + "ТолстыйКлиентУправляемоеПриложение.ThickClientManagedApplication," + "Сервер.Server," + "ВнешнееСоединение.ExternalConnection," + "ТонкийКлиент.ThinClient," + "ВебКлиент.WebClient" + ); +КонецФункции // СимволыПрепроцессора() + +Функция Перечисление(Структура, Ключи) + Перем Элементы, Имя, Имена, Значение; + + Для Каждого Элементы Из СтрРазделить(Ключи, ",", Ложь) Цикл + Имена = СтрРазделить(Элементы, ".", Ложь); + Значение = СокрЛП(Имена[0]); + Для Каждого Имя Из Имена Цикл + Структура.Вставить(СокрЛП(Имя), Значение); + КонецЦикла; + КонецЦикла; + + Возврат Новый ФиксированнаяСтруктура(Структура); +КонецФункции // Перечисление() + +#КонецОбласти // Перечисления + +#Область Парсер + +Функция СледующийТокен() + Перем Начало, ПредыдущийСимвол, Комментарий, ДанныеТокена; + + Парсер_Значение = Неопределено; + + Если Прав(Парсер_Литерал, 1) = Символы_ПС Тогда + Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; + Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция - 1; + КонецЕсли; + + Пока Истина Цикл + + Комментарий = Ложь; + + // пропуск невидимых символов + Пока ПустаяСтрока(Парсер_Символ) И Парсер_Символ <> "" Цикл + Если Парсер_Символ = Символы_ПС Тогда + Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; + Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция; + КонецЕсли; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЦикла; + + Парсер_ПозицияНачалаТокена = Парсер_ТекущаяПозиция; + + Парсер_Токен = КартаТокенов[Парсер_Символ]; + Если Парсер_Токен = Буква Тогда + + // сканирование идентификатора + Начало = Парсер_ТекущаяПозиция; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + КонецЦикла; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + + // определение токена + Если КлючевыеСлова.Свойство(Парсер_Литерал, Парсер_Токен) Тогда + Если Парсер_Токен = Токены.Истина Тогда + Парсер_Значение = Истина; + ИначеЕсли Парсер_Токен = Токены.Ложь Тогда + Парсер_Значение = Ложь; + ИначеЕсли Парсер_Токен = Токены.Null Тогда + Парсер_Значение = Null; + КонецЕсли; + Иначе + Парсер_Токен = Токены.Идентификатор; + КонецЕсли; + + ИначеЕсли Парсер_Токен = Токены.НачалоСтроки Тогда + + Начало = Парсер_ТекущаяПозиция; + Парсер_Символ = """"; // уловка + Пока Парсер_Символ = """" Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Пока Парсер_Символ <> """" И Парсер_Символ <> Символы_ПС И Парсер_Символ <> "" Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЦикла; + Если Парсер_Символ <> "" Тогда + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЕсли; + КонецЦикла; + + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + Парсер_Значение = СтрЗаменить(Сред(Парсер_Литерал, 2, СтрДлина(Парсер_Литерал) - 2), """""", """"); + Если Прав(Парсер_Литерал, 1) = """" Тогда + Парсер_Токен = Токены.Строка; + КонецЕсли; + + ИначеЕсли Парсер_Токен = Токены.ПродолжениеСтроки Тогда + + Начало = Парсер_ТекущаяПозиция; + Парсер_Символ = """"; // уловка + Пока Парсер_Символ = """" Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Пока Парсер_Символ <> """" И Парсер_Символ <> Символы_ПС И Парсер_Символ <> "" Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЦикла; + Если Парсер_Символ <> "" Тогда + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЕсли; + КонецЦикла; + + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + Парсер_Значение = СтрЗаменить(Сред(Парсер_Литерал, 2, СтрДлина(Парсер_Литерал) - 2), """""", """"); + Если Прав(Парсер_Литерал, 1) = """" Тогда + Парсер_Токен = Токены.ОкончаниеСтроки; + КонецЕсли; + + ИначеЕсли Парсер_Токен = Цифра Тогда + + Начало = Парсер_ТекущаяПозиция; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] = Цифра Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + КонецЦикла; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Если Парсер_Символ = "." Тогда + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] = Цифра Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + КонецЦикла; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЕсли; + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + + Парсер_Значение = Число(Парсер_Литерал); + Парсер_Токен = Токены.Число; + + ИначеЕсли Парсер_Токен = Токены.ДатаВремя Тогда + + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Начало = Парсер_ТекущаяПозиция; + Парсер_ТекущаяПозиция = СтрНайти(Парсер_Исходник, "'", , Парсер_ТекущаяПозиция); + Если Парсер_ТекущаяПозиция = 0 Тогда + Парсер_Символ = ""; + Иначе + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Значение = КакДата(Парсер_Литерал); + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЕсли; + + ИначеЕсли Парсер_Токен = Неопределено Тогда + + ПредыдущийСимвол = Парсер_Символ; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + + Если ПредыдущийСимвол = "/" Тогда + + Если Парсер_Символ = "/" Тогда + // сканирование комментария + Начало = Парсер_ТекущаяПозиция + 1; + Если Начало < Парсер_ДлинаИсходника Тогда + Парсер_ТекущаяПозиция = СтрНайти(Парсер_Исходник, Символы_ПС, , Начало); + Иначе + Парсер_ТекущаяПозиция = 0; + КонецЕсли; + Если Парсер_ТекущаяПозиция = 0 Тогда + Парсер_ТекущаяПозиция = Парсер_ДлинаИсходника + 1; + Парсер_Символ = ""; + Иначе + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЕсли; + Парсер_ИндексТокена = Парсер_ИндексТокена + 1; + ДанныеТокена = Парсер_Токены.Добавить(); + ДанныеТокена.Индекс = Парсер_ИндексТокена; + ДанныеТокена.Токен = Токены.Комментарий; + ДанныеТокена.НомерСтроки = Парсер_НомерТекущейСтроки; + ДанныеТокена.НомерКолонки = Парсер_ПозицияНачалаТокена + 2 - Парсер_ПозицияТекущейСтроки; + ДанныеТокена.Позиция = Парсер_ПозицияНачалаТокена + 2; + ДанныеТокена.Длина = Парсер_ТекущаяПозиция - ДанныеТокена.Позиция; + Комментарий = Истина; + Иначе + Парсер_Токен = Токены.ЗнакДеления; + КонецЕсли; + + ИначеЕсли ПредыдущийСимвол = "<" Тогда + + Если Парсер_Символ = ">" Тогда + Парсер_Токен = Токены.ЗнакНеРавно; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + ИначеЕсли Парсер_Символ = "=" Тогда + Парсер_Токен = Токены.ЗнакМеньшеИлиРавно; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Иначе + Парсер_Токен = Токены.ЗнакМеньше; + КонецЕсли; + + ИначеЕсли ПредыдущийСимвол = ">" Тогда + + Если Парсер_Символ = "=" Тогда + Парсер_Токен = Токены.ЗнакБольшеИлиРавно; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Иначе + Парсер_Токен = Токены.ЗнакБольше; + КонецЕсли; + + ИначеЕсли ПредыдущийСимвол = "&" Тогда + + Если КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Буква Тогда + Ошибка(2, Неопределено, Истина); + КонецЕсли; + + // сканирование идентификатора + Начало = Парсер_ТекущаяПозиция; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + КонецЦикла; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + + Если Директивы.Свойство(Парсер_Литерал) Тогда + Парсер_Токен = Токены.Директива; + ИначеЕсли Аннотации.Свойство(Парсер_Литерал) Тогда + Парсер_Токен = Токены.Аннотация; + Иначе + Ошибка(3, Парсер_Литерал, Ложь); + Парсер_Токен = Токены.Директива; + КонецЕсли; + + ИначеЕсли ПредыдущийСимвол = "#" Тогда + + // пропуск невидимых символов + Пока ПустаяСтрока(Парсер_Символ) И Парсер_Символ <> "" Цикл + Если Парсер_Символ = Символы_ПС Тогда + Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; + Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция; + КонецЕсли; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЦикла; + + Если КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Буква Тогда + Ошибка(4, Неопределено, Истина); + КонецЕсли; + + // сканирование идентификатора + Начало = Парсер_ТекущаяПозиция; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + КонецЦикла; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + + // сопоставление токена + Если ИнструкцииПрепроцессора.Свойство(Парсер_Литерал, Парсер_Токен) Тогда + Парсер_Токен = "_" + Парсер_Токен; + Иначе + Ошибка(5, Парсер_Литерал, Истина); + КонецЕсли; + + ИначеЕсли ПредыдущийСимвол = "~" Тогда + + // пропуск невидимых символов + Пока ПустаяСтрока(Парсер_Символ) И Парсер_Символ <> "" Цикл + Если Парсер_Символ = Символы_ПС Тогда + Парсер_НомерТекущейСтроки = Парсер_НомерТекущейСтроки + 1; + Парсер_ПозицияТекущейСтроки = Парсер_ТекущаяПозиция; + КонецЕсли; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + КонецЦикла; + + Если КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] = Неопределено Тогда + Парсер_Литерал = ""; + Иначе + // сканирование идентификатора + Начало = Парсер_ТекущаяПозиция; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Пока КартаБуквЦифр[Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1)] <> Неопределено Цикл + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + КонецЦикла; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + Парсер_Литерал = Сред(Парсер_Исходник, Начало, Парсер_ТекущаяПозиция - Начало); + КонецЕсли; + + Парсер_Токен = Токены.Метка; + + Иначе + + ВызватьИсключение "Неизвестный символ!"; + + КонецЕсли; + + Иначе + + Парсер_Литерал = Парсер_Символ; + Парсер_ТекущаяПозиция = Парсер_ТекущаяПозиция + 1; + Парсер_Символ = Сред(Парсер_Исходник, Парсер_ТекущаяПозиция, 1); + + КонецЕсли; + + Если Не Комментарий Тогда + Прервать; + КонецЕсли; + + КонецЦикла; + + Парсер_ДанныеПредыдущегоТокена = Парсер_ДанныеТекущегоТокена; + + Парсер_ИндексТокена = Парсер_ИндексТокена + 1; + + Парсер_ДанныеТекущегоТокена = Парсер_Токены.Добавить(); + Парсер_ДанныеТекущегоТокена.Индекс = Парсер_ИндексТокена; + Парсер_ДанныеТекущегоТокена.Токен = Парсер_Токен; + Парсер_ДанныеТекущегоТокена.НомерСтроки = Парсер_НомерТекущейСтроки; + Парсер_ДанныеТекущегоТокена.НомерКолонки = Парсер_ПозицияНачалаТокена - Парсер_ПозицияТекущейСтроки; + Парсер_ДанныеТекущегоТокена.Позиция = Парсер_ПозицияНачалаТокена; + Парсер_ДанныеТекущегоТокена.Длина = Парсер_ТекущаяПозиция - Парсер_ДанныеТекущегоТокена.Позиция; + + Возврат Парсер_Токен; + +КонецФункции // СледующийТокен() + +Функция Окружение(ВнешнееОкружение = Неопределено) Экспорт + Возврат Новый Структура( + "ВнешнееОкружение," // неопределено, структура (Окружение) + "Переменные," // структура как соответствие[строка] (ЭлементОкружения) + "Методы," // структура как соответствие[строка] (ЭлементОкружения) + "АвтоПеременные", // массив (ОбъявлениеАвтоПеременной) + ВнешнееОкружение, Новый Структура, Новый Структура, Новый Массив); +КонецФункции // Окружение() + +Функция НайтиЭлементОкружения(Имя) + Перем Окружение, ЭлементОкружения; + Окружение = Парсер_Окружение; + Окружение.Переменные.Свойство(Имя, ЭлементОкружения); + Пока ЭлементОкружения = Неопределено И Окружение.ВнешнееОкружение <> Неопределено Цикл + Окружение = Окружение.ВнешнееОкружение; + Окружение.Переменные.Свойство(Имя, ЭлементОкружения); + КонецЦикла; + Возврат ЭлементОкружения; +КонецФункции // НайтиЭлементОкружения() + +Функция НайтиМетод(Имя) + Перем Окружение, Метод; + Окружение = Парсер_Окружение; + Окружение.Методы.Свойство(Имя, Метод); + Пока Метод = Неопределено И Окружение.ВнешнееОкружение <> Неопределено Цикл + Окружение = Окружение.ВнешнееОкружение; + Окружение.Методы.Свойство(Имя, Метод); + КонецЦикла; + Возврат Метод; +КонецФункции + +Функция ОткрытьОкружение() + Перем Окружение; + Окружение = Окружение(Парсер_Окружение); + Парсер_Окружение = Окружение; + Парсер_Переменные = Окружение.Переменные; + Возврат Окружение; +КонецФункции // ОткрытьОкружение() + +Функция ЗакрытьОкружение() + Перем Окружение; + Окружение = Парсер_Окружение.ВнешнееОкружение; + Парсер_Окружение = Окружение; + Если Окружение <> Неопределено Тогда + Парсер_Переменные = Окружение.Переменные; + КонецЕсли; + Возврат Окружение; +КонецФункции // ЗакрытьОкружение() + +Функция Узлы() Экспорт + Возврат Парсер_Узлы; +КонецФункции + +Функция Токенизировать(Исходник) Экспорт + Перем ПоследнийТокен; + + Парсер_Исходник = Исходник; + Парсер_ТекущаяПозиция = 0; + Парсер_НомерТекущейСтроки = 1; + Парсер_ПозицияНачалаТокена = 0; + Парсер_ПозицияТекущейСтроки = 0; + Парсер_ДлинаИсходника = СтрДлина(Исходник); + Парсер_Литерал = ""; + Парсер_Символ = Неопределено; + Парсер_Ошибки.Очистить(); + Парсер_Токены.Очистить(); + Парсер_ИндексТокена = 0; + Парсер_ДанныеТекущегоТокена = Парсер_Токены.Добавить(); + Парсер_ДанныеТекущегоТокена.Токен = Токены.НачалоТекста; + Парсер_Замены.Очистить(); + + Пока СледующийТокен() <> Токены.КонецТекста Цикл + КонецЦикла; + + ПоследнийТокен = Парсер_Токены[Парсер_Токены.Количество() - 1]; + ПоследнийТокен.Длина = 0; + + Возврат Парсер_Токены; + +КонецФункции + +Функция ТаблицаТокенов() Экспорт + Возврат Парсер_Токены; +КонецФункции + +// Служебный метод. Позволяет установить таблицу токенов напрямую без вызова Разобрать(). +// Это необходимо делать перед вызовом Посетить() при обработке кэшированных АСД, +// чтобы плагины и бакенды могли получить таблицу токенов из парсера. +Процедура УстановитьТаблицуТокенов(ТаблицаТокенов) Экспорт + Парсер_Токены = ТаблицаТокенов; +КонецПроцедуры + +Функция ТаблицаЗамен() Экспорт + Возврат Парсер_Замены; +КонецФункции + +Функция ВыполнитьЗамены() Экспорт + Перем Результат, ПозицияНачала, Индекс, Замена; + + Если Парсер_Замены.Количество() = 0 Тогда + Возврат Неопределено; + КонецЕсли; + + Результат = Новый Массив; + + Парсер_Замены.Сортировать("Позиция"); + + ПозицияНачала = 1; + + Для Индекс = 0 По Парсер_Замены.Количество() - 1 Цикл + + Замена = Парсер_Замены[Индекс]; + + Если Замена.Позиция < ПозицияНачала Тогда + КодОшибки = 19; + Ошибка = Парсер_Ошибки.Добавить(); + Ошибка.Источник = "ПарсерВстроенногоЯзыка"; + Ошибка.Код = КодОшибки; + Ошибка.Текст = СтрШаблон(Ошибки[КодОшибки] + ": `%1`", Замена.Текст); + Ошибка.ПозицияНачала = Замена.Позиция; + Ошибка.ПозицияКонца = Замена.Позиция + Замена.Длина; + Продолжить; + КонецЕсли; + + Результат.Добавить(Сред(Парсер_Исходник, ПозицияНачала, Замена.Позиция - ПозицияНачала)); + Результат.Добавить(Замена.Текст); + + ПозицияНачала = Замена.Позиция + Замена.Длина; + + КонецЦикла; + + Результат.Добавить(Сред(Парсер_Исходник, ПозицияНачала)); + + Возврат СтрСоединить(Результат); + +КонецФункции + +Функция Разобрать(Исходник, ВнешнееОкружение = Неопределено) Экспорт + Перем Объявления, Переменные, ОбъявлениеАвтоПеременной, ЭлементОкружения, Операторы, Модуль, ТочкиВызова, ИндексТокена, ПоследнийТокен; + + Парсер_Исходник = Исходник; + Парсер_ТекущаяПозиция = 0; + Парсер_НомерТекущейСтроки = 1; + Парсер_ПозицияТекущейСтроки = 0; + Парсер_ПозицияНачалаТокена = 0; + Парсер_Неизвестные = Новый Структура; + Парсер_ТочкиВызова = Новый Соответствие; + Парсер_ЭтоФункция = Ложь; + Парсер_ЭтоАсинх = Ложь; + Парсер_ПеременныеРазрешены = Истина; + Парсер_Интерфейс = Новый Массив; + Парсер_ДлинаИсходника = СтрДлина(Исходник); + Парсер_Литерал = ""; + Парсер_Символ = Неопределено; + Парсер_Ошибки.Очистить(); + Парсер_Токены.Очистить(); + Парсер_ИндексТокена = 0; + Парсер_ДанныеТекущегоТокена = Парсер_Токены.Добавить(); + Парсер_ДанныеТекущегоТокена.Токен = Токены.НачалоТекста; + Парсер_Замены.Очистить(); + + Парсер_Окружение = ВнешнееОкружение; + ОткрытьОкружение(); + Парсер_Методы = Парсер_Окружение.Методы; + СледующийТокен(); + Переменные = Новый Массив; + Объявления = РазобратьОбъявленияМодуля(Переменные); + Операторы = РазобратьОператоры(); + Для Каждого ОбъявлениеАвтоПеременной Из Парсер_Окружение.АвтоПеременные Цикл + Переменные.Добавить(ОбъявлениеАвтоПеременной); + КонецЦикла; + Модуль = Парсер_Узлы.Модуль.Добавить(); + Модуль.Тип = Типы.Модуль; + Модуль.Объявления = Объявления; + Модуль.Переменные = Переменные; + Модуль.Операторы = Операторы; + Модуль.Интерфейс = Парсер_Интерфейс; + Если СтрогийРежим Тогда + Для Каждого ЭлементОкружения Из Парсер_Неизвестные Цикл + ТочкиВызова = Парсер_ТочкиВызова[ЭлементОкружения.Значение]; + Для Каждого ИндексТокена Из ТочкиВызова Цикл + Ошибка(6, ЭлементОкружения.Ключ, Ложь, ИндексТокена); + КонецЦикла; + КонецЦикла; + КонецЕсли; + Ожидать(Токены.КонецТекста); + ЗакрытьОкружение(); + + ПоследнийТокен = Парсер_Токены[Парсер_Токены.Количество() - 1]; + ПоследнийТокен.Длина = 0; + + Парсер_Неизвестные = Неопределено; + Парсер_Методы = Неопределено; + Парсер_СписокДиректив = Неопределено; + Парсер_СписокАннотаций = Неопределено; + Парсер_Интерфейс = Неопределено; + Парсер_Окружение = Неопределено; + Парсер_Переменные = Неопределено; + + Возврат Модуль; +КонецФункции // Разобрать() + +Функция ТаблицаОшибок() Экспорт + Возврат Парсер_Ошибки; +КонецФункции + +// Служебный метод. Позволяет установить таблицу ошибок напрямую без вызова Разобрать(). +// Это необходимо делать перед вызовом Посетить() при обработке кэшированных АСД, +// чтобы плагины и бакенды могли получить таблицу ошибок из парсера. +Процедура УстановитьТаблицуОшибок(ТаблицаОшибок) Экспорт + Парсер_Ошибки = ТаблицаОшибок; +КонецПроцедуры + +Функция Исходник() Экспорт + Возврат Парсер_Исходник; +КонецФункции + +// Служебный метод. Позволяет установить исходник напрямую без вызова Разобрать(). +// Это необходимо делать перед вызовом Посетить() при обработке кэшированных АСД, +// чтобы плагины и бакенды могли получить исходник из парсера. +Процедура УстановитьИсходник(Исходник) Экспорт + Парсер_Исходник = Исходник; +КонецПроцедуры + +#Область РазборВыражений + +Функция РазобратьВыражение() + Перем Выражение, Операция, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Выражение = РазобратьВыражениеИ(); + Пока Парсер_Токен = Токены.Или Цикл + Операция = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЛевыйОперанд = Выражение; + Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); + Выражение.Тип = Типы.ВыражениеБинарное; + Выражение.ЛевыйОперанд = ЛевыйОперанд; + Выражение.Операция = Операция; + Выражение.ПравыйОперанд = РазобратьВыражениеИ(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЦикла; + Возврат Выражение; +КонецФункции // РазобратьВыражение() + +Функция РазобратьВыражениеИ() + Перем Выражение, Операция, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Выражение = РазобратьВыражениеНе(); + Пока Парсер_Токен = Токены.И Цикл + Операция = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЛевыйОперанд = Выражение; + Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); + Выражение.Тип = Типы.ВыражениеБинарное; + Выражение.ЛевыйОперанд = ЛевыйОперанд; + Выражение.Операция = Операция; + Выражение.ПравыйОперанд = РазобратьВыражениеНе(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЦикла; + Возврат Выражение; +КонецФункции // РазобратьВыражениеИ() + +Функция РазобратьВыражениеНе() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Если Парсер_Токен = Токены.Не Тогда + СледующийТокен(); + Выражение = Парсер_Узлы.ВыражениеНе.Добавить(); + Выражение.Тип = Типы.ВыражениеНе; + Выражение.Выражение = РазобратьВыражениеОтношения(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + Иначе + Выражение = РазобратьВыражениеОтношения(); + КонецЕсли; + Возврат Выражение; +КонецФункции // РазобратьВыражениеНе() + +Функция РазобратьВыражениеОтношения() + Перем Выражение, Операция, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Выражение = РазобратьВыражениеАддитивное(); + Пока ОперацииСравнения.Найти(Парсер_Токен) <> Неопределено Цикл + Операция = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЛевыйОперанд = Выражение; + Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); + Выражение.Тип = Типы.ВыражениеБинарное; + Выражение.ЛевыйОперанд = ЛевыйОперанд; + Выражение.Операция = Операция; + Выражение.ПравыйОперанд = РазобратьВыражениеАддитивное(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЦикла; + Возврат Выражение; +КонецФункции // РазобратьВыражениеОтношения() + +Функция РазобратьВыражениеАддитивное() + Перем Выражение, Операция, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Выражение = РазобратьВыражениеМультипликативное(); + Пока ОперацииАддитивные.Найти(Парсер_Токен) <> Неопределено Цикл + Операция = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЛевыйОперанд = Выражение; + Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); + Выражение.Тип = Типы.ВыражениеБинарное; + Выражение.ЛевыйОперанд = ЛевыйОперанд; + Выражение.Операция = Операция; + Выражение.ПравыйОперанд = РазобратьВыражениеМультипликативное(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЦикла; + Возврат Выражение; +КонецФункции // РазобратьВыражениеАддитивное() + +Функция РазобратьВыражениеМультипликативное() + Перем Выражение, Операция, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Выражение = РазобратьВыражениеУнарное(); + Пока ОперацииМультипликативные.Найти(Парсер_Токен) <> Неопределено Цикл + Операция = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЛевыйОперанд = Выражение; + Выражение = Парсер_Узлы.ВыражениеБинарное.Добавить(); + Выражение.Тип = Типы.ВыражениеБинарное; + Выражение.ЛевыйОперанд = ЛевыйОперанд; + Выражение.Операция = Операция; + Выражение.ПравыйОперанд = РазобратьВыражениеУнарное(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЦикла; + Возврат Выражение; +КонецФункции // РазобратьВыражениеМультипликативное() + +Функция РазобратьВыражениеУнарное() + Перем Операция, Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Операция = Парсер_ДанныеТекущегоТокена; + Если ОперацииАддитивные.Найти(Парсер_Токен) <> Неопределено Тогда + СледующийТокен(); + Выражение = Парсер_Узлы.ВыражениеУнарное.Добавить(); + Выражение.Тип = Типы.ВыражениеУнарное; + Выражение.Операция = Операция; + Выражение.Операнд = РазобратьОперанд(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + ИначеЕсли Парсер_Токен = Токены.КонецТекста Тогда + Выражение = Неопределено; + Иначе + Выражение = РазобратьОперанд(); + КонецЕсли; + Возврат Выражение; +КонецФункции // РазобратьВыражениеУнарное() + +Функция РазобратьОперанд() + Перем Операнд; + Если Парсер_Токен = Токены.Строка Или Парсер_Токен = Токены.НачалоСтроки Тогда + Операнд = РазобратьВыражениеСтроковое(); + ИначеЕсли ЛитералКромеСтроки.Найти(Парсер_Токен) <> Неопределено Тогда + Операнд = Парсер_Узлы.ВыражениеЛитерал.Добавить(); + Операнд.Тип = Типы.ВыражениеЛитерал; + Операнд.Вид = Парсер_Токен; + Операнд.Значение = Парсер_Значение; + Операнд.Начало = Парсер_ДанныеТекущегоТокена; + Операнд.Конец = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены.Идентификатор Тогда + Операнд = РазобратьВыражениеИдентификатор(); + ИначеЕсли Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда + Операнд = РазобратьВыражениеСкобочное(); + ИначеЕсли Парсер_Токен = Токены.Новый Тогда + Операнд = РазобратьВыражениеНовый(); + ИначеЕсли Парсер_Токен = Токены.Ждать Тогда + Операнд = РазобратьВыражениеЖдать(); + ИначеЕсли Парсер_Токен = Токены.ЗнакВопроса Тогда + Операнд = РазобратьВыражениеТернарное(); + Иначе + Ошибка(7, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + Возврат Операнд; +КонецФункции // РазобратьОперанд() + +Функция РазобратьВыражениеСтроковое() + Перем СписокВыражений, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СписокВыражений = Новый Массив; + Пока Истина Цикл + Если Парсер_Токен = Токены.Строка Тогда + Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); + Узел.Тип = Типы.ВыражениеЛитерал; + Узел.Вид = Парсер_Токен; + Узел.Значение = Парсер_Значение; + Узел.Начало = Парсер_ДанныеТекущегоТокена; + Узел.Конец = Парсер_ДанныеТекущегоТокена;; + СписокВыражений.Добавить(Узел); + СледующийТокен(); + Пока Парсер_Токен = Токены.Строка Цикл + Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); + Узел.Тип = Типы.ВыражениеЛитерал; + Узел.Вид = Парсер_Токен; + Узел.Значение = Парсер_Значение; + Узел.Начало = Парсер_ДанныеТекущегоТокена; + Узел.Конец = Парсер_ДанныеТекущегоТокена;; + СписокВыражений.Добавить(Узел); + СледующийТокен(); + КонецЦикла; + ИначеЕсли Парсер_Токен = Токены.НачалоСтроки Тогда + Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); + Узел.Тип = Типы.ВыражениеЛитерал; + Узел.Вид = Парсер_Токен; + Узел.Значение = Парсер_Значение; + Узел.Начало = Парсер_ДанныеТекущегоТокена; + Узел.Конец = Парсер_ДанныеТекущегоТокена;; + СписокВыражений.Добавить(Узел); + СледующийТокен(); + Пока Парсер_Токен = Токены.ПродолжениеСтроки Цикл + Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); + Узел.Тип = Типы.ВыражениеЛитерал; + Узел.Вид = Парсер_Токен; + Узел.Значение = Парсер_Значение; + Узел.Начало = Парсер_ДанныеТекущегоТокена; + Узел.Конец = Парсер_ДанныеТекущегоТокена;; + СписокВыражений.Добавить(Узел); + СледующийТокен(); + КонецЦикла; + Если Парсер_Токен <> Токены.ОкончаниеСтроки Тогда + Ошибка(1, """", Истина, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + Узел = Парсер_Узлы.ВыражениеЛитерал.Добавить(); + Узел.Тип = Типы.ВыражениеЛитерал; + Узел.Вид = Парсер_Токен; + Узел.Значение = Парсер_Значение; + Узел.Начало = Парсер_ДанныеТекущегоТокена; + Узел.Конец = Парсер_ДанныеТекущегоТокена;; + СписокВыражений.Добавить(Узел); + СледующийТокен(); + Иначе + Прервать; + КонецЕсли; + КонецЦикла; + Узел = Парсер_Узлы.ВыражениеСтроковое.Добавить(); + Узел.Тип = Типы.ВыражениеСтроковое; + Узел.Элементы = СписокВыражений; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьВыражениеСтроковое() + +Функция РазобратьВыражениеНовый() + Перем Имя, Аргументы, Хвост, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Если Парсер_Токен = Токены.Идентификатор Тогда + Имя = Парсер_Литерал; + Аргументы = ПустойМассив; + СледующийТокен(); + КонецЕсли; + Хвост = ПустойМассив; + Если Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда + СледующийТокен(); + Если Парсер_Токен <> Токены.ПраваяКруглаяСкобка Тогда + Аргументы = РазобратьАргументы(); + Ожидать(Токены.ПраваяКруглаяСкобка); + КонецЕсли; + СледующийТокен(); + Если Парсер_Токен = Токены.Точка Тогда + Хвост = РазобратьХвост(); + КонецЕсли; + КонецЕсли; + Если Имя = Неопределено Тогда + Если Аргументы = Неопределено Тогда + Ошибка(8, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); + ИначеЕсли Аргументы.Количество() > 2 Тогда + Ошибка(9, Неопределено, Истина, Начало, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + КонецЕсли; + Узел = Парсер_Узлы.ВыражениеНовый.Добавить(); + Узел.Тип = Типы.ВыражениеНовый; + Узел.Имя = Имя; + Узел.Аргументы = Аргументы; + Узел.Хвост = Хвост; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьВыражениеНовый() + +Функция РазобратьВыражениеЖдать() + Перем Операция, Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + + СледующийТокен(); + Выражение = Парсер_Узлы.ВыражениеЖдать.Добавить(); + Выражение.Тип = Типы.ВыражениеЖдать; + Выражение.Выражение = РазобратьОперанд(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + + Возврат Выражение; +КонецФункции // РазобратьВыражениеУнарное() + +Функция РазобратьВыражениеИдентификатор(Знач НоваяПеременнаяРазрешена = Ложь, НоваяПеременная = Неопределено, ЭтоВызов = Неопределено) + Перем Имя, ЭлементОкружения, Хвост, Аргументы, НачалоАвтоПеременной, ТочкиВызова, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Имя = Парсер_Литерал; + НачалоАвтоПеременной = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Если Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда + Если СледующийТокен() = Токены.ПраваяКруглаяСкобка Тогда + Аргументы = ПустойМассив; + Иначе + Аргументы = РазобратьАргументы(); + КонецЕсли; + Ожидать(Токены.ПраваяКруглаяСкобка); + СледующийТокен(); + ЭлементОкружения = НайтиМетод(Имя); + Если ЭлементОкружения = Неопределено Тогда + Если Парсер_Неизвестные.Свойство(Имя, ЭлементОкружения) Тогда + ТочкиВызова = Парсер_ТочкиВызова[ЭлементОкружения]; + ТочкиВызова.Добавить(НачалоАвтоПеременной); + Иначе + ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); + ЭлементОкружения.Тип = Типы.ЭлементОкружения; + ЭлементОкружения.Имя = Имя; + ЭлементОкружения.Объявление = Неопределено; + Парсер_Неизвестные.Вставить(Имя, ЭлементОкружения); + ТочкиВызова = Новый Массив; + ТочкиВызова.Добавить(НачалоАвтоПеременной); + Парсер_ТочкиВызова[ЭлементОкружения] = ТочкиВызова; + КонецЕсли; + КонецЕсли; + ЭтоВызов = Истина; + Хвост = РазобратьХвост(ЭтоВызов); + Иначе + ЭтоВызов = Ложь; + Хвост = РазобратьХвост(ЭтоВызов); + Если Хвост.Количество() > 0 Тогда + НоваяПеременнаяРазрешена = Ложь; + КонецЕсли; + ЭлементОкружения = НайтиЭлементОкружения(Имя); + Если ЭлементОкружения = Неопределено Тогда + Если НоваяПеременнаяРазрешена Тогда + ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); + ЭлементОкружения.Тип = Типы.ЭлементОкружения; + ЭлементОкружения.Имя = Имя; + ЭлементОкружения.Объявление = Парсер_Узлы.ОбъявлениеАвтоПеременной.Добавить(); + ЭлементОкружения.Объявление.Тип = Типы.ОбъявлениеАвтоПеременной; + ЭлементОкружения.Объявление.Имя = Имя; + ЭлементОкружения.Объявление.Начало = НачалоАвтоПеременной; + ЭлементОкружения.Объявление.Конец = НачалоАвтоПеременной;; + НоваяПеременная = ЭлементОкружения; + Иначе + ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); + ЭлементОкружения.Тип = Типы.ЭлементОкружения; + ЭлементОкружения.Имя = Имя; + ЭлементОкружения.Объявление = Неопределено; + Если СтрогийРежим Тогда + Ошибка(10, Имя, Ложь, Начало); + КонецЕсли; + КонецЕсли; + КонецЕсли; + КонецЕсли; + Узел = Парсер_Узлы.ВыражениеИдентификатор.Добавить(); + Узел.Тип = Типы.ВыражениеИдентификатор; + Узел.Голова = ЭлементОкружения; + Узел.Хвост = Хвост; + Узел.Аргументы = Аргументы; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьВыражениеИдентификатор() + +Функция РазобратьХвост(Вызов = Неопределено) + Перем Хвост, Имя, Аргументы, Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Хвост = Новый Массив; + Пока Истина Цикл + Если Парсер_Токен = Токены.Точка Тогда + СледующийТокен(); + Если КартаБуквЦифр[Лев(Парсер_Литерал, 1)] <> Буква Или Не КлючевыеСлова.Свойство(Парсер_Литерал) Тогда + Ожидать(Токены.Идентификатор); + КонецЕсли; + Имя = Парсер_Литерал; + Если СледующийТокен() = Токены.ЛеваяКруглаяСкобка Тогда + Если СледующийТокен() = Токены.ПраваяКруглаяСкобка Тогда + Аргументы = ПустойМассив; + Иначе + Аргументы = РазобратьАргументы(); + КонецЕсли; + Ожидать(Токены.ПраваяКруглаяСкобка); + СледующийТокен(); + Вызов = Истина; + Иначе + Аргументы = Неопределено; + Вызов = Ложь; + КонецЕсли; + Узел = Парсер_Узлы.ВыражениеПоле.Добавить(); + Узел.Тип = Типы.ВыражениеПоле; + Узел.Имя = Имя; + Узел.Аргументы = Аргументы; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена;; + Хвост.Добавить(Узел); + ИначеЕсли Парсер_Токен = Токены.ЛеваяКвадратнаяСкобка Тогда + Вызов = Ложь; + Если СледующийТокен() = Токены.ПраваяКвадратнаяСкобка Тогда + Ошибка(11, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + Выражение = РазобратьВыражение(); + Ожидать(Токены.ПраваяКвадратнаяСкобка); + СледующийТокен(); + Узел = Парсер_Узлы.ВыражениеИндекс.Добавить(); + Узел.Тип = Типы.ВыражениеИндекс; + Узел.Выражение = Выражение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена;; + Хвост.Добавить(Узел); + Иначе + Прервать; + КонецЕсли; + КонецЦикла; + Возврат Хвост; +КонецФункции // РазобратьХвост() + +Функция РазобратьАргументы() + Перем СписокВыражений; + СписокВыражений = Новый Массив; + Пока Истина Цикл + Если ТокеныНачалаВыражения.Найти(Парсер_Токен) <> Неопределено Тогда + СписокВыражений.Добавить(РазобратьВыражение()); + Иначе + СписокВыражений.Добавить(Неопределено); + КонецЕсли; + Если Парсер_Токен = Токены.Запятая Тогда + СледующийТокен(); + Иначе + Прервать; + КонецЕсли; + КонецЦикла; + Возврат СписокВыражений; +КонецФункции // РазобратьАргументы() + +Функция РазобратьВыражениеТернарное() + Перем Выражение, ТогдаОператоры, ИначеОператоры, Хвост, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Ожидать(Токены.ЛеваяКруглаяСкобка); + СледующийТокен(); + Выражение = РазобратьВыражение(); + Ожидать(Токены.Запятая); + СледующийТокен(); + ТогдаОператоры = РазобратьВыражение(); + Ожидать(Токены.Запятая); + СледующийТокен(); + ИначеОператоры = РазобратьВыражение(); + Ожидать(Токены.ПраваяКруглаяСкобка); + Если СледующийТокен() = Токены.Точка Тогда + Хвост = РазобратьХвост(); + Иначе + Хвост = ПустойМассив; + КонецЕсли; + Узел = Парсер_Узлы.ВыражениеТернарное.Добавить(); + Узел.Тип = Типы.ВыражениеТернарное; + Узел.Выражение = Выражение; + Узел.Тогда = ТогдаОператоры; + Узел.Иначе = ИначеОператоры; + Узел.Хвост = Хвост; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьВыражениеТернарное() + +Функция РазобратьВыражениеСкобочное() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Выражение = РазобратьВыражение(); + Ожидать(Токены.ПраваяКруглаяСкобка); + СледующийТокен(); + Узел = Парсер_Узлы.ВыражениеСкобочное.Добавить(); + Узел.Тип = Типы.ВыражениеСкобочное; + Узел.Выражение = Выражение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьВыражениеСкобочное() + +#КонецОбласти // РазборВыражений + +#Область РазборОбъявлений + +Функция РазобратьОбъявленияМодуля(Переменные) + Перем Объявления, ОбъявлениеДирективы; + Объявления = Новый Массив; + Пока Истина Цикл + Парсер_СписокДиректив = Новый Массив; + Парсер_СписокАннотаций = Новый Массив; + Пока Истина Цикл + Если Парсер_Токен = Токены.Директива Тогда + ОбъявлениеДирективы = Парсер_Узлы.ОбъявлениеДирективы.Добавить(); + ОбъявлениеДирективы.Тип = Типы.ОбъявлениеДирективы; + ОбъявлениеДирективы.Директива = Директивы[Парсер_Литерал]; + ОбъявлениеДирективы.Начало = Парсер_ДанныеТекущегоТокена; + ОбъявлениеДирективы.Конец = Парсер_ДанныеТекущегоТокена; + Парсер_СписокДиректив.Добавить(ОбъявлениеДирективы); + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены.Аннотация Тогда + Аннотация = Аннотации[Парсер_Литерал]; + НачалоАннотации = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Ожидать(Токены.ЛеваяКруглаяСкобка); + СледующийТокен(); + Ожидать(Токены.Строка); + ИмяМетода = Парсер_Значение; + СледующийТокен(); + Ожидать(Токены.ПраваяКруглаяСкобка); + ОбъявлениеАннотации = Парсер_Узлы.ОбъявлениеАннотации.Добавить(); + ОбъявлениеАннотации.Тип = Типы.ОбъявлениеАннотации; + ОбъявлениеАннотации.Аннотация = Аннотация; + ОбъявлениеАннотации.ИмяМетода = ИмяМетода; + ОбъявлениеАннотации.Начало = НачалоАннотации; + ОбъявлениеАннотации.Конец = Парсер_ДанныеТекущегоТокена; + Парсер_СписокАннотаций.Добавить(ОбъявлениеАннотации); + СледующийТокен(); + Иначе + Прервать; + КонецЕсли; + КонецЦикла; + Если Парсер_Токен = Токены.Перем И Парсер_ПеременныеРазрешены Тогда + Объявления.Добавить(РазобратьОбъявлениеСпискаПеременныхМодуля(Переменные)); + ИначеЕсли Парсер_Токен = Токены.Функция + ИЛИ Парсер_Токен = Токены.Процедура + ИЛИ Парсер_Токен = Токены.Асинх Тогда + Если Парсер_Токен = Токены.Асинх Тогда + Парсер_ЭтоАсинх = Истина; + СледующийТокен(); + КонецЕсли; + Если Парсер_Токен = Токены.Функция Тогда + Парсер_ЭтоФункция = Истина; + КонецЕсли; + Объявления.Добавить(РазобратьОбъявлениеМетода()); + Парсер_ЭтоФункция = Ложь; + Парсер_ЭтоАсинх = Ложь; + Парсер_ПеременныеРазрешены = Ложь; + ИначеЕсли Парсер_Токен = Токены._Область Тогда + Объявления.Добавить(РазобратьИнструкциюПрепроцессораОбласть()); + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены._КонецОбласти Тогда + Объявления.Добавить(РазобратьИнструкциюПрепроцессораКонецОбласти()); + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены._Если Тогда + Объявления.Добавить(РазобратьИнструкциюПрепроцессораЕсли()); + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены._ИначеЕсли Тогда + Объявления.Добавить(РазобратьИнструкциюПрепроцессораИначеЕсли()); + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены._Иначе Тогда + Объявления.Добавить(РазобратьИнструкциюПрепроцессораИначе()); + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены._КонецЕсли Тогда + Объявления.Добавить(РазобратьИнструкциюПрепроцессораКонецЕсли()); + СледующийТокен(); + ИначеЕсли Парсер_Токен = Токены._Использовать Тогда + Объявления.Добавить(РазобратьИнструкциюПрепроцессораИспользовать()); + СледующийТокен(); + Иначе + Прервать; + КонецЕсли; + КонецЦикла; + Возврат Объявления; +КонецФункции // РазобратьОбъявленияМодуля() + +Функция РазобратьОбъявлениеСпискаПеременныхМодуля(Переменные) + Перем ОбъявленияПеременных, ОбъявлениеПеременной, Объявление, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ОбъявленияПеременных = Новый Массив; + ОбъявлениеПеременной = РазобратьОбъявлениеПеременнойМодуля(); + ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); + Переменные.Добавить(ОбъявлениеПеременной); + Пока Парсер_Токен = Токены.Запятая Цикл + СледующийТокен(); + ОбъявлениеПеременной = РазобратьОбъявлениеПеременнойМодуля(); + ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); + Переменные.Добавить(ОбъявлениеПеременной); + КонецЦикла; + Объявление = Парсер_Узлы.ОбъявлениеСпискаПеременныхМодуля.Добавить(); + Объявление.Тип = Типы.ОбъявлениеСпискаПеременныхМодуля; + Объявление.Директивы = Парсер_СписокДиректив; + Объявление.Объявления = ОбъявленияПеременных; + Объявление.Начало = Начало; + Объявление.Конец = Парсер_ДанныеПредыдущегоТокена; + Ожидать(Токены.ТочкаСЗапятой); + СледующийТокен(); + Пока Парсер_Токен = Токены.ТочкаСЗапятой Цикл + СледующийТокен(); + КонецЦикла; + Возврат Объявление; +КонецФункции // РазобратьОбъявлениеСпискаПеременныхМодуля() + +Функция РазобратьОбъявлениеПеременнойМодуля() + Перем Имя, ОбъявлениеПеременнойМодуля, ЭлементОкружения, ЕстьЭкспорт, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Ожидать(Токены.Идентификатор); + Имя = Парсер_Литерал; + Если СледующийТокен() = Токены.Экспорт Тогда + ЕстьЭкспорт = Истина; + СледующийТокен(); + Иначе + ЕстьЭкспорт = Ложь; + КонецЕсли; + ОбъявлениеПеременнойМодуля = Парсер_Узлы.ОбъявлениеПеременнойМодуля.Добавить(); + ОбъявлениеПеременнойМодуля.Тип = Типы.ОбъявлениеПеременнойМодуля; + ОбъявлениеПеременнойМодуля.Имя = Имя; + ОбъявлениеПеременнойМодуля.Директивы = Парсер_СписокДиректив; + ОбъявлениеПеременнойМодуля.Экспорт = ЕстьЭкспорт; + ОбъявлениеПеременнойМодуля.Начало = Начало; + ОбъявлениеПеременнойМодуля.Конец = Парсер_ДанныеПредыдущегоТокена; + Если Парсер_Переменные.Свойство(Имя) Тогда + Ошибка(12, Имя, СтрогийРежим, Начало); + КонецЕсли; + ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); + ЭлементОкружения.Тип = Типы.ЭлементОкружения; + ЭлементОкружения.Имя = Имя; + ЭлементОкружения.Объявление = ОбъявлениеПеременнойМодуля; + Парсер_Переменные.Вставить(Имя, ЭлементОкружения); + Если ЕстьЭкспорт Тогда + Парсер_Интерфейс.Добавить(ЭлементОкружения); + КонецЕсли; + Возврат ОбъявлениеПеременнойМодуля; +КонецФункции // РазобратьОбъявлениеПеременнойМодуля() + +Функция РазобратьОбъявлениеСпискаЛокальныхПеременных(Переменные) + Перем ОбъявленияПеременных, ОбъявлениеПеременной, Объявление, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ОбъявленияПеременных = Новый Массив; + ОбъявлениеПеременной = РазобратьОбъявлениеЛокальнойПеременной(); + ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); + Переменные.Добавить(ОбъявлениеПеременной); + Пока Парсер_Токен = Токены.Запятая Цикл + СледующийТокен(); + ОбъявлениеПеременной = РазобратьОбъявлениеЛокальнойПеременной(); + ОбъявленияПеременных.Добавить(ОбъявлениеПеременной); + Переменные.Добавить(ОбъявлениеПеременной); + КонецЦикла; + Объявление = Парсер_Узлы.ОбъявлениеСпискаЛокальныхПеременных.Добавить(); + Объявление.Тип = Типы.ОбъявлениеСпискаЛокальныхПеременных; + Объявление.Объявления = ОбъявленияПеременных; + Объявление.Начало = Начало; + Объявление.Конец = Парсер_ДанныеПредыдущегоТокена; + Ожидать(Токены.ТочкаСЗапятой); + СледующийТокен(); + Пока Парсер_Токен = Токены.ТочкаСЗапятой Цикл + СледующийТокен(); + КонецЦикла; + Возврат Объявление; +КонецФункции // РазобратьОбъявлениеСпискаЛокальныхПеременных() + +Функция РазобратьОбъявлениеЛокальнойПеременной() + Перем Имя, ОбъявлениеЛокальнойПеременной, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Ожидать(Токены.Идентификатор); + Имя = Парсер_Литерал; + ОбъявлениеЛокальнойПеременной = Парсер_Узлы.ОбъявлениеЛокальнойПеременной.Добавить(); + ОбъявлениеЛокальнойПеременной.Тип = Типы.ОбъявлениеЛокальнойПеременной; + ОбъявлениеЛокальнойПеременной.Имя = Имя; + ОбъявлениеЛокальнойПеременной.Начало = Начало; + ОбъявлениеЛокальнойПеременной.Конец = Начало; + Если Парсер_Переменные.Свойство(Имя) Тогда + Ошибка(12, Имя, СтрогийРежим, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); + ЭлементОкружения.Тип = Типы.ЭлементОкружения; + ЭлементОкружения.Имя = Имя; + ЭлементОкружения.Объявление = ОбъявлениеЛокальнойПеременной;; + Парсер_Переменные.Вставить(Имя, ЭлементОкружения); + СледующийТокен(); + Возврат ОбъявлениеЛокальнойПеременной; +КонецФункции // РазобратьОбъявлениеЛокальнойПеременной() + +Функция РазобратьОбъявлениеМетода() + Перем Сигнатура, ЭлементОкружения, Имя, Переменные, Параметры, ЕстьЭкспорт, Операторы, Объявления, ОбъявлениеАвтоПеременной, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + ЕстьЭкспорт = Ложь; + СледующийТокен(); + Ожидать(Токены.Идентификатор); + Имя = Парсер_Литерал; + СледующийТокен(); + ОткрытьОкружение(); + Параметры = РазобратьПараметры(); + Если Парсер_Токен = Токены.Экспорт Тогда + ЕстьЭкспорт = Истина; + СледующийТокен(); + КонецЕсли; + Если Парсер_ЭтоФункция Тогда + Сигнатура = Парсер_Узлы.ОбъявлениеСигнатурыФункции.Добавить(); + Сигнатура.Тип = Типы.ОбъявлениеСигнатурыФункции; + Сигнатура.Имя = Имя; + Сигнатура.Директивы = Парсер_СписокДиректив; + Сигнатура.Аннотации = Парсер_СписокАннотаций; + Сигнатура.Параметры = Параметры; + Сигнатура.Экспорт = ЕстьЭкспорт; + Сигнатура.Асинх = Парсер_ЭтоАсинх; + Сигнатура.Начало = Начало; + Сигнатура.Конец = Парсер_ДанныеПредыдущегоТокена; + Иначе + Сигнатура = Парсер_Узлы.ОбъявлениеСигнатурыПроцедуры.Добавить(); + Сигнатура.Тип = Типы.ОбъявлениеСигнатурыПроцедуры; + Сигнатура.Имя = Имя; + Сигнатура.Директивы = Парсер_СписокДиректив; + Сигнатура.Аннотации = Парсер_СписокАннотаций; + Сигнатура.Параметры = Параметры; + Сигнатура.Экспорт = ЕстьЭкспорт; + Сигнатура.Асинх = Парсер_ЭтоАсинх; + Сигнатура.Начало = Начало; + Сигнатура.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЕсли; + Если Парсер_Неизвестные.Свойство(Имя, ЭлементОкружения) Тогда + Парсер_Неизвестные.Удалить(Имя); + ЭлементОкружения.Объявление = Сигнатура; + Иначе + ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); + ЭлементОкружения.Тип = Типы.ЭлементОкружения; + ЭлементОкружения.Имя = Имя; + ЭлементОкружения.Объявление = Сигнатура; + КонецЕсли; + Если НайтиМетод(Имя) <> Неопределено Тогда + Ошибка(13, Имя, СтрогийРежим, Парсер_Токены[Начало.Индекс + 1]); + КонецЕсли; + Парсер_Методы.Вставить(Имя, ЭлементОкружения); + Если ЕстьЭкспорт Тогда + Парсер_Интерфейс.Добавить(ЭлементОкружения); + КонецЕсли; + Объявления = Новый Массив; + Переменные = Новый Массив; + Пока Парсер_Токен = Токены.Перем Цикл + Объявления.Добавить(РазобратьОбъявлениеСпискаЛокальныхПеременных(Переменные)); + КонецЦикла; + Операторы = РазобратьОператоры(); + Если Парсер_ЭтоФункция Тогда + Ожидать(Токены.КонецФункции); + Иначе + Ожидать(Токены.КонецПроцедуры); + КонецЕсли; + Для Каждого ОбъявлениеАвтоПеременной Из Парсер_Окружение.АвтоПеременные Цикл + Переменные.Добавить(ОбъявлениеАвтоПеременной); + КонецЦикла; + ЗакрытьОкружение(); + СледующийТокен(); + Узел = Парсер_Узлы.ОбъявлениеМетода.Добавить(); + Узел.Тип = Типы.ОбъявлениеМетода; + Узел.Сигнатура = Сигнатура; + Узел.Переменные = Переменные; + Узел.Объявления = Объявления; + Узел.Операторы = Операторы; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОбъявлениеМетода() + +Функция РазобратьПараметры() + Перем Параметры; + Ожидать(Токены.ЛеваяКруглаяСкобка); + СледующийТокен(); + Если Парсер_Токен = Токены.ПраваяКруглаяСкобка Тогда + Параметры = ПустойМассив; + Иначе + Параметры = Новый Массив; + Параметры.Добавить(РазобратьОбъявлениеПараметра()); + Пока Парсер_Токен = Токены.Запятая Цикл + СледующийТокен(); + Параметры.Добавить(РазобратьОбъявлениеПараметра()); + КонецЦикла; + КонецЕсли; + Ожидать(Токены.ПраваяКруглаяСкобка); + СледующийТокен(); + Возврат Параметры; +КонецФункции // РазобратьПараметры() + +Функция РазобратьОбъявлениеПараметра() + Перем Имя, ОбъявлениеПараметра, ПоЗначению, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Если Парсер_Токен = Токены.Знач Тогда + ПоЗначению = Истина; + СледующийТокен(); + Иначе + ПоЗначению = Ложь; + КонецЕсли; + Ожидать(Токены.Идентификатор); + Имя = Парсер_Литерал; + Если СледующийТокен() = Токены.ЗнакРавно Тогда + СледующийТокен(); + ОбъявлениеПараметра = Парсер_Узлы.ОбъявлениеПараметра.Добавить(); + ОбъявлениеПараметра.Тип = Типы.ОбъявлениеПараметра; + ОбъявлениеПараметра.Имя = Имя; + ОбъявлениеПараметра.ПоЗначению = ПоЗначению; + ОбъявлениеПараметра.Значение = РазобратьВыражениеУнарное(); + ОбъявлениеПараметра.Начало = Начало; + ОбъявлениеПараметра.Конец = Парсер_ДанныеПредыдущегоТокена; + Иначе + ОбъявлениеПараметра = Парсер_Узлы.ОбъявлениеПараметра.Добавить(); + ОбъявлениеПараметра.Тип = Типы.ОбъявлениеПараметра; + ОбъявлениеПараметра.Имя = Имя; + ОбъявлениеПараметра.ПоЗначению = ПоЗначению; + ОбъявлениеПараметра.Значение = Неопределено; + ОбъявлениеПараметра.Начало = Начало; + ОбъявлениеПараметра.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЕсли; + Если Парсер_Переменные.Свойство(Имя) Тогда + Ошибка(12, Имя, СтрогийРежим, Начало); + КонецЕсли; + ЭлементОкружения = Парсер_Узлы.ЭлементОкружения.Добавить(); + ЭлементОкружения.Тип = Типы.ЭлементОкружения; + ЭлементОкружения.Имя = Имя; + ЭлементОкружения.Объявление = ОбъявлениеПараметра;; + Парсер_Переменные.Вставить(Имя, ЭлементОкружения); + Возврат ОбъявлениеПараметра; +КонецФункции // РазобратьОбъявлениеПараметра() + +#КонецОбласти // РазборОбъявлений + +#Область РазборОператоров + +Функция РазобратьОператоры() + Перем Операторы, Оператор; + Операторы = Новый Массив; + Оператор = РазобратьОператор(); + Если Оператор <> Неопределено Тогда + Операторы.Добавить(Оператор); + КонецЕсли; + Пока Истина Цикл + Если Парсер_Токен = Токены.ТочкаСЗапятой Тогда + СледующийТокен(); + ИначеЕсли Лев(Парсер_Токен, 1) <> "_" Тогда // если не препроцессор + Прервать; + КонецЕсли; + Оператор = РазобратьОператор(); + Если Оператор <> Неопределено Тогда + Операторы.Добавить(Оператор); + КонецЕсли; + КонецЦикла; + Возврат Операторы; +КонецФункции // РазобратьОператоры() + +Функция РазобратьОператор() + Перем Оператор; + Если Парсер_Токен = Токены.Идентификатор Тогда + Оператор = РазобратьОператорПрисваиванияИлиВызоваПроцедуры(); + ИначеЕсли Парсер_Токен = Токены.Если Тогда + Оператор = РазобратьОператорЕсли(); + ИначеЕсли Парсер_Токен = Токены.Попытка Тогда + Оператор = РазобратьОператорПопытка(); + ИначеЕсли Парсер_Токен = Токены.Пока Тогда + Оператор = РазобратьОператорПока(); + ИначеЕсли Парсер_Токен = Токены.Для Тогда + Если СледующийТокен() = Токены.Каждого Тогда + Оператор = РазобратьОператорДляКаждого(); + Иначе + Оператор = РазобратьОператорДля(); + КонецЕсли; + ИначеЕсли Парсер_Токен = Токены.Возврат Тогда + Оператор = РазобратьОператорВозврат(); + ИначеЕсли Парсер_Токен = Токены.Прервать Тогда + Оператор = РазобратьОператорПрервать(); + ИначеЕсли Парсер_Токен = Токены.Продолжить Тогда + Оператор = РазобратьОператорПродолжить(); + ИначеЕсли Парсер_Токен = Токены.ВызватьИсключение Тогда + Оператор = РазобратьОператорВызватьИсключение(); + ИначеЕсли Парсер_Токен = Токены.Выполнить Тогда + Оператор = РазобратьОператорВыполнить(); + ИначеЕсли Парсер_Токен = Токены.Перейти Тогда + Оператор = РазобратьОператорПерейти(); + ИначеЕсли Парсер_Токен = Токены.Метка Тогда + Оператор = РазобратьОператорМетка(); + ИначеЕсли Парсер_Токен = Токены.ДобавитьОбработчик Тогда + Оператор = РазобратьОператорДобавитьОбработчик(); + ИначеЕсли Парсер_Токен = Токены.УдалитьОбработчик Тогда + Оператор = РазобратьОператорУдалитьОбработчик(); + ИначеЕсли Парсер_Токен = Токены._Область Тогда + Оператор = РазобратьИнструкциюПрепроцессораОбласть(); + ИначеЕсли Парсер_Токен = Токены._КонецОбласти Тогда + Оператор = РазобратьИнструкциюПрепроцессораКонецОбласти(); + ИначеЕсли Парсер_Токен = Токены._Если Тогда + Оператор = РазобратьИнструкциюПрепроцессораЕсли(); + ИначеЕсли Парсер_Токен = Токены._ИначеЕсли Тогда + Оператор = РазобратьИнструкциюПрепроцессораИначеЕсли(); + ИначеЕсли Парсер_Токен = Токены._Иначе Тогда + Оператор = РазобратьИнструкциюПрепроцессораИначе(); + ИначеЕсли Парсер_Токен = Токены._КонецЕсли Тогда + Оператор = РазобратьИнструкциюПрепроцессораКонецЕсли(); + ИначеЕсли Парсер_Токен = Токены._Вставка Тогда + Оператор = РазобратьИнструкциюПрепроцессораВставка(); + ИначеЕсли Парсер_Токен = Токены._КонецВставки Тогда + Оператор = РазобратьИнструкциюПрепроцессораКонецВставки(); + ИначеЕсли Парсер_Токен = Токены._Удаление Тогда + Оператор = РазобратьИнструкциюПрепроцессораУдаление(); + ИначеЕсли Парсер_Токен = Токены._КонецУдаления Тогда + Оператор = РазобратьИнструкциюПрепроцессораКонецУдаления(); + ИначеЕсли Парсер_Токен = Токены.ТочкаСЗапятой Тогда + // NOP + КонецЕсли; + Возврат Оператор; +КонецФункции // РазобратьОператор() + +Функция РазобратьОператорВызватьИсключение() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Если ТокеныНачалаВыражения.Найти(СледующийТокен()) <> Неопределено Тогда + Выражение = РазобратьВыражение(); + КонецЕсли; + Узел = Парсер_Узлы.ОператорВызватьИсключение.Добавить(); + Узел.Тип = Типы.ОператорВызватьИсключение; + Узел.Выражение = Выражение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорВызватьИсключение() + +Функция РазобратьОператорВыполнить() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Узел = Парсер_Узлы.ОператорВыполнить.Добавить(); + Узел.Тип = Типы.ОператорВыполнить; + Узел.Выражение = РазобратьВыражение(); + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорВыполнить() + +Функция РазобратьОператорПрисваиванияИлиВызоваПроцедуры() + Перем ЛевыйОперанд, ЭтоВызов, ПравыйОперанд, Оператор, НоваяПеременная, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + ЛевыйОперанд = РазобратьВыражениеИдентификатор(Истина, НоваяПеременная, ЭтоВызов); + Если ЭтоВызов Тогда + Оператор = Парсер_Узлы.ОператорВызоваПроцедуры.Добавить(); + Оператор.Тип = Типы.ОператорВызоваПроцедуры; + Оператор.Идентификатор = ЛевыйОперанд; + Оператор.Начало = Начало; + Оператор.Конец = Парсер_ДанныеПредыдущегоТокена; + Иначе + Ожидать(Токены.ЗнакРавно); + СледующийТокен(); + ПравыйОперанд = РазобратьВыражение(); + Если НоваяПеременная <> Неопределено Тогда + Парсер_Переменные.Вставить(НоваяПеременная.Имя, НоваяПеременная); + Парсер_Окружение.АвтоПеременные.Добавить(НоваяПеременная.Объявление); + КонецЕсли; + Оператор = Парсер_Узлы.ОператорПрисваивания.Добавить(); + Оператор.Тип = Типы.ОператорПрисваивания; + Оператор.ЛевыйОперанд = ЛевыйОперанд; + Оператор.ПравыйОперанд = ПравыйОперанд; + Оператор.Начало = Начало; + Оператор.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЕсли; + Возврат Оператор; +КонецФункции // РазобратьОператорПрисваиванияИлиВызоваПроцедуры() + +Функция РазобратьОператорЕсли() + Перем Выражение, ТогдаОператоры, ОператорИначе, СписокИначеЕсли, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Выражение = РазобратьВыражение(); + Ожидать(Токены.Тогда); + СледующийТокен(); + ТогдаОператоры = РазобратьОператоры(); + Если Парсер_Токен = Токены.ИначеЕсли Тогда + СписокИначеЕсли = Новый Массив; + Пока Парсер_Токен = Токены.ИначеЕсли Цикл + СписокИначеЕсли.Добавить(РазобратьОператорИначеЕсли()); + КонецЦикла; + КонецЕсли; + Если Парсер_Токен = Токены.Иначе Тогда + ОператорИначе = РазобратьОператорИначе(); + КонецЕсли; + Ожидать(Токены.КонецЕсли); + СледующийТокен(); + Узел = Парсер_Узлы.ОператорЕсли.Добавить(); + Узел.Тип = Типы.ОператорЕсли; + Узел.Выражение = Выражение; + Узел.Тогда = ТогдаОператоры; + Узел.ИначеЕсли = СписокИначеЕсли; + Узел.Иначе = ОператорИначе; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорЕсли() + +Функция РазобратьОператорИначеЕсли() + Перем ЕслиВыражение, ТогдаОператоры, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЕслиВыражение = РазобратьВыражение(); + Ожидать(Токены.Тогда); + СледующийТокен(); + ТогдаОператоры = РазобратьОператоры(); + Узел = Парсер_Узлы.ОператорИначеЕсли.Добавить(); + Узел.Тип = Типы.ОператорИначеЕсли; + Узел.Выражение = ЕслиВыражение; + Узел.Тогда = ТогдаОператоры; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорИначеЕсли() + +Функция РазобратьОператорИначе() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Узел = Парсер_Узлы.ОператорИначе.Добавить(); + Узел.Тип = Типы.ОператорИначе; + Узел.Операторы = РазобратьОператоры(); + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорИначе() + +Функция РазобратьОператорПопытка() + Перем Операторы, ОператорИсключение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Операторы = РазобратьОператоры(); + Ожидать(Токены.Исключение); + ОператорИсключение = РазобратьОператорИсключение(); + Ожидать(Токены.КонецПопытки); + СледующийТокен(); + Узел = Парсер_Узлы.ОператорПопытка.Добавить(); + Узел.Тип = Типы.ОператорПопытка; + Узел.Попытка = Операторы; + Узел.Исключение = ОператорИсключение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорПопытка() + +Функция РазобратьОператорИсключение() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Узел = Парсер_Узлы.ОператорИсключение.Добавить(); + Узел.Тип = Типы.ОператорИсключение; + Узел.Операторы = РазобратьОператоры(); + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорИсключение() + +Функция РазобратьОператорПока() + Перем Выражение, Операторы, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Выражение = РазобратьВыражение(); + Ожидать(Токены.Цикл); + СледующийТокен(); + Операторы = РазобратьОператоры(); + Ожидать(Токены.КонецЦикла); + СледующийТокен(); + Узел = Парсер_Узлы.ОператорПока.Добавить(); + Узел.Тип = Типы.ОператорПока; + Узел.Выражение = Выражение; + Узел.Операторы = Операторы; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорПока() + +Функция РазобратьОператорДля() + Перем ВыражениеИдентификатор, ЭтоВызов, Начало, Операторы, ИндексТокенаПеременной, НоваяПеременная, Старт, Финиш; + Начало = Парсер_ДанныеПредыдущегоТокена; + Ожидать(Токены.Идентификатор); + ИндексТокенаПеременной = Парсер_ДанныеТекущегоТокена; + ВыражениеИдентификатор = РазобратьВыражениеИдентификатор(Истина, НоваяПеременная, ЭтоВызов); + Если ЭтоВызов Тогда + Ошибка(14, Неопределено, Истина, ИндексТокенаПеременной); + КонецЕсли; + Ожидать(Токены.ЗнакРавно); + СледующийТокен(); + Старт = РазобратьВыражение(); + Ожидать(Токены.По); + СледующийТокен(); + Финиш = РазобратьВыражение(); + Если НоваяПеременная <> Неопределено Тогда + Парсер_Переменные.Вставить(НоваяПеременная.Имя, НоваяПеременная); + Парсер_Окружение.АвтоПеременные.Добавить(НоваяПеременная.Объявление); + КонецЕсли; + Ожидать(Токены.Цикл); + СледующийТокен(); + Операторы = РазобратьОператоры(); + Ожидать(Токены.КонецЦикла); + СледующийТокен(); + Узел = Парсер_Узлы.ОператорДля.Добавить(); + Узел.Тип = Типы.ОператорДля; + Узел.Идентификатор = ВыражениеИдентификатор; + Узел.Старт = Старт; + Узел.Финиш = Финиш; + Узел.Операторы = Операторы; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорДля() + +Функция РазобратьОператорДляКаждого() + Перем ВыражениеИдентификатор, ЭтоВызов, Коллекция, Операторы, ИндексТокенаПеременной, НоваяПеременная, Начало; + Начало = Парсер_ДанныеПредыдущегоТокена; + СледующийТокен(); + Ожидать(Токены.Идентификатор); + ИндексТокенаПеременной = Парсер_ДанныеТекущегоТокена; + ВыражениеИдентификатор = РазобратьВыражениеИдентификатор(Истина, НоваяПеременная, ЭтоВызов); + Если ЭтоВызов Тогда + Ошибка(14, Неопределено, Истина, ИндексТокенаПеременной); + КонецЕсли; + Ожидать(Токены.Из); + СледующийТокен(); + Коллекция = РазобратьВыражение(); + Если НоваяПеременная <> Неопределено Тогда + Парсер_Переменные.Вставить(НоваяПеременная.Имя, НоваяПеременная); + Парсер_Окружение.АвтоПеременные.Добавить(НоваяПеременная.Объявление); + КонецЕсли; + Ожидать(Токены.Цикл); + СледующийТокен(); + Операторы = РазобратьОператоры(); + Ожидать(Токены.КонецЦикла); + СледующийТокен(); + Узел = Парсер_Узлы.ОператорДляКаждого.Добавить(); + Узел.Тип = Типы.ОператорДляКаждого; + Узел.Идентификатор = ВыражениеИдентификатор; + Узел.Коллекция = Коллекция; + Узел.Операторы = Операторы; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорДляКаждого() + +Функция РазобратьОператорПерейти() + Перем Метка, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Ожидать(Токены.Метка); + Метка = Парсер_Литерал; + СледующийТокен(); + Узел = Парсер_Узлы.ОператорПерейти.Добавить(); + Узел.Тип = Типы.ОператорПерейти; + Узел.Метка = Метка; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорПерейти() + +Функция РазобратьОператорВозврат() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Если Парсер_ЭтоФункция Тогда + Выражение = РазобратьВыражение(); + КонецЕсли; + Узел = Парсер_Узлы.ОператорВозврат.Добавить(); + Узел.Тип = Типы.ОператорВозврат; + Узел.Выражение = Выражение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорВозврат() + +Функция РазобратьОператорПрервать() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Узел = Парсер_Узлы.ОператорПрервать.Добавить(); + Узел.Тип = Типы.ОператорПрервать; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорПрервать() + +Функция РазобратьОператорПродолжить() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Узел = Парсер_Узлы.ОператорПродолжить.Добавить(); + Узел.Тип = Типы.ОператорПродолжить; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорПродолжить() + +Функция РазобратьОператорМетка() + Перем Метка, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Метка = Парсер_Литерал; + СледующийТокен(); + Ожидать(Токены.Двоеточие); + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ОператорМетка.Добавить(); + Узел.Тип = Типы.ОператорМетка; + Узел.Метка = Метка; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорМетка() + +Функция РазобратьОператорДобавитьОбработчик() + Перем Событие, ОбработчикСобытия, ЭтоВызов, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Ожидать(Токены.Идентификатор); + Событие = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); + Если ЭтоВызов Тогда + Ошибка(15, Неопределено, Истина, Начало); + КонецЕсли; + Ожидать(Токены.Запятая); + СледующийТокен(); + Ожидать(Токены.Идентификатор); + ОбработчикСобытия = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); + Если ЭтоВызов Тогда + Ошибка(16, Неопределено, Истина, Начало); + КонецЕсли; + Узел = Парсер_Узлы.ОператорДобавитьОбработчик.Добавить(); + Узел.Тип = Типы.ОператорДобавитьОбработчик; + Узел.Событие = Событие; + Узел.ОбработчикСобытия = ОбработчикСобытия; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорДобавитьОбработчик() + +Функция РазобратьОператорУдалитьОбработчик() + Перем Событие, ОбработчикСобытия, ЭтоВызов, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Ожидать(Токены.Идентификатор); + Событие = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); + Если ЭтоВызов Тогда + Ошибка(15, Неопределено, Истина, Начало); + КонецЕсли; + Ожидать(Токены.Запятая); + СледующийТокен(); + Ожидать(Токены.Идентификатор); + ОбработчикСобытия = РазобратьВыражениеИдентификатор(Ложь, Неопределено, ЭтоВызов); + Если ЭтоВызов Тогда + Ошибка(16, Неопределено, Истина, Начало); + КонецЕсли; + Узел = Парсер_Узлы.ОператорУдалитьОбработчик.Добавить(); + Узел.Тип = Типы.ОператорУдалитьОбработчик; + Узел.Событие = Событие; + Узел.ОбработчикСобытия = ОбработчикСобытия; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьОператорУдалитьОбработчик() + +#КонецОбласти // РазборОператоров + +#Область РазборПрепроцессора + + // Выражения + +Функция РазобратьВыражениеПрепроцессора() + Перем Выражение, Операция, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Выражение = РазобратьВыражениеПрепроцессораИ(); + Пока Парсер_Токен = Токены.Или Цикл + Операция = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЛевыйОперанд = Выражение; + Выражение = Парсер_Узлы.ВыражениеПрепроцессораБинарное.Добавить(); + Выражение.Тип = Типы.ВыражениеПрепроцессораБинарное; + Выражение.ЛевыйОперанд = ЛевыйОперанд; + Выражение.Операция = Операция; + Выражение.ПравыйОперанд = РазобратьВыражениеПрепроцессораИ(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЦикла; + Возврат Выражение; +КонецФункции // РазобратьВыражениеПрепроцессора() + +Функция РазобратьВыражениеПрепроцессораИ() + Перем Выражение, Операция, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Выражение = РазобратьВыражениеПрепроцессораНе(); + Пока Парсер_Токен = Токены.И Цикл + Операция = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + ЛевыйОперанд = Выражение; + Выражение = Парсер_Узлы.ВыражениеПрепроцессораБинарное.Добавить(); + Выражение.Тип = Типы.ВыражениеПрепроцессораБинарное; + Выражение.ЛевыйОперанд = ЛевыйОперанд; + Выражение.Операция = Операция; + Выражение.ПравыйОперанд = РазобратьВыражениеПрепроцессораНе(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + КонецЦикла; + Возврат Выражение; +КонецФункции // РазобратьВыражениеПрепроцессораИ() + +Функция РазобратьВыражениеПрепроцессораНе() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Если Парсер_Токен = Токены.Не Тогда + СледующийТокен(); + Выражение = Парсер_Узлы.ВыражениеПрепроцессораНе.Добавить(); + Выражение.Тип = Типы.ВыражениеПрепроцессораНе; + Выражение.Выражение = РазобратьВыражениеПрепроцессораОперанд(); + Выражение.Начало = Начало; + Выражение.Конец = Парсер_ДанныеПредыдущегоТокена; + Иначе + Выражение = РазобратьВыражениеПрепроцессораОперанд(); + КонецЕсли; + Возврат Выражение; +КонецФункции // РазобратьВыражениеПрепроцессораНе() + +Функция РазобратьВыражениеПрепроцессораОперанд() + Перем Операнд; + Если Парсер_Токен = Токены.Идентификатор Тогда + Операнд = РазобратьВыражениеПрепроцессораСимвол(); + ИначеЕсли Парсер_Токен = Токены.ЛеваяКруглаяСкобка Тогда + Операнд = РазобратьВыражениеПрепроцессораСкобочное(); + Иначе + Ошибка(7, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + Возврат Операнд; +КонецФункции + +Функция РазобратьВыражениеПрепроцессораСимвол() + Перем Символ, СимволСуществует; + СимволСуществует = СимволыПрепроцессора.Свойство(Парсер_Литерал); + Символ = Парсер_Узлы.ВыражениеПрепроцессораСимвол.Добавить(); + Символ.Тип = Типы.ВыражениеПрепроцессораСимвол; + Символ.Символ = Парсер_Литерал; + Символ.Существует = СимволСуществует; + Символ.Начало = Парсер_ДанныеТекущегоТокена; + Символ.Конец = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Возврат Символ; +КонецФункции // РазобратьВыражениеПрепроцессораСимвол() + +Функция РазобратьВыражениеПрепроцессораСкобочное() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Выражение = РазобратьВыражениеПрепроцессора(); + Ожидать(Токены.ПраваяКруглаяСкобка); + СледующийТокен(); + Узел = Парсер_Узлы.ВыражениеПрепроцессораСкобочное.Добавить(); + Узел.Тип = Типы.ВыражениеПрепроцессораСкобочное; + Узел.Выражение = Выражение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьВыражениеПрепроцессораСкобочное() + +// Инструкции + +Функция РазобратьИнструкциюПрепроцессораЕсли() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Выражение = РазобратьВыражениеПрепроцессора(); + Ожидать(Токены.Тогда); + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораЕсли.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораЕсли; + Узел.Выражение = Выражение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораЕсли() + +Функция РазобратьИнструкциюПрепроцессораИначеЕсли() + Перем Выражение, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Выражение = РазобратьВыражениеПрепроцессора(); + Ожидать(Токены.Тогда); + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораИначеЕсли.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораИначеЕсли; + Узел.Выражение = Выражение; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеПредыдущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораИначеЕсли() + +Функция РазобратьИнструкциюПрепроцессораИначе() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораИначе.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораИначе; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораИначе() + +Функция РазобратьИнструкциюПрепроцессораКонецЕсли() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецЕсли.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораКонецЕсли; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораКонецЕсли() + +Функция РазобратьИнструкциюПрепроцессораОбласть() + Перем Имя, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Ожидать(Токены.Идентификатор); + Имя = Парсер_Литерал; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораОбласть.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораОбласть; + Узел.Имя = Имя; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораОбласть() + +Функция РазобратьИнструкциюПрепроцессораКонецОбласти() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецОбласти.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораКонецОбласти; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораКонецОбласти() + +Функция РазобратьИнструкциюПрепроцессораВставка() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораВставка.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораВставка; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораВставка() + +Функция РазобратьИнструкциюПрепроцессораКонецВставки() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецВставки.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораКонецВставки; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораКонецВставки() + +Функция РазобратьИнструкциюПрепроцессораУдаление() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораУдаление.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораУдаление; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораУдаление() + +Функция РазобратьИнструкциюПрепроцессораКонецУдаления() + Перем Начало; + Начало = Парсер_ДанныеТекущегоТокена; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораКонецУдаления.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораКонецУдаления; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораКонецУдаления() + +Функция РазобратьИнструкциюПрепроцессораИспользовать() + Перем Путь, Начало; + Начало = Парсер_ДанныеТекущегоТокена; + СледующийТокен(); + Если Парсер_НомерТекущейСтроки <> Начало.НомерСтроки Тогда + Ошибка(20, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + Если Парсер_Токен = Токены.Число Тогда + Путь = Парсер_Литерал; + Если КартаБуквЦифр[Парсер_Символ] = Буква Тогда + СледующийТокен(); + Путь = Путь + Парсер_Литерал; + КонецЕсли; + ИначеЕсли Парсер_Токен = Токены.Идентификатор + Или Парсер_Токен = Токены.Строка Тогда + Путь = Парсер_Литерал; + Иначе + Ошибка(20, Неопределено, Истина, Парсер_ДанныеТекущегоТокена); + КонецЕсли; + Парсер_Токен = Токены.ТочкаСЗапятой; // уловка + Узел = Парсер_Узлы.ИнструкцияПрепроцессораИспользовать.Добавить(); + Узел.Тип = Типы.ИнструкцияПрепроцессораИспользовать; + Узел.Путь = Путь; + Узел.Начало = Начало; + Узел.Конец = Парсер_ДанныеТекущегоТокена; + Возврат Узел; +КонецФункции // РазобратьИнструкциюПрепроцессораИспользовать() + +#КонецОбласти // РазборПрепроцессора + +#КонецОбласти // Парсер + +#Область СлужебныеМетоды + +Функция Доступность(Клиент, ВнешнееСоединение, МобильноеПриложение, МобильныйКлиент, МобильныйСервер, Сервер, ТолстыйКлиент, ТонкийКлиент, ВебКлиент, Интеграция) Экспорт + Возврат Новый Структура( + "Клиент, ВнешнееСоединение, МобильноеПриложение, МобильныйКлиент, МобильныйСервер, Сервер, ТолстыйКлиент, ТонкийКлиент, ВебКлиент, Интеграция", + Клиент, ВнешнееСоединение, МобильноеПриложение, МобильныйКлиент, МобильныйСервер, Сервер, ТолстыйКлиент, ТонкийКлиент, ВебКлиент, Интеграция + ); +КонецФункции + +Функция КакДата(ЛитералДаты) + Перем Список, Символ, Позиция, ДатаСтрокой, Дата; + Список = Новый Массив; + Для Позиция = 1 По СтрДлина(ЛитералДаты) Цикл + Символ = Сред(ЛитералДаты, Позиция, 1); + Если КартаБуквЦифр[Символ] = Цифра Тогда + Список.Добавить(Символ); + КонецЕсли; + КонецЦикла; + ДатаСтрокой = СтрСоединить(Список); + Если ДатаСтрокой = "00000000" + Или ДатаСтрокой = "000000000000" + Или ДатаСтрокой = "00000000000000" Тогда + Возврат '00010101'; + КонецЕсли; + Попытка + Дата = Дата(ДатаСтрокой); + Исключение + Ошибка(18, ЛитералДаты, Истина); + КонецПопытки; + Возврат Дата; +КонецФункции // КакДата() + +Процедура Ожидать(Токен) + Если Парсер_Токен <> Токен Тогда + Ошибка(1, Токен, Истина, Парсер_ДанныеТекущегоТокена); + КонецЕсли; +КонецПроцедуры // Ожидать() + +Процедура Ошибка(Код, Аргумент, Остановить, Начало = Неопределено, Конец = Неопределено) + Перем Ошибка, ТокенНачала, ТокенКонца; + Ошибка = Парсер_Ошибки.Добавить(); + Ошибка.Источник = "ПарсерВстроенногоЯзыка"; + Ошибка.Код = Код; + Ошибка.Текст = Ошибки[Код] + ?(Аргумент = Неопределено, "", ": " + Аргумент); + Если Начало = Неопределено Тогда + ТокенНачала = Новый Структура; + ТокенНачала.Вставить("Токен", Неопределено); + ТокенНачала.Вставить("НомерСтроки", Парсер_НомерТекущейСтроки); + ТокенНачала.Вставить("НомерКолонки", Парсер_ПозицияНачалаТокена - Парсер_ПозицияТекущейСтроки); + ТокенНачала.Вставить("Позиция", Парсер_ПозицияНачалаТокена); + ТокенНачала.Вставить("Длина", Парсер_ТекущаяПозиция - Парсер_ПозицияНачалаТокена); + Иначе + ТокенНачала = Начало; + КонецЕсли; + Если Конец = Неопределено Тогда + ТокенКонца = ТокенНачала; + Иначе + ТокенКонца = Конец; + КонецЕсли; + Ошибка.ПозицияНачала = Мин(ТокенНачала.Позиция, Парсер_ДлинаИсходника); + Ошибка.НомерСтрокиНачала = ТокенНачала.НомерСтроки; + Ошибка.НомерКолонкиНачала = ТокенНачала.НомерКолонки; + Ошибка.ПозицияКонца = Мин(ТокенКонца.Позиция + ТокенКонца.Длина, Парсер_ДлинаИсходника + 1); + Ошибка.НомерСтрокиКонца = ТокенКонца.НомерСтроки; + Ошибка.НомерКолонкиКонца = ТокенКонца.НомерКолонки; + Если Остановить Тогда + ВызватьИсключение Ошибка.Текст; + КонецЕсли; +КонецПроцедуры // Ошибка() + +#КонецОбласти // СлужебныеМетоды + +#Область Посетитель + +Процедура Подключить(Знач Плагины) Экспорт + Перем Плагин, Список, ИмяПроцедуры; + Если ТипЗнч(Плагины) <> Тип("Массив") Тогда + Плагин = Плагины; + Плагины = Новый Массив; + Плагины.Добавить(Плагин); + КонецЕсли; + Посетитель_Плагины = Плагины; + Посетитель_Подписки = Подписки(); + Для Каждого Плагин Из Плагины Цикл + Список = Неопределено; + Для Каждого ИмяПроцедуры Из Плагин.Подписки() Цикл + Если Посетитель_Подписки.Свойство(ИмяПроцедуры, Список) Тогда + Список.Добавить(Плагин); + КонецЕсли; + КонецЦикла; + КонецЦикла; +КонецПроцедуры // Подключить() + +Функция Стек() Экспорт + Возврат Посетитель_Стек; +КонецФункции + +Функция Счетчики() Экспорт + Возврат Посетитель_Счетчики; +КонецФункции + +Процедура ДобавитьНаСтек(Узел) + Посетитель_Стек.Добавить(Узел); + Посетитель_Счетчики[Узел.Тип] = Посетитель_Счетчики[Узел.Тип] + 1; +КонецПроцедуры // ДобавитьНаСтек() + +Процедура УдалитьСоСтека() + Перем Узел, Вершина; + Вершина = Посетитель_Стек.ВГраница(); + Узел = Посетитель_Стек[Вершина]; + Посетитель_Счетчики[Узел.Тип] = Посетитель_Счетчики[Узел.Тип] - 1; + Посетитель_Стек.Удалить(Вершина); +КонецПроцедуры // УдалитьСоСтека() + +Функция Подписки() + Перем Подписки, Элемент; + + Подписки = Новый Структура( + "ПосетитьМодуль, ПокинутьМодуль," + "ПосетитьОбъявления, ПокинутьОбъявления," + "ПосетитьОператоры, ПокинутьОператоры," + "ПосетитьОбъявлениеСпискаПеременныхМодуля, ПокинутьОбъявлениеСпискаПеременныхМодуля," + "ПосетитьОбъявлениеПеременнойМодуля, ПокинутьОбъявлениеПеременнойМодуля," + "ПосетитьОбъявлениеСпискаЛокальныхПеременных, ПокинутьОбъявлениеСпискаЛокальныхПеременных," + "ПосетитьОбъявлениеЛокальнойПеременной, ПокинутьОбъявлениеЛокальнойПеременной," + "ПосетитьОбъявлениеПараметра, ПокинутьОбъявлениеПараметра," + "ПосетитьОбъявлениеМетода, ПокинутьОбъявлениеМетода," + "ПосетитьСигнатуру, ПокинутьСигнатуру," + "ПосетитьВыражение, ПокинутьВыражение," // вызываются один раз для корня выражения + "ПосетитьВыражениеЛитерал, ПокинутьВыражениеЛитерал," + "ПосетитьВыражениеИдентификатор, ПокинутьВыражениеИдентификатор," + "ПосетитьВыражениеУнарное, ПокинутьВыражениеУнарное," + "ПосетитьВыражениеБинарное, ПокинутьВыражениеБинарное," + "ПосетитьВыражениеНовый, ПокинутьВыражениеНовый," + "ПосетитьВыражениеТернарное, ПокинутьВыражениеТернарное," + "ПосетитьВыражениеСкобочное, ПокинутьВыражениеСкобочное," + "ПосетитьВыражениеНе, ПокинутьВыражениеНе," + "ПосетитьВыражениеСтроковое, ПокинутьВыражениеСтроковое," + "ПосетитьОператорПрисваивания, ПокинутьОператорПрисваивания," + "ПосетитьОператорВозврат, ПокинутьОператорВозврат," + "ПосетитьОператорПрервать, ПокинутьОператорПрервать," + "ПосетитьОператорПродолжить, ПокинутьОператорПродолжить," + "ПосетитьОператорВызватьИсключение, ПокинутьОператорВызватьИсключение," + "ПосетитьОператорВыполнить, ПокинутьОператорВыполнить," + "ПосетитьОператорВызоваПроцедуры, ПокинутьОператорВызоваПроцедуры," + "ПосетитьОператорЕсли, ПокинутьОператорЕсли," + "ПосетитьОператорИначеЕсли, ПокинутьОператорИначеЕсли," + "ПосетитьОператорИначе, ПокинутьОператорИначе," + "ПосетитьОператорПока, ПокинутьОператорПока," + "ПосетитьОператорДля, ПокинутьОператорДля," + "ПосетитьОператорДляКаждого, ПокинутьОператорДляКаждого," + "ПосетитьОператорПопытка, ПокинутьОператорПопытка," + "ПосетитьОператорИсключение, ПокинутьОператорИсключение," + "ПосетитьОператорПерейти, ПокинутьОператорПерейти," + "ПосетитьОператорМетка, ПокинутьОператорМетка," + "ПосетитьОператорДобавитьОбработчик, ПокинутьОператорДобавитьОбработчик," + "ПосетитьОператорУдалитьОбработчик, ПокинутьОператорУдалитьОбработчик," + "ПосетитьИнструкциюПрепроцессора, ПокинутьИнструкциюПрепроцессора," + "ПосетитьВыражениеПрепроцессора, ПокинутьВыражениеПрепроцессора," + "ПосетитьВыражениеПрепроцессораБинарное, ПокинутьВыражениеПрепроцессораБинарное," + "ПосетитьВыражениеПрепроцессораНе, ПокинутьВыражениеПрепроцессораНе," + "ПосетитьВыражениеПрепроцессораСимвол, ПокинутьВыражениеПрепроцессораСимвол," + "ПосетитьВыражениеПрепроцессораСкобочное, ПокинутьВыражениеПрепроцессораСкобочное" + ); + + Для Каждого Элемент Из Подписки Цикл + Подписки[Элемент.Ключ] = Новый Массив; + КонецЦикла; + + Возврат Подписки; +КонецФункции // Подписки() + +Процедура Посетить(Модуль, Параметры = Неопределено) Экспорт + Перем Плагин, Подписка, Элемент, ПараметрыПлагина; + Если Параметры = Неопределено Тогда + Параметры = Новый Соответствие; + КонецЕсли; + Посетитель_Стек = Новый Массив; + Посетитель_Счетчики = Новый Структура; + Для Каждого Элемент Из Типы Цикл + Посетитель_Счетчики.Вставить(Элемент.Ключ, 0); + КонецЦикла; + Для Каждого Плагин Из Посетитель_Плагины Цикл + Попытка + // 1С - на платформе обработка не может быть ключом соответствия, но свойство ЭтотОбъект может + // ¯\_(ツ)_/¯ + ПараметрыПлагина = Параметры[Плагин.ЭтотОбъект]; + Исключение + // onescript + ПараметрыПлагина = Параметры[Плагин]; + КонецПопытки; + Плагин.Открыть(ЭтотОбъект, ПараметрыПлагина); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьМодуль Цикл + Подписка.ПосетитьМодуль(Модуль); + КонецЦикла; + ДобавитьНаСтек(Модуль); + ПосетитьОбъявления(Модуль.Объявления); + ПосетитьОператоры(Модуль.Операторы); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьМодуль Цикл + Подписка.ПокинутьМодуль(Модуль); + КонецЦикла; +КонецПроцедуры // Посетить() + +Процедура ПосетитьОбъявления(Объявления) + Перем Объявление, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявления Цикл + Подписка.ПосетитьОбъявления(Объявления); + КонецЦикла; + Для Каждого Объявление Из Объявления Цикл + ПосетитьОбъявлениеПоТипу(Объявление); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявления Цикл + Подписка.ПокинутьОбъявления(Объявления); + КонецЦикла; +КонецПроцедуры // ПосетитьОбъявления() + +Процедура ПосетитьОператоры(Операторы) + Перем Оператор, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператоры Цикл + Подписка.ПосетитьОператоры(Операторы); + КонецЦикла; + Для Каждого Оператор Из Операторы Цикл + ПосетитьОператорПоТипу(Оператор); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператоры Цикл + Подписка.ПокинутьОператоры(Операторы); + КонецЦикла; +КонецПроцедуры // ПосетитьОператоры() + +#Область ПосещениеОбъявлений + +Процедура ПосетитьОбъявлениеПоТипу(Объявление) + Перем Тип; + Тип = Объявление.Тип; + Если Тип = Типы.ОбъявлениеСпискаПеременныхМодуля Тогда + ПосетитьОбъявлениеСпискаПеременныхМодуля(Объявление); + ИначеЕсли Тип = Типы.ОбъявлениеЛокальнойПеременной Тогда + ПосетитьОбъявлениеЛокальнойПеременной(Объявление); + ИначеЕсли Тип = Типы.ОбъявлениеМетода Тогда + ПосетитьОбъявлениеМетода(Объявление); + ИначеЕсли Тип = Типы.ИнструкцияПрепроцессораОбласть + Или Тип = Типы.ИнструкцияПрепроцессораКонецОбласти + Или Тип = Типы.ИнструкцияПрепроцессораЕсли + Или Тип = Типы.ИнструкцияПрепроцессораИначеЕсли + Или Тип = Типы.ИнструкцияПрепроцессораИначе + Или Тип = Типы.ИнструкцияПрепроцессораКонецЕсли + Или Тип = Типы.ИнструкцияПрепроцессораИспользовать Тогда + ПосетитьИнструкциюПрепроцессора(Объявление); + КонецЕсли; +КонецПроцедуры // ПосетитьОбъявлениеПоТипу() + +Процедура ПосетитьОбъявлениеСпискаПеременныхМодуля(ОбъявлениеСпискаПеременныхМодуля) + Перем Подписка, ОбъявлениеПеременнойМодуля; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеСпискаПеременныхМодуля Цикл + Подписка.ПосетитьОбъявлениеСпискаПеременныхМодуля(ОбъявлениеСпискаПеременныхМодуля); + КонецЦикла; + ДобавитьНаСтек(ОбъявлениеСпискаПеременныхМодуля); + Для Каждого ОбъявлениеПеременнойМодуля Из ОбъявлениеСпискаПеременныхМодуля.Объявления Цикл + ПосетитьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля); + КонецЦикла; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеСпискаПеременныхМодуля Цикл + Подписка.ПокинутьОбъявлениеСпискаПеременныхМодуля(ОбъявлениеСпискаПеременныхМодуля); + КонецЦикла; +КонецПроцедуры // ПосетитьОбъявлениеСпискаПеременныхМодуля() + +Процедура ПосетитьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеПеременнойМодуля Цикл + Подписка.ПосетитьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеПеременнойМодуля Цикл + Подписка.ПокинутьОбъявлениеПеременнойМодуля(ОбъявлениеПеременнойМодуля); + КонецЦикла; +КонецПроцедуры // ПосетитьОбъявлениеПеременнойМодуля() + +Процедура ПосетитьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных) + Перем Подписка, ОбъявлениеЛокальнойПеременной; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеСпискаЛокальныхПеременных Цикл + Подписка.ПосетитьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных); + КонецЦикла; + ДобавитьНаСтек(ОбъявлениеСпискаЛокальныхПеременных); + Для Каждого ОбъявлениеЛокальнойПеременной Из ОбъявлениеСпискаЛокальныхПеременных.Объявления Цикл + ПосетитьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной); + КонецЦикла; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеСпискаЛокальныхПеременных Цикл + Подписка.ПокинутьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных); + КонецЦикла; +КонецПроцедуры // ПосетитьОбъявлениеСпискаЛокальныхПеременных() + +Процедура ПосетитьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеЛокальнойПеременной Цикл + Подписка.ПосетитьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеЛокальнойПеременной Цикл + Подписка.ПокинутьОбъявлениеЛокальнойПеременной(ОбъявлениеЛокальнойПеременной); + КонецЦикла; +КонецПроцедуры // ПосетитьОбъявлениеЛокальнойПеременной() + +Процедура ПосетитьОбъявлениеПараметра(ОбъявлениеПараметра) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеПараметра Цикл + Подписка.ПосетитьОбъявлениеПараметра(ОбъявлениеПараметра); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеПараметра Цикл + Подписка.ПокинутьОбъявлениеПараметра(ОбъявлениеПараметра); + КонецЦикла; +КонецПроцедуры // ПосетитьОбъявлениеПараметра() + +Процедура ПосетитьОбъявлениеМетода(ОбъявлениеМетода) + Перем Подписка, ОбъявлениеСпискаЛокальныхПеременных; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОбъявлениеМетода Цикл + Подписка.ПосетитьОбъявлениеМетода(ОбъявлениеМетода); + КонецЦикла; + ДобавитьНаСтек(ОбъявлениеМетода); + ПосетитьСигнатуру(ОбъявлениеМетода.Сигнатура); + Для Каждого ОбъявлениеСпискаЛокальныхПеременных Из ОбъявлениеМетода.Объявления Цикл + ПосетитьОбъявлениеСпискаЛокальныхПеременных(ОбъявлениеСпискаЛокальныхПеременных); + КонецЦикла; + ПосетитьОператоры(ОбъявлениеМетода.Операторы); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОбъявлениеМетода Цикл + Подписка.ПокинутьОбъявлениеМетода(ОбъявлениеМетода); + КонецЦикла; +КонецПроцедуры // ПосетитьОбъявлениеМетода() + +Процедура ПосетитьСигнатуру(Сигнатура) + Перем Подписка, ОбъявлениеПараметра; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьСигнатуру Цикл + Подписка.ПосетитьСигнатуру(Сигнатура); + КонецЦикла; + ДобавитьНаСтек(Сигнатура); + Для Каждого ОбъявлениеПараметра Из Сигнатура.Параметры Цикл + ПосетитьОбъявлениеПараметра(ОбъявлениеПараметра); + КонецЦикла; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьСигнатуру Цикл + Подписка.ПокинутьСигнатуру(Сигнатура); + КонецЦикла; +КонецПроцедуры // ПосетитьСигнатуру() + +#КонецОбласти // ПосещениеОбъявлений + +#Область ПосещениеВыражений + +Процедура ПосетитьВыражение(Выражение) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражение Цикл + Подписка.ПосетитьВыражение(Выражение); + КонецЦикла; + ПосетитьВыражениеПоТипу(Выражение); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражение Цикл + Подписка.ПокинутьВыражение(Выражение); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражение() + +Процедура ПосетитьВыражениеПоТипу(Выражение) + Перем Тип; + Тип = Выражение.Тип; + Если Тип = Типы.ВыражениеЛитерал Тогда + ПосетитьВыражениеЛитерал(Выражение); + ИначеЕсли Тип = Типы.ВыражениеИдентификатор Тогда + ПосетитьВыражениеИдентификатор(Выражение); + ИначеЕсли Тип = Типы.ВыражениеУнарное Тогда + ПосетитьВыражениеУнарное(Выражение); + ИначеЕсли Тип = Типы.ВыражениеБинарное Тогда + ПосетитьВыражениеБинарное(Выражение); + ИначеЕсли Тип = Типы.ВыражениеНовый Тогда + ПосетитьВыражениеНовый(Выражение); + ИначеЕсли Тип = Типы.ВыражениеТернарное Тогда + ПосетитьВыражениеТернарное(Выражение); + ИначеЕсли Тип = Типы.ВыражениеСкобочное Тогда + ПосетитьВыражениеСкобочное(Выражение); + ИначеЕсли Тип = Типы.ВыражениеНе Тогда + ПосетитьВыражениеНе(Выражение); + ИначеЕсли Тип = Типы.ВыражениеСтроковое Тогда + ПосетитьВыражениеСтроковое(Выражение); + КонецЕсли; +КонецПроцедуры // ПосетитьВыражениеПоТипу() + +Процедура ПосетитьВыражениеЛитерал(ВыражениеЛитерал) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеЛитерал Цикл + Подписка.ПосетитьВыражениеЛитерал(ВыражениеЛитерал); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеЛитерал Цикл + Подписка.ПокинутьВыражениеЛитерал(ВыражениеЛитерал); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеЛитерал() + +Процедура ПосетитьВыражениеИдентификатор(ВыражениеИдентификатор) + Перем Элемент, Выражение, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеИдентификатор Цикл + Подписка.ПосетитьВыражениеИдентификатор(ВыражениеИдентификатор); + КонецЦикла; + ДобавитьНаСтек(ВыражениеИдентификатор); + Если ВыражениеИдентификатор.Аргументы <> Неопределено Тогда + Для Каждого Выражение Из ВыражениеИдентификатор.Аргументы Цикл + Если Выражение <> Неопределено Тогда + ПосетитьВыражениеПоТипу(Выражение); + КонецЕсли; + КонецЦикла; + КонецЕсли; + Для Каждого Элемент Из ВыражениеИдентификатор.Хвост Цикл + Если Элемент.Тип = Типы.ВыражениеПоле Тогда + Если Элемент.Аргументы <> Неопределено Тогда + Для Каждого Выражение Из Элемент.Аргументы Цикл + Если Выражение <> Неопределено Тогда + ПосетитьВыражениеПоТипу(Выражение); + КонецЕсли; + КонецЦикла; + КонецЕсли; + ИначеЕсли Элемент.Тип = Типы.ВыражениеИндекс Тогда + ПосетитьВыражениеПоТипу(Элемент.Выражение); + Иначе + ВызватьИсключение "нарушение протокола"; + КонецЕсли; + КонецЦикла; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеИдентификатор Цикл + Подписка.ПокинутьВыражениеИдентификатор(ВыражениеИдентификатор); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеИдентификатор() + +Процедура ПосетитьВыражениеУнарное(ВыражениеУнарное) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеУнарное Цикл + Подписка.ПосетитьВыражениеУнарное(ВыражениеУнарное); + КонецЦикла; + ДобавитьНаСтек(ВыражениеУнарное); + ПосетитьВыражениеПоТипу(ВыражениеУнарное.Операнд); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеУнарное Цикл + Подписка.ПокинутьВыражениеУнарное(ВыражениеУнарное); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеУнарное() + +Процедура ПосетитьВыражениеБинарное(ВыражениеБинарное) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеБинарное Цикл + Подписка.ПосетитьВыражениеБинарное(ВыражениеБинарное); + КонецЦикла; + ДобавитьНаСтек(ВыражениеБинарное); + ПосетитьВыражениеПоТипу(ВыражениеБинарное.ЛевыйОперанд); + ПосетитьВыражениеПоТипу(ВыражениеБинарное.ПравыйОперанд); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеБинарное Цикл + Подписка.ПокинутьВыражениеБинарное(ВыражениеБинарное); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеБинарное() + +Процедура ПосетитьВыражениеНовый(ВыражениеНовый) + Перем Выражение, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеНовый Цикл + Подписка.ПосетитьВыражениеНовый(ВыражениеНовый); + КонецЦикла; + ДобавитьНаСтек(ВыражениеНовый); + Для Каждого Выражение Из ВыражениеНовый.Аргументы Цикл + Если Выражение <> Неопределено Тогда + ПосетитьВыражениеПоТипу(Выражение); + КонецЕсли; + КонецЦикла; + Для Каждого Элемент Из ВыражениеНовый.Хвост Цикл + Если Элемент.Тип = Типы.ВыражениеПоле Тогда + Если Элемент.Аргументы <> Неопределено Тогда + Для Каждого Выражение Из Элемент.Аргументы Цикл + Если Выражение <> Неопределено Тогда + ПосетитьВыражениеПоТипу(Выражение); + КонецЕсли; + КонецЦикла; + КонецЕсли; + ИначеЕсли Элемент.Тип = Типы.ВыражениеИндекс Тогда + ПосетитьВыражениеПоТипу(Элемент.Выражение); + Иначе + ВызватьИсключение "нарушение протокола"; + КонецЕсли; + КонецЦикла; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеНовый Цикл + Подписка.ПокинутьВыражениеНовый(ВыражениеНовый); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеНовый() + +Процедура ПосетитьВыражениеТернарное(ВыражениеТернарное) + Перем Элемент, Выражение, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеТернарное Цикл + Подписка.ПосетитьВыражениеТернарное(ВыражениеТернарное); + КонецЦикла; + ДобавитьНаСтек(ВыражениеТернарное); + ПосетитьВыражениеПоТипу(ВыражениеТернарное.Выражение); + ПосетитьВыражениеПоТипу(ВыражениеТернарное.Тогда); + ПосетитьВыражениеПоТипу(ВыражениеТернарное.Иначе); + Для Каждого Элемент Из ВыражениеТернарное.Хвост Цикл + Если Элемент.Тип = Типы.ВыражениеПоле Тогда + Если Элемент.Аргументы <> Неопределено Тогда + Для Каждого Выражение Из Элемент.Аргументы Цикл + Если Выражение <> Неопределено Тогда + ПосетитьВыражениеПоТипу(Выражение); + КонецЕсли; + КонецЦикла; + КонецЕсли; + ИначеЕсли Элемент.Тип = Типы.ВыражениеИндекс Тогда + ПосетитьВыражениеПоТипу(Элемент.Выражение); + Иначе + ВызватьИсключение "нарушение протокола"; + КонецЕсли; + КонецЦикла; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеТернарное Цикл + Подписка.ПокинутьВыражениеТернарное(ВыражениеТернарное); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеТернарное() + +Процедура ПосетитьВыражениеСкобочное(ВыражениеСкобочное) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеСкобочное Цикл + Подписка.ПосетитьВыражениеСкобочное(ВыражениеСкобочное); + КонецЦикла; + ДобавитьНаСтек(ВыражениеСкобочное); + ПосетитьВыражениеПоТипу(ВыражениеСкобочное.Выражение); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеСкобочное Цикл + Подписка.ПокинутьВыражениеСкобочное(ВыражениеСкобочное); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеСкобочное() + +Процедура ПосетитьВыражениеНе(ВыражениеНе) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеНе Цикл + Подписка.ПосетитьВыражениеНе(ВыражениеНе); + КонецЦикла; + ДобавитьНаСтек(ВыражениеНе); + ПосетитьВыражениеПоТипу(ВыражениеНе.Выражение); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеНе Цикл + Подписка.ПокинутьВыражениеНе(ВыражениеНе); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеНе() + +Процедура ПосетитьВыражениеСтроковое(ВыражениеСтроковое) + Перем Выражение, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеСтроковое Цикл + Подписка.ПосетитьВыражениеСтроковое(ВыражениеСтроковое); + КонецЦикла; + ДобавитьНаСтек(ВыражениеСтроковое); + Для Каждого Выражение Из ВыражениеСтроковое.Элементы Цикл + ПосетитьВыражениеЛитерал(Выражение); + КонецЦикла; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеСтроковое Цикл + Подписка.ПокинутьВыражениеСтроковое(ВыражениеСтроковое); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеСтроковое() + +#КонецОбласти // ПосещениеВыражений + +#Область ПосещениеОператоров + +Процедура ПосетитьОператорПоТипу(Оператор) + Перем Тип; + Тип = Оператор.Тип; + Если Тип = Типы.ОператорПрисваивания Тогда + ПосетитьОператорПрисваивания(Оператор); + ИначеЕсли Тип = Типы.ОператорВозврат Тогда + ПосетитьОператорВозврат(Оператор); + ИначеЕсли Тип = Типы.ОператорПрервать Тогда + ПосетитьОператорПрервать(Оператор); + ИначеЕсли Тип = Типы.ОператорПродолжить Тогда + ПосетитьОператорПродолжить(Оператор); + ИначеЕсли Тип = Типы.ОператорВызватьИсключение Тогда + ПосетитьОператорВызватьИсключение(Оператор); + ИначеЕсли Тип = Типы.ОператорВыполнить Тогда + ПосетитьОператорВыполнить(Оператор); + ИначеЕсли Тип = Типы.ОператорВызоваПроцедуры Тогда + ПосетитьОператорВызоваПроцедуры(Оператор); + ИначеЕсли Тип = Типы.ОператорЕсли Тогда + ПосетитьОператорЕсли(Оператор); + ИначеЕсли Тип = Типы.ОператорПока Тогда + ПосетитьОператорПока(Оператор); + ИначеЕсли Тип = Типы.ОператорДля Тогда + ПосетитьОператорДля(Оператор); + ИначеЕсли Тип = Типы.ОператорДляКаждого Тогда + ПосетитьОператорДляКаждого(Оператор); + ИначеЕсли Тип = Типы.ОператорПопытка Тогда + ПосетитьОператорПопытка(Оператор); + ИначеЕсли Тип = Типы.ОператорПерейти Тогда + ПосетитьОператорПерейти(Оператор); + ИначеЕсли Тип = Типы.ОператорМетка Тогда + ПосетитьОператорМетка(Оператор); + ИначеЕсли Тип = Типы.ОператорДобавитьОбработчик Тогда + ПосетитьОператорДобавитьОбработчик(Оператор); + ИначеЕсли Тип = Типы.ОператорУдалитьОбработчик Тогда + ПосетитьОператорУдалитьОбработчик(Оператор); + ИначеЕсли Тип = Типы.ИнструкцияПрепроцессораОбласть + Или Тип = Типы.ИнструкцияПрепроцессораКонецОбласти + Или Тип = Типы.ИнструкцияПрепроцессораЕсли + Или Тип = Типы.ИнструкцияПрепроцессораИначеЕсли + Или Тип = Типы.ИнструкцияПрепроцессораИначе + Или Тип = Типы.ИнструкцияПрепроцессораКонецЕсли + Или Тип = Типы.ИнструкцияПрепроцессораВставка + Или Тип = Типы.ИнструкцияПрепроцессораКонецВставки + Или Тип = Типы.ИнструкцияПрепроцессораУдаление + Или Тип = Типы.ИнструкцияПрепроцессораКонецУдаления Тогда + ПосетитьИнструкциюПрепроцессора(Оператор); + КонецЕсли; +КонецПроцедуры // ПосетитьОператорПоТипу() + +Процедура ПосетитьОператорПрисваивания(ОператорПрисваивания) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПрисваивания Цикл + Подписка.ПосетитьОператорПрисваивания(ОператорПрисваивания); + КонецЦикла; + ДобавитьНаСтек(ОператорПрисваивания); + ПосетитьВыражениеИдентификатор(ОператорПрисваивания.ЛевыйОперанд); + ПосетитьВыражение(ОператорПрисваивания.ПравыйОперанд); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПрисваивания Цикл + Подписка.ПокинутьОператорПрисваивания(ОператорПрисваивания); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорПрисваивания() + +Процедура ПосетитьОператорВозврат(ОператорВозврат) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВозврат Цикл + Подписка.ПосетитьОператорВозврат(ОператорВозврат); + КонецЦикла; + ДобавитьНаСтек(ОператорВозврат); + Если ОператорВозврат.Выражение <> Неопределено Тогда + ПосетитьВыражение(ОператорВозврат.Выражение); + КонецЕсли; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВозврат Цикл + Подписка.ПокинутьОператорВозврат(ОператорВозврат); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорВозврат() + +Процедура ПосетитьОператорПрервать(ОператорПрервать) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПрервать Цикл + Подписка.ПосетитьОператорПрервать(ОператорПрервать); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПрервать Цикл + Подписка.ПокинутьОператорПрервать(ОператорПрервать); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорПрервать() + +Процедура ПосетитьОператорПродолжить(ОператорПродолжить) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПродолжить Цикл + Подписка.ПосетитьОператорПродолжить(ОператорПродолжить); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПродолжить Цикл + Подписка.ПокинутьОператорПродолжить(ОператорПродолжить); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорПродолжить() + +Процедура ПосетитьОператорВызватьИсключение(ОператорВызватьИсключение) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВызватьИсключение Цикл + Подписка.ПосетитьОператорВызватьИсключение(ОператорВызватьИсключение); + КонецЦикла; + ДобавитьНаСтек(ОператорВызватьИсключение); + Если ОператорВызватьИсключение.Выражение <> Неопределено Тогда + ПосетитьВыражение(ОператорВызватьИсключение.Выражение); + КонецЕсли; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВызватьИсключение Цикл + Подписка.ПокинутьОператорВызватьИсключение(ОператорВызватьИсключение); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорВызватьИсключение() + +Процедура ПосетитьОператорВыполнить(ОператорВыполнить) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВыполнить Цикл + Подписка.ПосетитьОператорВыполнить(ОператорВыполнить); + КонецЦикла; + ДобавитьНаСтек(ОператорВыполнить); + ПосетитьВыражение(ОператорВыполнить.Выражение); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВыполнить Цикл + Подписка.ПокинутьОператорВыполнить(ОператорВыполнить); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорВыполнить() + +Процедура ПосетитьОператорВызоваПроцедуры(ОператорВызоваПроцедуры) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорВызоваПроцедуры Цикл + Подписка.ПосетитьОператорВызоваПроцедуры(ОператорВызоваПроцедуры); + КонецЦикла; + ДобавитьНаСтек(ОператорВызоваПроцедуры); + ПосетитьВыражениеИдентификатор(ОператорВызоваПроцедуры.Идентификатор); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорВызоваПроцедуры Цикл + Подписка.ПокинутьОператорВызоваПроцедуры(ОператорВызоваПроцедуры); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорВызоваПроцедуры() + +Процедура ПосетитьОператорЕсли(ОператорЕсли) + Перем ОператорИначеЕсли, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорЕсли Цикл + Подписка.ПосетитьОператорЕсли(ОператорЕсли); + КонецЦикла; + ДобавитьНаСтек(ОператорЕсли); + ПосетитьВыражение(ОператорЕсли.Выражение); + ПосетитьОператоры(ОператорЕсли.Тогда); + Если ОператорЕсли.ИначеЕсли <> Неопределено Тогда + Для Каждого ОператорИначеЕсли Из ОператорЕсли.ИначеЕсли Цикл + ПосетитьОператорИначеЕсли(ОператорИначеЕсли); + КонецЦикла; + КонецЕсли; + Если ОператорЕсли.Иначе <> Неопределено Тогда + ПосетитьОператорИначе(ОператорЕсли.Иначе); + КонецЕсли; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорЕсли Цикл + Подписка.ПокинутьОператорЕсли(ОператорЕсли); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорЕсли() + +Процедура ПосетитьОператорИначеЕсли(ОператорИначеЕсли) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорИначеЕсли Цикл + Подписка.ПосетитьОператорИначеЕсли(ОператорИначеЕсли); + КонецЦикла; + ДобавитьНаСтек(ОператорИначеЕсли); + ПосетитьВыражение(ОператорИначеЕсли.Выражение); + ПосетитьОператоры(ОператорИначеЕсли.Тогда); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорИначеЕсли Цикл + Подписка.ПокинутьОператорИначеЕсли(ОператорИначеЕсли); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорИначеЕсли() + +Процедура ПосетитьОператорИначе(ОператорИначе) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорИначе Цикл + Подписка.ПосетитьОператорИначе(ОператорИначе); + КонецЦикла; + ДобавитьНаСтек(ОператорИначе); + ПосетитьОператоры(ОператорИначе.Операторы); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорИначе Цикл + Подписка.ПокинутьОператорИначе(ОператорИначе); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорИначе() + +Процедура ПосетитьОператорПока(ОператорПока) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПока Цикл + Подписка.ПосетитьОператорПока(ОператорПока); + КонецЦикла; + ДобавитьНаСтек(ОператорПока); + ПосетитьВыражение(ОператорПока.Выражение); + ПосетитьОператоры(ОператорПока.Операторы); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПока Цикл + Подписка.ПокинутьОператорПока(ОператорПока); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорПока() + +Процедура ПосетитьОператорДля(ОператорДля) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорДля Цикл + Подписка.ПосетитьОператорДля(ОператорДля); + КонецЦикла; + ДобавитьНаСтек(ОператорДля); + ПосетитьВыражениеИдентификатор(ОператорДля.Идентификатор); + ПосетитьВыражение(ОператорДля.Старт); + ПосетитьВыражение(ОператорДля.Финиш); + ПосетитьОператоры(ОператорДля.Операторы); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорДля Цикл + Подписка.ПокинутьОператорДля(ОператорДля); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорДля() + +Процедура ПосетитьОператорДляКаждого(ОператорДляКаждого) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорДляКаждого Цикл + Подписка.ПосетитьОператорДляКаждого(ОператорДляКаждого); + КонецЦикла; + ДобавитьНаСтек(ОператорДляКаждого); + ПосетитьВыражениеИдентификатор(ОператорДляКаждого.Идентификатор); + ПосетитьВыражение(ОператорДляКаждого.Коллекция); + ПосетитьОператоры(ОператорДляКаждого.Операторы); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорДляКаждого Цикл + Подписка.ПокинутьОператорДляКаждого(ОператорДляКаждого); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорДляКаждого() + +Процедура ПосетитьОператорПопытка(ОператорПопытка) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПопытка Цикл + Подписка.ПосетитьОператорПопытка(ОператорПопытка); + КонецЦикла; + ДобавитьНаСтек(ОператорПопытка); + ПосетитьОператоры(ОператорПопытка.Попытка); + ПосетитьОператорИсключение(ОператорПопытка.Исключение); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПопытка Цикл + Подписка.ПокинутьОператорПопытка(ОператорПопытка); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорПопытка() + +Процедура ПосетитьОператорИсключение(ОператорИсключение) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорИсключение Цикл + Подписка.ПосетитьОператорИсключение(ОператорИсключение); + КонецЦикла; + ДобавитьНаСтек(ОператорИсключение); + ПосетитьОператоры(ОператорИсключение.Операторы); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорИсключение Цикл + Подписка.ПокинутьОператорИсключение(ОператорИсключение); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорИсключение() + +Процедура ПосетитьОператорПерейти(ОператорПерейти) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорПерейти Цикл + Подписка.ПосетитьОператорПерейти(ОператорПерейти); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорПерейти Цикл + Подписка.ПокинутьОператорПерейти(ОператорПерейти); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорПерейти() + +Процедура ПосетитьОператорМетка(ОператорМетка) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорМетка Цикл + Подписка.ПосетитьОператорМетка(ОператорМетка); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорМетка Цикл + Подписка.ПокинутьОператорМетка(ОператорМетка); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорМетка() + +Процедура ПосетитьОператорДобавитьОбработчик(ОператорДобавитьОбработчик) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорДобавитьОбработчик Цикл + Подписка.ПосетитьОператорДобавитьОбработчик(ОператорДобавитьОбработчик); + КонецЦикла; + ДобавитьНаСтек(ОператорДобавитьОбработчик); + ПосетитьВыражениеИдентификатор(ОператорДобавитьОбработчик.Событие); + ПосетитьВыражениеИдентификатор(ОператорДобавитьОбработчик.ОбработчикСобытия); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорДобавитьОбработчик Цикл + Подписка.ПокинутьОператорДобавитьОбработчик(ОператорДобавитьОбработчик); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорДобавитьОбработчик() + +Процедура ПосетитьОператорУдалитьОбработчик(ОператорУдалитьОбработчик) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьОператорУдалитьОбработчик Цикл + Подписка.ПосетитьОператорУдалитьОбработчик(ОператорУдалитьОбработчик); + КонецЦикла; + ДобавитьНаСтек(ОператорУдалитьОбработчик); + ПосетитьВыражениеИдентификатор(ОператорУдалитьОбработчик.Событие); + ПосетитьВыражениеИдентификатор(ОператорУдалитьОбработчик.ОбработчикСобытия); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьОператорУдалитьОбработчик Цикл + Подписка.ПокинутьОператорУдалитьОбработчик(ОператорУдалитьОбработчик); + КонецЦикла; +КонецПроцедуры // ПосетитьОператорУдалитьОбработчик() + +#КонецОбласти // ПосещениеОператоров + +#Область ПосещениеВыраженийПрепроцессора + +Процедура ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессора) + Перем Тип, Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессора Цикл + Подписка.ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессора); + КонецЦикла; + Тип = ВыражениеПрепроцессора.Тип; + Если Тип = Типы.ВыражениеПрепроцессораСимвол Тогда + ПосетитьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессора); + ИначеЕсли Тип = Типы.ВыражениеПрепроцессораБинарное Тогда + ПосетитьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессора); + ИначеЕсли Тип = Типы.ВыражениеПрепроцессораНе Тогда + ПосетитьВыражениеПрепроцессораНе(ВыражениеПрепроцессора); + ИначеЕсли Тип = Типы.ВыражениеПрепроцессораСкобочное Тогда + ПосетитьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессора); + КонецЕсли; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессора Цикл + Подписка.ПокинутьВыражениеПрепроцессора(ВыражениеПрепроцессора); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеПрепроцессора() + +Процедура ПосетитьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессораСимвол) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораСимвол Цикл + Подписка.ПосетитьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессораСимвол); + КонецЦикла; + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораСимвол Цикл + Подписка.ПокинутьВыражениеПрепроцессораСимвол(ВыражениеПрепроцессораСимвол); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеПрепроцессораСимвол() + +Процедура ПосетитьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессораБинарное) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораБинарное Цикл + Подписка.ПосетитьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессораБинарное); + КонецЦикла; + ДобавитьНаСтек(ВыражениеПрепроцессораБинарное); + ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораБинарное.ЛевыйОперанд); + ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораБинарное.ПравыйОперанд); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораБинарное Цикл + Подписка.ПокинутьВыражениеПрепроцессораБинарное(ВыражениеПрепроцессораБинарное); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеПрепроцессораБинарное() + +Процедура ПосетитьВыражениеПрепроцессораНе(ВыражениеПрепроцессораНе) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораНе Цикл + Подписка.ПосетитьВыражениеПрепроцессораНе(ВыражениеПрепроцессораНе); + КонецЦикла; + ДобавитьНаСтек(ВыражениеПрепроцессораНе); + ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораНе.Выражение); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораНе Цикл + Подписка.ПокинутьВыражениеПрепроцессораНе(ВыражениеПрепроцессораНе); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеПрепроцессораНе() + +Процедура ПосетитьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессораСкобочное) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьВыражениеПрепроцессораСкобочное Цикл + Подписка.ПосетитьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессораСкобочное); + КонецЦикла; + ДобавитьНаСтек(ВыражениеПрепроцессораСкобочное); + ПосетитьВыражениеПрепроцессора(ВыражениеПрепроцессораСкобочное.Выражение); + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьВыражениеПрепроцессораСкобочное Цикл + Подписка.ПокинутьВыражениеПрепроцессораСкобочное(ВыражениеПрепроцессораСкобочное); + КонецЦикла; +КонецПроцедуры // ПосетитьВыражениеПрепроцессораСкобочное() + +Процедура ПосетитьИнструкциюПрепроцессора(ИнструкцияПрепроцессора) + Перем Подписка; + Для Каждого Подписка Из Посетитель_Подписки.ПосетитьИнструкциюПрепроцессора Цикл + Подписка.ПосетитьИнструкциюПрепроцессора(ИнструкцияПрепроцессора); + КонецЦикла; + ДобавитьНаСтек(ИнструкцияПрепроцессора); + Если ИнструкцияПрепроцессора.Владелец().Колонки.Найти("Выражение") <> Неопределено Тогда + ПосетитьВыражениеПрепроцессора(ИнструкцияПрепроцессора.Выражение); + КонецЕсли; + УдалитьСоСтека(); + Для Каждого Подписка Из Посетитель_Подписки.ПокинутьИнструкциюПрепроцессора Цикл + Подписка.ПокинутьИнструкциюПрепроцессора(ИнструкцияПрепроцессора); + КонецЦикла; +КонецПроцедуры // ПосетитьИнструкциюПрепроцессора() + +#КонецОбласти // ПосещениеВыраженийПрепроцессора + +#КонецОбласти // Посетитель + +Функция Пуск(Исходник, Знач Плагины, Параметры = Неопределено, Окружение = Неопределено) Экспорт + Перем Результаты, Плагин; + Подключить(Плагины); + Посетить(Разобрать(Исходник, Окружение), Параметры); + Результаты = Новый Массив; + Для Каждого Плагин Из Посетитель_Плагины Цикл + Результаты.Добавить(Плагин.Закрыть()); + КонецЦикла; + Очистить(); + Возврат Результаты; +КонецФункции // Пуск() + +Процедура Очистить() Экспорт + Парсер_Токены.Очистить(); + Для Каждого Элемент Из Парсер_Узлы Цикл + Элемент.Значение.ЗаполнитьЗначения(Неопределено); + Элемент.Значение.Очистить(); + КонецЦикла; +КонецПроцедуры // Очистить() + +Инициализировать(); From a1e7f8bc1a3ef8e8d973cf4fcc188de112824290 Mon Sep 17 00:00:00 2001 From: Vladimir Kharin Date: Thu, 14 Dec 2023 08:41:31 +0400 Subject: [PATCH 2/3] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D1=83=20?= =?UTF-8?q?=D0=90=D1=81=D0=B8=D0=BD=D1=85=20/=20=D0=96=D0=B4=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20(#159)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Ext/ObjectModule.bsl" | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 99fb606..a9d2b10 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" @@ -1946,7 +1946,7 @@ ИначеЕсли Парсер_Токен = Токены.Новый Тогда Операнд = РазобратьВыражениеНовый(); ИначеЕсли Парсер_Токен = Токены.Ждать Тогда - Операнд = РазобратьВыражениеЖдать(); + Операнд = РазобратьВыражениеОператорЖдать(); ИначеЕсли Парсер_Токен = Токены.ЗнакВопроса Тогда Операнд = РазобратьВыражениеТернарное(); Иначе @@ -2059,7 +2059,7 @@ Возврат Узел; КонецФункции // РазобратьВыражениеНовый() -Функция РазобратьВыражениеЖдать() +Функция РазобратьВыражениеОператорЖдать() Перем Операция, Выражение, Начало; Начало = Парсер_ДанныеТекущегоТокена; @@ -2643,6 +2643,8 @@ Оператор = РазобратьОператорВызватьИсключение(); ИначеЕсли Парсер_Токен = Токены.Выполнить Тогда Оператор = РазобратьОператорВыполнить(); + ИначеЕсли Парсер_Токен = Токены.Ждать Тогда + Оператор = РазобратьВыражениеОператорЖдать(); ИначеЕсли Парсер_Токен = Токены.Перейти Тогда Оператор = РазобратьОператорПерейти(); ИначеЕсли Парсер_Токен = Токены.Метка Тогда From f0d49b3e853df110f505513f100c7db266a88596 Mon Sep 17 00:00:00 2001 From: Vladimir Kharin Date: Thu, 14 Dec 2023 20:38:15 +0400 Subject: [PATCH 3/3] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=87=D1=82=D0=BE=20=D0=96=D0=B4=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?=D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8=20=D0=90=D1=81=D0=B8=D0=BD?= =?UTF-8?q?=D1=85,=20=D0=96=D0=B4=D0=B0=D1=82=D1=8C=20=D0=B2=20=D0=BD?= =?UTF-8?q?=D0=B0=D1=87=D0=B0=D0=BB=D0=B5=20=D0=B2=D1=8B=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20(#159)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Ext/ObjectModule.bsl" | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) 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 a9d2b10..55cadae 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" @@ -137,6 +137,7 @@ ТокеныНачалаВыражения.Добавить(Токены.ДатаВремя); ТокеныНачалаВыражения.Добавить(Токены.ЗнакВопроса); ТокеныНачалаВыражения.Добавить(Токены.Новый); + ТокеныНачалаВыражения.Добавить(Токены.Ждать); ТокеныНачалаВыражения.Добавить(Токены.Истина); ТокеныНачалаВыражения.Добавить(Токены.Ложь); ТокеныНачалаВыражения.Добавить(Токены.Неопределено); @@ -191,7 +192,7 @@ КартаТокенов[";"] = Токены.ТочкаСЗапятой; КартаТокенов[""] = Токены.КонецТекста; - Ошибки = Новый Массив(21); + Ошибки = Новый Массив(22); Ошибки[00] = Неопределено; // ошибки регистрируемые плагинами Ошибки[01] = "Ожидалось"; Ошибки[02] = "Ожидалась директива"; @@ -213,6 +214,8 @@ Ошибки[18] = "Ошибка в литерале даты"; Ошибки[19] = "Не удалось выполнить замену"; Ошибки[20] = "Ожидалось имя или путь"; + Ошибки[20] = "Ожидалось имя или путь"; + Ошибки[21] = "Оператор Ждать (Await) может употребляться только в асинхронных процедурах или функциях"; СтрогийРежим = Ложь; @@ -2063,6 +2066,10 @@ Перем Операция, Выражение, Начало; Начало = Парсер_ДанныеТекущегоТокена; + Если Не Парсер_ЭтоАсинх Тогда + Ошибка(21, Неопределено, Истина); + КонецЕсли; + СледующийТокен(); Выражение = Парсер_Узлы.ВыражениеЖдать.Добавить(); Выражение.Тип = Типы.ВыражениеЖдать;