gifts2017

Статический анализатор кода для встроенного языка 1С

Опубликовал Александр Хромов (honomer) в раздел Программирование - Инструментарий

Инструмент статического анализа модулей встроенного языка 1С

Назначение инструмента

Программа предназначена для статического анализа модулей встроенного языка 1С (файлов *.bsl).  

Зачем это нужно? Применение статического анализа при разработке позволяет сократить количество ошибок, выявляемых на этапе работы и сократить время, затрачиваемое на отладку за счёт выявления этих ошибок на этапе разработки.

В ходе работы проверяется в первую очередь корректность программы на встроенном языке (несколько строже, чем сам 1С), а так же ищутся ошибки в конструкциях программы, которые являются синтаксически правильными, но при этом содержат смысловые ошибки (см. список проверяемых ошибок ниже).

Возможности

Позволяет выполнить проверку файлов на наличие ошибок в интерактивном или пакетном режиме работы.

В интерактивном режиме предоставляется возможности:

  • загрузки и проверки файла на наличие ошибок с учётом задаваемых констант компиляции
  • отображения списка ошибок и переход из него к месту ошибки в редактируемом файле
  • загрузки файла для редактирования
  • сохранения файла
  • при запуске программы открывается последний редактируемый файл

В пакетном режиме предоставляется возможность проверки одного или нескольких файлов с учётом определённых констант препроцессора и вывод сообщений об ошибках в файл протокола

Запуск в пакетном режиме

bslsa.exe pathToLogFile [ --define=DEFINE [...]] pathToFileToCheck1 [... pathToFileToCheckN]

где:

    pathToLogFile - путь к файлу протокола

    --define=DEFINE - определение требуемого символа препроцессора, например Клиент или Сервер

   pathToFileToCheck1 - путь к файлу или файлам, которые требуется проверить

Пример строки запуска в пакетном режиме

bslsa.exe c:\check.log  --define=Клиент --define=Сервер d:\cfgunload\*.bsl

Планы по развитию

В перспективе планируется:

  • реализовать возможность проверять файлы не как отдельные единицы, но как часть конфигурации
  • реализовать выбор набора правил для анализа
  • расширить набор правил анализа
  • улучшить работу с протоколом ошибок (сортировка, отбор и т.д.)
  • улучшить редактор (раскраска текста и поиск по файлу)

Ошибки и предложения

https://trello.com/b/mwACzUl2/estatico-analisis

Распознаваемые ошибки

  • Две последовательные переменные присваиваются через одно и то же выражение, что может являться логической ошибкой или неоптимизированным кодом.
  • Не все ветви выполнения в функции %1 возвращают какое-либо значение, что похоже на ошибку.
  • В функции ИМЯ отсутствует завершающий оператор ВОЗВРАТ (или ВЫЗВАТЬИСКЛЮЧЕНИЕ) что похоже на ошибку.
  • Результат вызова функции '%1' не используется, что может являться ошибкой.
  • Функция ИМЯ возвращает одно и тоже значение ЗНАЧЕНИЕ во всех точках возврата, что похоже на ошибку.
  • Операторы функции ИМЯ1 полностью совпадают с операторами функции ИМЯ2.
  • Возможно конструкция A[B ОПЕРАТОР C] ошибочна и нужна была A[B] ОПЕРАТОР C.
  • Функция СтрДлина вызывается в цикле для константного выражения, что может сказываться на производительности.
  • В выражении используется неинициализированная локальная переменная %1, что похоже на ошибку.
  • Создаваемая переменная ИМЯ имеет тоже имя что и процедура, что может привести к ошибкам.
  • Переменная ИМЯ присваивается дважды подряд без её использования между присваиваниями, что похоже на ошибку.
  • Переменной ИМЯ присвоено значение, но оно нигде не используется, что похоже на ошибку.
  • Переменная ИМЯ имеет имя одинаковое с глобальной переменной, что может привести к ошибкам.
  • Переменная %1 переопределяет одноимённый параметр.
  • Инструкция ПРОДОЛЖИТЬ является последней в цикле. Она либо является лишней, либо это похоже на ошибку кодирования.
  • Отсутствуют какие-либо операторы внутри блока (ЦИКЛ|ЕСЛИ). Возможно это ошибка кодирования.
  • Переменная ИМЯ используется для счётчика цикла и в этом и внешнем цикле, что похоже на ошибку кодирования.
  • Этот и внешний циклы ДЛЯ КАЖДОГО реализуют обход по одной и той же коллекции %1, что может быть ошибкой.
  • Начальное и конечное значение цикла совпадают, что похоже на ошибку кодирования.
  • Безусловная операция ВОЗВРАТ внутри цикла. Это может указывать на логическую ошибку.
  • Недостижимый код.
  • Оператор ? вне зависимости от условия возвращает одинаковые значения.
  • Присвоение переменной ИМЯ самой себе похоже на ошибку кодирования.
  • Рекурсивная проверка ЕСЛИ (%1) ТОГДА ЕСЛИ (%1) ... похожа на ошибку кодирования, так как условие уже проверено выше.
  • Обнаружены два взаимоисключающих условия (%1) и (%2). Второе условие всегда будет ложным.
  • Последний оператор ВОЗВРАТ в ветке ТОГДА|ИНАЧЕТОГДА|ИНАЧЕ идентичен оператору ВОЗВРАТ следующему после оператора ЕСЛИ. Похоже, что он не нужен или присутствует ошибка.
  • В первом из двух последовательных операторов ЕСЛИ с одинаковыми условиями содержится безусловный оператор ВОЗВРАТ. Второй оператор ЕСЛИ либо не нужен, либо его условие записано с ошибкой.
  • Конструкция ЕСЛИ (%1) ТОГДА ... ИНАЧЕ ЕСЛИ (%1) ... похожа на ошибку кодирования, так как оно никогда не будет выполнено.
  • Операторы в блоке ТОГДА полностью эквивалентны операторам в блоке ИНАЧЕ.
  • Выражение (%1) окружено бесполезными скобками. Может быть они не нужны или присутствует ошибка
  • Одинаковые выражения '%2' слева и справа от оператора '%1'. Возможно это ошибка кодирования.

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
bslsa.zip
.zip 6,14Mb
07.09.16
24
.zip 6,14Mb 24 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Юрий Былинкин (ardn) 30.05.16 16:00
Возможна ли пакетная работа?
2. Андрей Овсянкин (Evil Beaver) 30.05.16 20:06
А без окошка, в командной строке работает?
CodeNull; reotem; nixel; artbear; lustin; +5 Ответить 1
3. Артур Аюханов (artbear) 30.05.16 20:10
Правильно я понимаю, что пока исследуется только независимый/отдельный модуль, без связей с соседними модулями, например, общие модули ?
4. Андрей Овсянкин (Evil Beaver) 30.05.16 20:23
(3) artbear, судя по диагностике "переменная дублирует глобальную переменную" - нет. Или под глобальной имеется в виду переменная уровня модуля?
5. Никита Грызлов (nixel) 30.05.16 20:58
Некорректно обрабатывает комментарии внутри многострочной строки вида:

"Многострочная
|строка
// коммент +
|с добавленным текстом, окруженным тегами
// коммент -
|завершение строки";

Ну и конечно же интересует запуск из командной строки. Плюс интересно взглянуть на исходники (желательно открытые) :)

Спасибо за инструмент!
6. Валентин Бомбин (so-quest) 30.05.16 23:22
winxp - не запустилось.


С чем связан выбор qt?
7. Валентин Бомбин (so-quest) 30.05.16 23:27
разбор по грамматике или руками? Поддержка препроцессора есть или планируется? Разделение по областям видимости - если сделана - то как? Обработка правил - как реализована (кодом или есть язык преобразований)? Сырцы - принципиально не открываешь или можно ожидать?
8. Александр Хромов (honomer) 31.05.16 08:02
(1) ardn, Возможна. Посмотрить окно "О программе", там написано, как это сделать.
9. Александр Хромов (honomer) 31.05.16 08:27
(2) Evil Beaver, Работает. Можно увидеть синтаксис командной строки вызвав программу с параметром /?
Alien_job; +1 Ответить
10. Александр Хромов (honomer) 31.05.16 08:29
(3) artbear, Да, правильно. Пока только один модуль без связи с соседними. И это существенно сказывается на выводе типов.
11. Александр Хромов (honomer) 31.05.16 08:31
(5) nixel, разбор многострочной строки на выходных попробую исправить.
12. Александр Хромов (honomer) 31.05.16 08:33
(6) so-quest, на QT потому, что не охота было сильно заморачиваться с интерфейсом. А что пишет в WinXP - ошибка какая-то есть или совсем не запускается?
13. Александр Хромов (honomer) 31.05.16 08:39
(7) so-quest, Препроцессор поддерживается. Про области видимости - не понял о чём речь.
Разбор пока руками, может когда ANTLR v4 поддержит С++ перейдём на него.
Исходники вам в данный момент зачем?
14. Андрей Овсянкин (Evil Beaver) 31.05.16 14:38
(13) honomer, нам в данный момент они (исходники) не зачем, но в перспективе мы хотим использовать открытый инструмент (если он будет открытым). Религия у нас такая тут... ))

Кроме того, в открытый инструмент мы запросто сможем вложиться кодом, делая мир лучше.
JohnyDeath; ret-Phoenix; +2 Ответить 1
15. Александр Хромов (honomer) 31.05.16 16:34
(14) Evil Beaver, простите, я религии стараюсь обходить стороной. Пока открывать не готов, потом - подумаем.
16. Андрей Овсянкин (Evil Beaver) 31.05.16 16:38
(15) honomer, думайте, конечно. Просто когда надоест пилить в одиночку, вспомните мои слова )))
17. Александр Хромов (honomer) 31.05.16 16:42
(16) Evil Beaver, под oneScript eго проще заново написать, чем этот переделывать.
18. Валентин Бомбин (so-quest) 31.05.16 16:57
Да не в коде дело, а в правилах и модели на которой эти правила будете анализировать.
(17) как совет - пока не поздно - уходи с С++ на языки с более простым циклом разработки
19. Андрей Овсянкин (Evil Beaver) 31.05.16 16:57
(17) honomer, я вовсе не в привязке к oscript спрашиваю)))
20. Александр Хромов (honomer) 31.05.16 16:59
(19) Evil Beaver, да я, если честно, ни в чём плохом вас и не подозревал. Извините, действительно со стороны некрасиво получилось.
21. Александр Хромов (honomer) 31.05.16 17:03
(18) so-quest, более простой цикл разработки - это какой-же? :) Шарп, ява? Фреймворки у них мощные, а цикл разработки такой же - кодишь, дебажишь, тестишь.
22. Валентин Бомбин (so-quest) 31.05.16 17:23
(21) лисп/кложура/схема : тест -> репл -> код и функции не будут такие большие
23. Артур Аюханов (artbear) 31.05.16 18:14
(21) honomer,
цикл разработки такой же - кодишь, дебажишь, тестишь.

ОФФ/2 А если юзать ТДД, то скорость будет выше :)
24. Алексей Лустин (lustin) 31.05.16 21:18
25. Андрей Овсянкин (Evil Beaver) 31.05.16 21:24
(24) lustin, кстати, да. Golang разработан, как конкурент C/C++, в нем авторы серьезно подумали над устранением атавизмов C++ и заявляют практически о будущем мировом господстве.
26. Максим *** (premier) 01.06.16 10:02
На Инфостарте уже был опубликован проект тестирования конфигураций. Реализован на wsh скриптах (vbs, js). Исходные коды открыты. Тесты легко подключаются буквально на лету, каждый тест снабжен документацией, в проекте принимало участие несколько разработчиков. Кому интересно, можно посмотреть по ссылке.
h00k; artbear; +2 Ответить 2
27. Александр Хромов (honomer) 01.06.16 11:04
(26) premier,
Больше инструментов, хороших и разных.
Сайт программы недоступен.
28. Brr (brr) 01.06.16 11:07
(26) premier, это разные вещи
Evil Beaver; +1 Ответить 1
29. Вадим Латышев (pro1c@inbox.ru) 01.06.16 13:06
Без раскраски кода не годится!
Для такого инструмента, как статический анализатор кода, она обязательна должна быть!
30. Валентин Бомбин (so-quest) 01.06.16 13:14
(29) - а подробнее? чем эта раскраска поможет?
31. Александр Хромов (honomer) 01.06.16 13:22
(29) pro1c@inbox.ru, вот тоже хотелось бы узнать - чем поможет раскраска, если основной режим работы для не встроенного в Конфигуратор инструмента, вообще говоря, из командной строки.
32. Вадим Латышев (pro1c@inbox.ru) 01.06.16 13:26
(30) so-quest,

Если я делаю, статический анализ кода, мне мало сообщений о потенциальных или существующих ошибках, а хотелось бы без труда охватить взглядом код!
Ведь где то я могу согласится с анализатором, а где то нет, раскраска просто помогает мне визуально пробегать по коду взглядом, без лишнего труда выделять ключевые слова и т.д.
Плюс, я могу просто начать писать какую-нибудь процедуру для своих тестов на анализ сразу в окне, хотелось бы иметь удобный редактор!
33. Валентин Бомбин (so-quest) 01.06.16 13:35
(32) Подобные инструменты просто делают вывод (файл или консоль) а уж раскраской занимаются совсем другие программы. Основная задача анализатора - сообщить о проблеме (сообщение может быть и ложным, но если анализатор его нашел, значит текст попадает под правило анализа) Что делать с этой информаций дальше - анализатору пофиг. ведь вывод прогаммы можно и в dev/null отправить
34. Максим *** (premier) 01.06.16 20:13
(27) Сайт программы действительно недоступен, т.к. автор этот проект забросил, но я принимал активное участие в этом проекте (писал часть движка и некоторые тесты) и, думаю, смог бы убедить автора проекта "подарить" его сообществу. К тому же большинство исходных кодов сохранились, их можно на этом сайте скачать или у меня попросить (не уверен, правда, что самой последней версии) .
(28) Уважаемый, Вы ошибаетесь. Эти проекты из одной и той же области - а именно: тестирование кода модулей на соответствие некоторым стандартам (кто уж какой придумает). Отличие от предлагаемого ПО в данной публикации (+ кстати забыл поставить, исправлюсь) - это открытость кодов и масштабируемость, т.е. возможность написать тест под какие-то свои стандарты оформления кода. Ну и возможность работы над проектом в команде.
35. Максим *** (premier) 01.06.16 20:20
Вот архив, который у меня сохранился, посмотрите, протестируйте...
Прикрепленные файлы:
TestIB8x.rar
vursan; cleaner_it; +2 Ответить
36. Валентин Бомбин (so-quest) 02.06.16 11:08
Как минимум неплохо бы документацию.
Как максимум - подробную документацию.

37. Александр Хромов (honomer) 02.06.16 12:04
(36) so-quest, как-то пока руки не дошли
38. Максим *** (premier) 03.06.16 09:09
(0) Автор, утверждение Конструкция ЕСЛИ (%1) ТОГДА ... ИНАЧЕ ЕСЛИ (%1) ... похожа на ошибку кодирования, так как оно никогда не будет выполнено. не совсем верно, так как ЕСЛИ (%1) = Истина то код, следующий за оператором ТОГДА будет выполняться всегда, а вот код, следующий за конструкцией ИНАЧЕ ЕСЛИ (%1) ТОГДА действительно никогда выполняться не будет.
39. Александр Хромов (honomer) 03.06.16 19:47
(38) premier, спасибо. Переформулирую в следующей версии
40. Александр Хромов (honomer) 05.06.16 12:34
Коллеги, вопрос: кроме понятного желания "больше правил" и хотелки "подкрашивающий редактор" есть ещё какие-то пожелания по функционалу, которые вы считаете важными, но они отсутствуют? Настройка списка правил для проверки и т.д.?
41. Валентин Бомбин (so-quest) 05.06.16 13:47
1. Отдельно правила для лексера, парсера, преобразователя.
2. Свое описание правил и соответственно интерпретатор этих правил.
3. Возможность выключать проверку правила в коде
4. Связь метаданных и кода
5. Расчет метрик для кода
42. Валентин Бомбин (so-quest) 05.06.16 13:51
6. Вывод лексем и ast в отдельный файл (даст возможность самому писать правила)
43. Валентин Бомбин (so-quest) 05.06.16 13:51
7. Документировать все это
44. Валентин Бомбин (so-quest) 05.06.16 13:54
8. Уйти от ручного разбора на генератор парсеров
45. Игорь Левин (Zlohobbit) 06.06.16 11:34
Отличная доработка! Если возможно добавьте в следующих версиях поиск по анализируемому тексту! Нужно для анализа таких ошибок например как:"..похожа на ошибку кодирования, так как условие уже проверено выше.". И конечно же мечта это анализ cf -ников или для начала *.epf и *.erf))).
А так суперская Приблуда! Спасибо!
46. Александр Хромов (honomer) 06.06.16 14:24
(45) Zlohobbit, я подумывал сделать сортировку списка ошибок и его фильтрацию по типам и процедурам. Поиск, по-моему, тут не очень пригодится.
Для анализа cf, epf, erf - их нужно распаковывать, а это уже другой компот: уже существуют такие инструменты, зачем писать ещё один.
47. Александр Хромов (honomer) 06.06.16 14:29
(44) so-quest, про разбор я уже писал - antlr4 пока не поддерживает С++
Писать самостоятельно пользовательские правила и их интерпретацию - я пока не вижу перспективы и ресурсов для этого, что самое главное. так же как и вывод дерева в файл, Это-то вообще зачем? Чтобы использовать в сторонних инструментах? И в каком формате?
Пока хочется документировать нормально, сделать настройку списка проверяемых правил, исправить ошибки, внести новые :) правила.
Можно и расчет метрик кода.

Остальное, как мне кажется, сейчас не так важно.
48. Валентин Бомбин (so-quest) 06.06.16 15:25
(47) Я бы тебе рекомендовал определиться - ты будешь за деньги это продавать или бесплатно раздавать. Если за деньги - тогда твои аргументы понятны и смысла что либо дальше говорить - мало. Если же оплата не планируется - тогда я не понимаю в чем проблема вывести дерево в файл (формат - любой какой нравится - от xml до чистого текста, главное его хоть как-то описать)
Про генератор - кроме антлр есть море генераторов. Выгода от них - в более быстрой разработке - не надо думать про состояния и переходы. За тебя все сделают. Да и когда захочешь с С++ уйти - не придется много переписывать.
Про правила - ты уверен что будешь успевать реагировать на все просьбы - добавь то или это? проще дать язык описания правил и на нем уже пусть пишут все что хотят. Внутри все равно примитивная перезапись термов и паттернматчинг .
49. Александр Хромов (honomer) 06.06.16 17:16
(48) so-quest, Сделать вывод дерева - проблем нет. Как я уже выше спросил - какой в этом смысл? Кому это нужно и для чего? От этого зависит что и как выводить.
Нужно ли, в конце концов, вообще тратить на это время?
Про генераторы я в курсе. Flex, bison, flex++, bison++, spirit... и иже с ними. А так же про проблемы левой рекурсии и адские сообщения компилятора у некоторых.

Что же про разработку основанную на правилах - считаю, что это ни разу не тривиальная задача по масштабам сравнивая и даже наверное больше с самим анализатором. Время затраченное на её разработку можно потратить довольно много и без особого успеха. Ведь это по сути - интерпретатор ещё одного языка, который будет описывать эти правила.

Можете привести пример хотя бы одного анализатора, который использует такой подход? Я поглядел в википедии, но что-то ничего там такого не нашёл, хотя, нужно признаться, искал тоже не очень сильно.
50. Валентин Бомбин (so-quest) 07.06.16 09:59
> Сделать вывод дерева - проблем нет. Как я уже выше спросил - какой в этом смысл? Кому это нужно и для чего?

Сделай. Мне нужен этот вывод. Для собственных правил. Это же очевидно.

> А так же про проблемы левой рекурсии ...

Ты грамматику С/С++ разбираешь? Это примитивный 1С. Тупо бейсик, без всяких извращений. Тебе грамматика наоборот поможет и спасет от проблем связанных с неоднозначностью разбора выражений


> Что же про разработку основанную на правилах - считаю, что это ни разу не тривиальная задача

