Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
1C 8.x

Парсер в 1С. Глава 1. Критикуйте

22.11.2014, 21:23. Показов 12286. Ответов 59
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У каждого действия которое мы делаем – есть мотивация. Мотивацией для этой статьи было желание увидеть продолжение статьи http://infostart.ru/public/239061/. Продал год, подвижек нет, вспомнил вечное «Хочешь сделать хорошо – сделай это сам». Как и предыдущий докладчик я пообещаю вам что к концу этой статьи вы сможете написать свой парсер текста запроса. Тем более ничего сложного в этом нет.
Если вы уже читали «Yacc is dead» (http://arxiv.org/abs/1010.5023) то можете не читать дальше, перейти к комментам, написать кг/ам и перейти к следующей публикации. Для всех остальных – в первой части статьи - небольшой экскурс в теорию.
Что такое парсер в контексте «Matching with derivatives»? Как и на любой другой вопрос в computer since – правильный ответ – функция. Но не любая, а удовлетворяющая следующим условиям
1. Функция разбора пустой строки всегда возвращает истину
2. Функция принимает 2 аргумента – символ для проверки и строку
3. В случае если первый символ в строке для разбора совпадает с символолм для проверки, то функция возвращает остаток строки, исключив первый символ
4. Если 1 символ не совпадает с символом для проверки, то функция возвращает входящую строку
Рассмотрим примитивный парсер, разбирающий строку «а»
1C
1
2
3
4
5
6
7
Функция Разобрать_символ(символ,строка)
    Если сред(строка,1,1) = символ Тогда
        Возврат сред(строка,2);
    Иначе
        Возврат строка;
    КонецЕсли;
КонецФункции
Вызов Разобрать_символ(«м», «м») вернет пустую строку. А как вы помните по определению - вызов любого парсера к пустой строке всегда успешен. То есть вызов Разобрать_символ(«м», «м») и есть примитивный парсер для строки «а». Но что делать если наша строка имеет вид «мама»? Логика подсказывает - необходимо уметь представить запрограммировать последовательность парсеров применяемых к одной строке.
Нет ничего проще
1C
1
2
3
4
5
6
7
Функция РазобратьСлово(ВходящееСлово) 
    результат = Разобрать_символ("м",ВходящееСлово);
    результат = Разобрать_символ("а",результат);
    результат = Разобрать_символ("м",результат);
    результат = Разобрать_символ("а",результат);
    Возврат  результат = "";
КонецФункции
Вызов РазобратьСлово(«мама») вернет истина, как и ожидается. Парсер корректно разбирает входящее слово. Но, предположим, наша грамматика определяет разбор 2 слов –
L -> «мама» | «папа».
Простой вариант решения –
1C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Функция РазобратьСлово_мама(ВходящееСлово) 
    результат = Разобрать_символ("м",ВходящееСлово);
    результат = Разобрать_символ("а",результат);
    результат = Разобрать_символ("м",результат);
    результат = Разобрать_символ("а",результат);
    Возврат  результат = "";
КонецФункции
Функция РазобратьСлово_папа(ВходящееСлово) 
    результат = Разобрать_символ("м",ВходящееСлово);
    результат = Разобрать_символ("а",результат);
    результат = Разобрать_символ("м",результат);
    результат = Разобрать_символ("а",результат);
    Возврат  результат = "";
КонецФункции
 
Функция РазобратьСлово (ВходящееСлово) 
    Возврат  РазобратьСлово_мама(входящееСлово) или РазобратьСлово_папа(ВходящееСлово);
КонецФункции
Как видим, РазобратьСлово(«мама») или РазобратьСлово(«папа») – вернет истину, во всех оставшихся случаях будет возвращена ложь.
Но, как быть, если наша грамматика будет представлена в виде L-> («м»| «п») «а» («м»| «п») «а»
Можно попытаться описать функцию разбора так
1C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Функция РазобратьСлово(ВходящееСлово) 
    результат = Разобрать_символ("м",ВходящееСлово);
    Если результат = ВходящееСлово Тогда
        результат = Разобрать_символ("п",ВходящееСлово);
    КонецЕсли;
    Если результат = ВходящееСлово Тогда
        Возврат ложь; // первый символ не "м" и не "п"
    КонецЕсли;
    результатА = Разобрать_символ("а",результат);
    Если результат = результатА Тогда
        Возврат ложь; // второй символ не "а"
    КонецЕсли;
    результат = Разобрать_символ("м",результатА);
    Если результат = результатА Тогда
        результат = Разобрать_символ("п",ВходящееСлово);
    КонецЕсли;
    Если результат = результатА Тогда
        Возврат ложь; // третий символ не "м" и не "п"
    КонецЕсли;
    результат = Разобрать_символ("а",результат);
    Возврат  результат = "";
КонецФункции
Не знаю как вам, но у меня есть подозрение - такой код писать могут только за деньги и только сотрудники франчайзи (я знаю такого франча, но писать его название не буду).
1
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.11.2014, 21:23
Ответы с готовыми решениями:

Парсер в 1С. Глава 2. Критикуйте
Предыдущая ветка - https://www.cyberforum.ru/1c-custom/thread1307974.html Там остаются вопросы связанные с первой главой. Вторая глава...

критикуйте мой сайт
у меня есть сайт который я создал для того, чтобы донести обществу что есть кучка людей коллекционирующих ретро автомобили, также мы их...

Оцените сбору, критикуйте, предлагайте
Дело такое, собрали мне вчера компухтер, прокомментируйте пожалуйста)) https://www.dns-shop.ru/custompc/configuration/e5df9279c4659b9d/

59
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
01.12.2014, 17:46  [ТС]
Студворк — интернет-сервис помощи студентам
что он из себя представляет сам знаю как никак 6 лет за клюшками просидел. Собирать грамматику просто лень
0
0 / 0 / 0
Регистрация: 25.11.2014
Сообщений: 11
02.12.2014, 10:55
Проверки принадлежности символа набору символов нет.
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
02.12.2014, 10:59  [ТС]
Цитата Сообщение от akabrr Посмотреть сообщение
Проверки принадлежности символа набору символов нет.
подробнее
0
0 / 0 / 0
Регистрация: 25.11.2014
Сообщений: 11
02.12.2014, 11:16
{Id Ch Standard} = {Alphanumeric} + [_]
{Id Ch Extended} = {Printable} - ['['] - [']']

Id = ({Letter}{Id Ch Standard}* | '['{Id Ch Extended}+']') ('.'({Letter}{Id Ch Standard}* | '['{Id Ch Extended}+']'))?

{Id Ch Standard} - получается не диапазон символов, а набор.

Добавлено через 4 минуты
Форматирование меняется в статье. То блоки строк разделяются пустыми строками, то нет. Лучше разделять. Сплошной текст читать можно но не комфортно. Субъективно конечно.
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
02.12.2014, 11:24  [ТС]
Добавлю.

Добавлено через 3 минуты
Цитата Сообщение от akabrr Посмотреть сообщение
Лучше разделять.
Исправлю
0
0 / 0 / 0
Регистрация: 25.11.2014
Сообщений: 11
02.12.2014, 11:43
ОперацияВыбор подходит для проверки вхождения символа в набор.
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
02.12.2014, 11:52  [ТС]
Подходит, но будет медленно. Более правильно оформить парсер отдельно.
1C
1
2
3
4
5
6
7
8
9
10
11
12
13
Функция ПокаВходитВНабор(Парсер,СтрокаАнализа)
      строкаРаботы = строкаАнализа;
     Результат = "";
      пока истина
        символ = сред(строкаРаботы,1,1);
        если Парсер.Парсер.СимволыНабора.Найти(символ) = неопределено тогда
         прервать;
        коенцесли;
       Результат = результат + символ;
       строкаработы = сред(строкаработы,2);
   конеццикла;
   возврат РазобраноУспешно(Результат,СтрокаРАботы);
 конецфункции;
Пример вызова
1C
1
2
ид = ПостроитьПарсер("digits",новый Структура("СимволыНабора",ВМассив("0","1"....,"9")));
 Рез = ПрименитьПарсер(ид,"12345674233453245235");
Аналогично и для символов

Так будет работать быстрее нежели
1C
1
 Ид = построитьПарсер("*",ПостроитьПарсер("/",ВМассив("0","1"....,"9")))
При разработке маркдаун парсера будет показано что подобные вещи лучше в собственный функционал заворачивать
1
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
03.12.2014, 13:51  [ТС]
http://infostart.ru/public/316338/ начало
Следующая часть уже в новом году.
Подумал над предложением akabrr - парситься будет текст запроса для 7.7 - это и логичней, и проще
0
Модератор
Эксперт 1С
 Аватар для Dethmontt
4032 / 2977 / 594
Регистрация: 10.03.2011
Сообщений: 11,701
Записей в блоге: 1
03.12.2014, 20:01
Цитата Сообщение от wwall Посмотреть сообщение
Подумал над предложением akabrr - парситься будет текст запроса для 7.7 - это и логичней, и проще

Клюшки - это уже никому не интересно =(
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
03.12.2014, 21:04  [ТС]
Зато простой язык и сразу понятно как со всем этим работать
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
18.12.2014, 22:49  [ТС]
начало второй части - https://github.com/wwall/report-1.git
если не используете git то link на zip - https://github.com/wwall/repor... master.zip

Как и прежде - нужны отзывы, поиск неточностей и нелогичностей. Рекомендации по стилю.
1
0 / 0 / 0
Регистрация: 25.11.2014
Сообщений: 11
19.12.2014, 17:08
Мало . Читается легко. Спасибо. У вас талант.
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
19.12.2014, 21:09  [ТС]
да теперь стараюсь проще писать. Один из отзывов на предыдущую статью был что слишком мудренно и не понятно о чем (правда та девушка была, и начинающая).
Цитата Сообщение от akabrr Посмотреть сообщение
Мало
Ну теперь вроде как договорился с человеком. с меня рыба, код и объяснения, с него вода и упрощения. Думаю что теперь дело быстрее пойдет.

Не по теме:

Доброе слово и одинэснику приятно.

0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
23.12.2014, 19:51  [ТС]
Немного продолжения. Брать можно по ссылкам
https://www.cyberforum.ru/redi... N0ZXIuemlw
либо
https://www.cyberforum.ru/redi... QtMS5naXQ=

Как обычно - жду критику и предложение.

ЗЫ. Просьба к модерам - снесите все в 1 первом сообщении и оставьте там эти ссылки - что бы народ не путался.
0
0 / 0 / 0
Регистрация: 25.11.2014
Сообщений: 11
24.12.2014, 09:22
Функция РезультатВЧисло(значение)
ЦелаяЧасть = МассивВСтроку(значение(значение)[0]);
ДробнаяЧасть = "";
Если Не значение(значение)[1] = Неопределено Тогда
ДробнаяЧасть = МассивВСтроку(значение(значение)[1][1]);
Конецесли;


Возврат Число(ЦелаяЧасть+"."+ДробнаяЧасть);
Конецфункции

Лишние пустые строки

Добавлено через 5 минут
Как видим -строка вполне корректно разбирвается на символы и группируется по нетерминалам.

Не пробела после - .

Добавлено через 57 секунд
В коде это выглядит так
digits = ПостроитьПарсер("+",ПостроитьПарсер("ran ge",Новый Структура("Минимум,Максимум","0","9")));
На примере теста видно как строить и вызывать парсер :

То используется : то нет.

Добавлено через 2 минуты
Чем править текст? Я бы сразу в репозиторий залил.
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
24.12.2014, 09:36  [ТС]
Текст в drracket правлю. Файлы с расшриением scrbl.
Если лень его запускать - то можешь править в любоv удобном редакторе, после чего выполнять вызов make.bat - будет происходить пересборка.
0
0 / 0 / 0
Регистрация: 25.11.2014
Сообщений: 11
24.12.2014, 10:56
В DrRacket не видно лишних пустых строк. Интересно. Некорректно обрабатывает правила?

Добавлено через 30 секунд
@1C{
Функция РезультатВЧисло(значение)
ЦелаяЧасть = МассивВСтроку(значение(значение)[0]);
ДробнаяЧасть = "";
Если не значение(значение)[1] = Неопределено Тогда
ДробнаяЧасть = МассивВСтроку(значение(значение)[1][1]);
КонецЕсли;
Возврат Число(ЦелаяЧасть+"."+ДробнаяЧасть);
КонецФункции}
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
24.12.2014, 10:59  [ТС]
Не. Сразу поправил после твоего сообщения утром и перезалил.
0
0 / 0 / 0
Регистрация: 17.04.2019
Сообщений: 2
23.04.2020, 15:57
wwall, подскажите так сделал кто нибудь готовую обработку? Готов купить
0
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
23.04.2020, 16:14  [ТС]

Не по теме:

Фигасе ты некромант



По делу
https://github.com/1c-syntax/bsl-language-server - java
https://github.com/lead-tools/bsparser - 1C
ну и мое недоделаное
https://gitlab.com/wwall/styleguide

В телеграмме коференции
https://github.com/lead-tools
https://t.me/bsl_language_server
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.04.2020, 16:14

Критикуйте код. Очень надо
Особо интересует это - https://github.com/wwall/drracket-loxy/blob/master/rules/lexer-rules.rkt ну и полностью по проекту - тоже...

Стоит брать это Пк или по критикуйте конфигу
Мат.плата Gigabyte GA-Z68P-DS3 Soc-1155 iZ68 Процессор Core i5-3450 OEM <3.10GHz, 6Mb, LGA Вентилятор DeepCool...

Глава Microsoft
Выступает, танцует, и просто отжигает :) Молодец дядька, за такое человека можно уважать :)

Шлее, глава 40
Читал я книгу Шлее по Qt 4.5, дочитал до сороковой главы (Программирование поддержки сети). Попробовал скомпилировать его пример. Исходный...

Лафоре. Глава 11. Задача 2
Решал задачку из учебника - Лафоре. Глава 11. Задача 2. Вот код #include <iostream> #include <iomanip> #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Опции темы

Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru