Парсер арифметичних виразів, Все про програмування на 1С Підприємство
Навчання програмування на 1С
Парсер арифметичних виразів
Що таке парсер виразів?
Парсер – це програма, яка зіставляє набір лексем формальної мови з його граматикою. Результатом парсингу є дерево лексем, структура представленого виразу.
Парсер арифметичних виразів розбирає вихідний рядок формули на складові, серед яких можуть бути знаки арифметичних операцій, математичні функції та змінні та обчислює значення цього виразу.
Навіщо потрібен парсер?
Люди, які ніколи не чули, що таке парсер, можуть запитати: «Навіщо взагалі потрібен парсер?».
Саме парсер виразів можна застосовувати у таких ситуациях:
- При побудові регламентованої звітності в 1С, де певні рядки звітності складаються за певними закономірностями.
- Обчислення формул, задані користувачем у системі.
- Побудова звітів СКД з полями, що обчислюються.
- p align="justify"> Динамічні алгоритми, які можна легко змінити і які застосовуються, наприклад, для розрахунку сум документів.
- Розбір виразів у запитах 1С.
Вимоги до парсеру.
Вимоги до алгоритму парсера арифметичних виразів мають бути такими:
- Парсер повинен розбирати граматику формальної мови за один прохід ліворуч (на відміну від двопрохідної обробки граматики в деяких мовах програмування).
- Парсер повинен включати як лексичний, так і синтаксичний аналіз вихідного тексту.
- Парсер має правильно обробляти винятки.
- Парсер повинен враховувати пріоритет операцій, що виконуються.
- Парсер має вміти обчислювати стандартні математичні функції.
Щоб краще розуміти з урахуванням якого алгоритму будується даний парсер, розглянемо теорію побудови формальних граматик.
Формальні граматики.
Розглянемо приклад простої мови, що визначає підмножину арифметичних формул. Формули можуть складатися із знаків арифметичних операцій, чисел та дужок. Така мова міститиме певні правила побудови своєї граматики. У кожному правилі є ліва та права частина. При цьому з лівого боку від знака? у правилі є лише один нетермінальний символ.
Набір термінальних символів у цьому алфавіті буде таким:
Нетермінальний алфавіт наступний:
Правила граматики мови:
1. Вираз є два вирази, поєднані знаком:
ВИРАЗ? ВИРАЗ ЗНАК ВИРАЗ
2. Вираз є число:
3. Вираз є вираз у дужках:
4. Вираз є чи плюс, чи мінус, чи помножити, чи розділити:
5. Число є цифрою:
6. Число є числом і цифрою:
ЧИСЛО? ЧИСЛО ЦИФРУ
7. Цифра є чи 0, чи 1, … , чи 9:
ЦИФРА? 0 1 2 3 4 5 6 7 8 9
Виведемо формулу (25+3) за допомогою правил виведення формальної граматики. Послідовність виведення наведена нижче, кожна поточна заміна підкреслена.
Правило №3: ВИРАЗ? (ВИРАЗ)
Правило №1: (ВИРАЗ) ? ( ВИРАЗ ЗНАК ВИРАЗ )
Правило №4: (ВИРАЗ ЗНАК ВИРАЗ) ? (ВИРАЗ + ВИРАЗ)
Правило №2: (ВИРАЗ + ВИРАЗ ) ? (Вираз + число)
Правило №5: (ВИРАЗ + число) ? (ВИРАЗ + ЦИФРА)
Правило №7: (ВИРАЗ +ЦИФРА)? (ВИРАЗ + 3)
Правило №2: (ВИРАЗ + 3) ? (ЧИСЛО + 3)
Правило №6: (ЧИСЛО + 3)? (ЧИСЛО ЦИФРА + 3)
Правило №5: (ЧИСЛО ЦИФРА + 3)? ( ЦИФРА ЦИФРА + 3)
Правило №7: ( ЦИФРА ЦИФРА + 3) ? (2 ЦИФРА + 3)
Правило №7: (2 ЦИФРА + 3)? (2 5 + 3)
Програмна реалізація
Моя програмна реалізація парсера виразів на мові 1С включає проведення аналізу наступних операцій:
1. Арифметичні операції: «+» (додавання), «-» (віднімання), «*» (множення), «/» (розподіл).
2. Зміна пріоритету операцій: "(" (відкриває дужка), ")" (закриваюча дужка).
3. Операції порівняння: « » (більше), «=» (більше або одно), «=» (рівно), «<>» (не дорівнює).
4. Математичні функції:
- Ціл(x1) – Ціла частина числа. Параметри: x1 – вихідне число;
- Окр (x1, x2) - Округлення. Параметри: x1 – вихідне число, x2 – розрядність одержаного числа. Якщо параметр негативний, вихідне число округляється до відповідного розряду цілої частини;
- Ln(x1) – Натуральний логарифм. Параметри: x1 – вихідне число;
- Lg(x1) – десятковий логарифм. Параметри: x1 – вихідне число;
- Sin(x1) – Сінус. Параметри: x1 – аргумент функції;
- Cos(x1) – Косінус. Параметри: x1 – аргумент функції;
- Tg(x1) - Тангенс. Параметри: x1 – аргумент функції;
- Asin(x1) – Арксинус. Параметри: x1 – аргумент функції;
- Acos(x1) – Арккосинус. Параметри: x1 – аргумент функції;
- Atg (x1) - Арктангенс. Параметри: x1 – аргумент функції;
- Pow (x1, x2) - Зведення в ступінь. Параметри: x1 – основа, x2 – показник ступеня;
- Sqrt(x1) – Квадратний корінь.Параметри: x1 – аргумент функції;
- Abs(x1) – модуль числа. Параметри: x1 – вихідне число;
- Exp(x1) – Число e у ступені x1. Параметри: x1 – аргумент функції;
- Pi(x1) - Число пі в ступеню x1. Параметри: x1 – показник ступеня;
- Cmp(x1, x2, x3) – Умовний перехід. Якщо x1 = 0, то cmp = x2, інакше cmp = x3. Параметри: x1 – число, яке порівнюється з нулем, x2, x3 – значення умов;
- If (x1, x2, x3) - Умовний перехід. Якщо x1 = 0, то if = x2, інакше if = x3. Параметри: x1 – число, яке порівнюється з нулем, x2, x3 – значення умов;
- Min(…) – Мінімальне значення;
- Max(…) – Максимальне значення;
- And(…) – Логічний оператор «І»;
- Or(…) – Логічний оператор «АБО».
5. Виділення символьного рядка: «'» (апостроф).
6. Змінні таблиці: ( ). Знаходить у таблиці, що передається, комірку з певним значенням. Наприклад, функція Про('522000') знаходить у стовпці "Про" у рядку з ідентифікатором "522000" задане значення. Якщо такий ідентифікатор знайдено не один, значення комірок складаються між собою.
Лексичний аналізатор.
При проходженні текстового виразу використовується лексичний аналізатор, який виділяє з вхідного потоку символів цілісні лексеми: символи, числа, імена функцій, операції. Таким чином, вбудований в парсер лексичний аналізатор використовується як фільтр незначних символів і як будівник цілісних лексем, що значно полегшує розбір виразу.
Наприклад, якщо текст висловлювання трапляється число «5.78», то лексичний аналізатор сприймає його як набір символів, бо як єдину рядок. Вираз «5.78 + 7.12» — це відповідно набір 3 лексем: 2 числа – «5.78» та «7.12» та 1операція - "+". Прогалини у виразі у своїй ігноруються.
Далі отримані лексеми передаються синтаксичному аналізатору виділення з її структури і наступного обчислення значень.
Синтаксичний аналізатор.
Синтаксичний аналізатор будує з перетвореного виразу дерево набору лексем за допомогою рекурсивного виклику функцій, які відповідають певним правилам. Побудоване аналізатором дерево згортається згідно з порядком виклику функцій в 1С і на виході виходить одне підсумкове значення, яке і є значенням всього арифметичного виразу.
У коді також представлені деякі винятки, які аналізують різні ситуації при розборі виразу. Набір цих винятків у даному випадку мінімальний і не враховує всіляких «ексклюзивних» ситуацій, зате покриває більшість помилок, що виникають.
Обробка 1С.
Для прикладу функціонування парсера виразів створено обробку «Парсер формул». Вводимо формулу, заповнюємо табличну частину та натискаємо кнопку «Виконати». У полі «Результат» з'являється результат обчислення формули.
У прикладі використовується формула: if( and( К1('Ім'я'+1) >= abs((-1) * К2), 3 > 2), 2 + 3 * 4 - (143 + 211.50), sqrt( К1('Ім'я'+2) + К2('Ім'я2'))).