Java-парсер синтакс-помощника (.hbk) платформы 1С:Предприятие 8.
Извлекает из файлов справки полную модель: типы, методы, свойства,
события, конструкторы, перечисления, глобальный контекст и языковые
конструкции встроенного языка (литералы, операторы, директивы
компиляции, аннотации, инструкции препроцессора) — с метаданными
(версии появления и депрекации, описания, примеры, ссылки «См. также»,
значения по умолчанию для параметров, рекомендации по замене
устаревших элементов).
Парсятся оба парных HBK платформы:
shcntx_*.hbk— типы, методы, свойства, события, перечисления, глобальный контекст;shlang_*.hbk— раздел «Встроенный язык»: примитивы, литералы (Истина/Ложь), операторы и управляющие конструкции (Если,Для,Пока,Попытка,Новый,?,[...],И/ИЛИ/НЕ), объявления (Процедура,Функция,Перем), директивы компиляции (&НаКлиенте,&НаСервере, …), аннотации (&Перед,&После, …), инструкции препроцессора (#Если,#Область, …).
Предназначен для использования в инструментах статического анализа
кода 1С — в первую очередь как источник платформенных типов для
bsl-language-server.
- Распаковка
.hbk— самостоятельно вытаскивает FileStorage из контейнера (внутри это два вложенных ZIP) в память, без записи десятков тысяч HTML-файлов на диск. Полный парсинг русского синтакс-помощника современной платформы занимает порядка секунды. - Полная модель элементов
(
api/):ContextType— платформенный тип со свойствами / методами / событиями / конструкторами и описанием из СП;ContextEnum/ContextEnumValue— системные перечисления и их значения;ContextMethod,ContextProperty,ContextEvent,ContextConstructor;ContextMethodSignature(с поддержкой нескольких вариантов синтаксиса) иContextSignatureParameter;PlatformGlobalContext— глобальный контекст (top-level методы, свойства, события приложения / обычного приложения / сеанса / внешнего соединения);ContextLanguageKeyword+LanguageKeywordCategory(LITERAL,STATEMENT,OPERATOR,DECLARATION,PRAGMA,ANNOTATION,PREPROCESSOR_INSTRUCTION) +LanguageKeywordSnippet(двуязычный шаблон автодополнения с плейсхолдерами<?>).
- Примитивные типы —
Строка,Число,Дата,Булево,Тип,Null,Неопределено— приходят какContextKind.PRIMITIVE_TYPEсо своими описаниями из синтакс-помощника.Произвольный(псевдо-маркер «любой тип») у платформы отдельной страницы не имеет и публикуется как синтетический примитив с тем жеkind. - Метаданные:
sinceVersion,deprecatedSinceVersion,recommendedReplacements,description,notes(«Замечание:»),examples(«Пример:»),seeAlso(«См. также:»),returnValueDescription,syntaxText(сырая строкаСинтаксис:),defaultValueпараметра,accessModeсвойства,availabilities(по видам клиента). - Generic-типы. Типы вида
СправочникСсылка.<Имя справочника>и свойства видаСправочникиМенеджер :: <Имя справочника>— плейсхолдеры, конкретизация которых приходит из конфигурации и парсится отдельным проектомMDClasses. Все такие элементы помечены флагомisGeneric()через эвристику вContextNames. - Двуязычие (ru + en). Имена самих сущностей приходят сразу с
обоими языками. Имена вариантов сигнатур и параметров в
одной HBK живут только на одном языке — для них есть
BilingualMerger, который парсит обе версии (shcntx_ru.hbk+shcntx_root.hbk) и подтягивает en-алиасы в ru-провайдер. Языковые конструкции изshlang_ru.hbkподмешивают en-алиасы из парногоshlang_root.hbk(имена body-keyword'ов вродеТогда/Then,КонецЕсли/EndIfсматчиваются по позиции тегов на синхронных страницах ru/en), а двуязычные сниппеты автодополнения тащатся прямо из парного.st-файла. - Автодетект установленной платформы —
PlatformFinderна Windows / Linux / macOS, аналог OneScript-библиотекиv8find. Можно запросить самую свежую версию (findLatest()) или конкретную (findVersion("8.3.27.1786")).
Через jitpack:
repositories {
maven(url = "https://jitpack.io")
}
dependencies {
implementation("com.github.1c-syntax:bsl-context:<tag>")
}import com.github._1c_syntax.bsl.context.PlatformContextGrabber;
import com.github._1c_syntax.bsl.context.api.ContextProvider;
import com.github._1c_syntax.bsl.context.api.ContextType;
// Автодетект самой свежей установленной платформы.
var grabber = PlatformContextGrabber.autoDetect(null);
grabber.parse();
ContextProvider ctx = grabber.getProvider();
// Резолв по имени (ru или en, регистронезависимый).
var array = ctx.getContextByName("Массив"); // или "Array"
// Перебор типов.
ctx.getContexts().stream()
.filter(c -> c instanceof ContextType)
.map(c -> (ContextType) c)
.forEach(type -> {
System.out.println(type.name() + (type.isGeneric() ? " [generic]" : ""));
type.methods().forEach(m -> {
var since = m.sinceVersion();
var dep = m.deprecatedSinceVersion();
System.out.println(" " + m.name()
+ (since.isEmpty() ? "" : " since=" + since)
+ (dep.isEmpty() ? "" : " DEPRECATED since=" + dep
+ " → " + String.join(", ", m.recommendedReplacements())));
});
});
// Глобальный контекст.
ctx.getGlobalContext().methods().forEach(m -> System.out.println(m.name()));// 1. Автодетект — берёт самую свежую установку, найденную PlatformFinder.
PlatformContextGrabber.autoDetect(workDir);
// 2. По каталогу bin платформы.
PlatformContextGrabber.fromPlatformBin(platformBin, workDir);
// 3. По явному пути к .hbk.
PlatformContextGrabber.fromHbk(hbkFile, workDir);
// Двуязычие — после parse() подтянуть en-имена сигнатур и параметров.
grabber.parseBilingual(enHbkFile);workDir может быть null — тогда будет использован временный каталог.
shcntx_*.hbk shlang_*.hbk
├─ FileStorage (ZIP) ─► in-memory Map └─ FileStorage (плоский,
└─ PackBlock (ZIP) ─► TableOfContent ru+en) ─► ShlangParser
│ │
▼ │
HbkTreeParser ◄──── extra:Context┘
│ для каждой страницы
▼
HtmlParser ── через PageSource
│ извлекает структурные секции
▼
PlatformContext* объекты (rawTypes = строки)
│
▼
PlatformContextProvider
│ resolve: имена → ссылки на Context
▼ (в т.ч. в shlang-примитивы)
ContextProvider (готов к использованию)
Ключевые компоненты:
| Класс | Роль |
|---|---|
PlatformContextGrabber |
Точка входа: fromHbk / fromPlatformBin / autoDetect / parseBilingual. |
PlatformFinder |
Поиск установок платформы 1С на машине (v8find-аналог). |
HbkContainerExtractor |
Разбирает внешний .hbk-контейнер на FileStorage + PackBlock. |
HbkTreeParser |
Обходит дерево HBK и для каждой страницы строит PlatformContext*-объект через HtmlParser. |
HtmlParser |
Извлекает структурные секции HTML-страницы в *Description-DTO. |
ShlangParser |
Парсит раздел «Встроенный язык» из shlang_*.hbk: примитивные типы и языковые конструкции (литералы, операторы, директивы, аннотации, инструкции препроцессора). Сниппеты автодополнения и en-алиасы вытаскивает из парного shlang_root.hbk. |
PageSource |
Абстракция «открыть страницу по пути». Реализации: InMemory (production) и FileSystem (тесты на распакованных фикстурах). |
PlatformContextProvider |
Хранит готовые контексты и резолвит строковые ссылки в объекты Context. |
BilingualMerger |
Подтягивает en-алиасы из en-провайдера в ru-провайдер. |
ContextNames |
Утилита: эвристика isGeneric(name). |
API-интерфейсы в
api/ не
зависят от реализаций и не тащат сторонних библиотек — потребитель
пишет адаптер к своей модели прямо через них.
Узкое место в наивной реализации — запись десятков тысяч HTML-файлов
на диск (особенно на NTFS). bsl-context обходит её через
PageSource.InMemory: FileStorage читается в Map<String, byte[]>
и парсится прямо из памяти, без затрагивания файловой системы.
Полный парсинг shcntx_ru.hbk современной платформы занимает порядка
1–2 секунд на ноутбуке среднего класса. После завершения парсинга
in-memory карта страниц очищается, чтобы освободить heap.
Требуется Java 21+ (включена через Gradle toolchain).
./gradlew build # сборка + тесты
./gradlew publishToMavenLocal # положить артефакт в ~/.m2В обычный прогон не включён — требует установленной 1С. Запускать вручную, выставив env-флаг:
BSL_CONTEXT_REAL_HBK=true ./gradlew test --tests "*Smoke*"Тесты автоматически находят свежую установку через PlatformFinder
и парсят пары shcntx_ru.hbk + shcntx_root.hbk (типы) и
shlang_ru.hbk + shlang_root.hbk (примитивы и языковые конструкции).
Проверяются: наличие ключевых типов, срабатывание generic-эвристики,
корректность двуязычного мерджа, разрешение типов параметров методов
в shlang-примитивы по ссылочной идентичности.
ContextProvider
├─ getContexts(): List<Context> // типы и перечисления
├─ getContextByName(name): Optional<Context> // ru или en, case-insensitive
└─ getGlobalContext(): PlatformGlobalContext // top-level
Context
├─ name(): ContextName(ru, en)
├─ kind(): ContextKind { PRIMITIVE_TYPE, TYPE, ENUM, GLOBAL_CONTEXT, LANGUAGE_KEYWORD }
└─ isGeneric(): boolean
ContextType extends Context
├─ methods(): List<ContextMethod>
├─ properties(): List<ContextProperty>
├─ events(): List<ContextEvent>
├─ constructors(): List<ContextConstructor>
└─ description(): String
ContextLanguageKeyword extends Context
├─ category(): LanguageKeywordCategory
│ { LITERAL, STATEMENT, OPERATOR, DECLARATION,
│ PRAGMA, ANNOTATION, PREPROCESSOR_INSTRUCTION }
├─ description(): String
└─ snippet(): LanguageKeywordSnippet(ru, en) // шаблон с плейсхолдерами <?>
ContextMethod
├─ name(): ContextName
├─ description(), notes(), returnValueDescription(): String
├─ examples(), seeAlso(), recommendedReplacements(): List<String>
├─ availabilities(): List<Availability>
├─ signatures(): List<ContextMethodSignature>
├─ returnValues(): List<Context>
├─ sinceVersion(), deprecatedSinceVersion(): String
└─ isGeneric(): boolean
ContextMethodSignature
├─ name(): ContextName // имя варианта
├─ parameters(): List<ContextSignatureParameter>
├─ description(): String
└─ syntaxText(): String // сырая строка «Получить(<Индекс>)»
ContextSignatureParameter
├─ name(): ContextName
├─ isRequired(): boolean
├─ types(): List<Context>
├─ description(): String
└─ defaultValue(): String
ContextProperty
├─ accessMode(): AccessMode { READ, READ_WRITE }
├─ types(): List<Context>
├─ description(), sinceVersion(), deprecatedSinceVersion(): String
├─ recommendedReplacements(): List<String>
├─ availabilities(): List<Availability>
└─ isGeneric(): boolean
ContextEnum extends Context
└─ values(): List<ContextEnumValue>
ContextEnumValue
├─ name(): ContextName
├─ description(), sinceVersion(), deprecatedSinceVersion(): String
└─ recommendedReplacements(): List<String>
LGPL-3.0-or-later.
Содержимое .hbk-файлов платформы 1С — собственность фирмы «1С» и
в репозиторий не включено. Тесты используют обезличенные
HTML-фикстуры, повторяющие разметку синтакс-помощника.