Кто сказал что будет просто? Хотя там сложного ничего и нет . Вот пример простого правила для подобной твоей системы-
(defrule :where 'lexer
  :name 'check-id-length
  :token ':identifier
  :description "Длинна переменной меньше 2 символов"
  :check #'(lambda (text type start end file index data)
         (> 2 (length text ))))
...Показать Скрыть

Где сложность в реализации? Аналогично и для обхода AST строиться набор правил.

Про построение статанализаторов кода - https://lvee.org/en/reports/LVEE_2012_01 и дальше по ссылкам.

И просьба - сделай что бы под WinXP работала твоя разработка.
51. eugenie zheludkov (eugeniezheludkov) 08.06.16 03:56
Начинал как то делать что-то подобное на регулярках в шарпе, просто была идея немного упростить труд КодРевьюверов ) и заодно "прошерстить" код от франчайзи. никакого статанализа не делал, только регулярка )

https://github.com/znsoft/1SCodeAnalyze

за код стыдно если честно. Последняя версия в ветви VS08.

работает так: распаковываете все модули конфигурации в каталог,
и в этом каталоге запускаете прогу .. а она в консоль выдает все найденные ошибки (имя объекта.имя модуля. имя метода. номер строки. кусок кода)
hotey; tkalin.vladimir; Sardukar; +3 Ответить
52. Александр Хромов (honomer) 08.06.16 14:18
(50) so-quest,
про вывод дерева понял. запишу себе в план.

про то, где сложность реализации. Вот есть правило:
(defrule :where 'lexer
:name 'check-id-length
:token ':identifier
:description "Длинна переменной меньше 2 символов"
:check #'(lambda (text type start end file index data)
(> 2 (length text ))))

сложность хотя бы в том, что в С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить. Т.е. Нужно будет написать ещё один интерпретатор. или встроить какой-то, типа lua.

про построение анализаторов - интересно, но примеров анализатора, основанного на правилах (о чём я собственно и задавал вопрос), которые мог бы задавать непосредственно пользователь я там что-то не обнаружил. Плохо искал?
53. Валентин Бомбин (so-quest) 08.06.16 15:14
-> про вывод дерева понял. запишу себе в план.
Ну хоть что-то :) Когда ждать? Где будут обновления?

-> сложность хотя бы в том, что в С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить.

Нет никакой сложности. ecl именно для этого и придуман. Хотя проще сразу перейти на интерпретируемый язык. Выгоды получишь больше. Правда, если планируешь потом продавать свой продукт - будет сложнее защитить.

-> Плохо искал?

Нет, видимо искал хорошо. Но пропустил слова ASTLOG, datalog. Понимаешь в чем дело - нет стандартизированных методик статанализа кода, но все исследования которые проводятся в этом направлении - завершаются словами "Создана база правил для анализа языка " и правила эти до боли похожи на прологовские.
54. Александр Хромов (honomer) 08.06.16 15:29
(45) Zlohobbit, при клике на сообщении курсор переходит на строку, где диагностировали ошибку. Этого не достаточно?
55. Н Ф (naf2000) 08.06.16 15:32
а зачем анализировать недоязык?
56. Александр Хромов (honomer) 08.06.16 15:37
(53) so-quest, ecl - это Embedable Common Lisp? Если да, ну и зачем оно мне - в QT уже есть встроенная поддержка QtScript.

57. Александр Хромов (honomer) 08.06.16 15:39
(55) naf2000, Если вы серьёзно не понимаете зачем это, то дискуссия видится бессмысленной.
58. Валентин Бомбин (so-quest) 08.06.16 15:45
(55) Тролишь? Или можешь привести доказательство того что 1С недоязык?
(56) тогда непонятно что вsзвало проблему - " С++ нет возможности взять лямбду в виде куска кода из файлы и выполнить. Т.е. Нужно будет написать ещё один интерпретатор. или встроить какой-то, типа lua. " - если есть qtscript.
59. Александр Хромов (honomer) 08.06.16 15:56
(58) so-quest, правила в приведённом виде - это не язык. и нужно будет делать их анализ и интерпретацию.
В общем, я запишу и подумаю.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа