Форум программистов, компьютерный форум, киберфорум
1С: Собственные программы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.52/56: Рейтинг темы: голосов - 56, средняя оценка - 4.52
 Аватар для wwall
213 / 204 / 15
Регистрация: 29.05.2014
Сообщений: 1,058
1C 8.x

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

22.11.2014, 21:23. Показов 12207. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302 Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru