Розробка формальних граматик
1. Дотримуючись умов завдання, виходячи із заданих операцій та їх пріоритетів, була побудована наступна граматика:
Перегляд вираження і згортка зліва-направо.
ВИРАЗ = А_ВИР!
Л_ВИР.
Л_ВИР = Л_ВИР «EQU» Л_ОПЕР1! / / Операція леворекурсівная => згортка зліва-направо
Л_ОПЕР1.
Л_ОПЕР1 = Л_ОПЕР1 «XOR» Л_ОПЕР2!
Л_ОПЕР1 «OR» Л_ОПЕР2!
Л_ОПЕР2.
Л_ОПЕР2 = Л_ОПЕР2 «AND» Л_ОПЕР3!
Л_ОПЕР3.
Л_ОПЕР3 = «NOT» ЗНАК!
ЗНАК.
ЗНАК = А_ВИР ОПЕР_СР А_ВИР.
А_ВИР = А_ВИР «+» А_ОПЕР1!
А_ВИР «-» А_ОПЕР1!
А_ОПЕР1.
А_ОПЕР1 = А_ОПЕР1 «*» А_ОПЕР2!
А_ОПЕР2.
А_ОПЕР2 = А_ОПЕР2 «MOD» А_ОПЕР3!
А_ОПЕР3.
А_ОПЕР3 = А_ОПЕР4 «^» А_ОПЕР3! / / Операція праворекурсівная => згортка справа-наліво
А_ОПЕР4.
А_ОПЕР4 = FUNK «(« А_ВИР «)»!
FUNK «(» ІД_К «)»!
«(» А_ВИР «)»!
ІД_К.
ІД_К = ВД!
Конст.
ВД = «DOUBLE»!
«INTEGER»!
«STRING».
Конст = «Конст _10»!
«КОНСТ_16»!
«КОНСТ_2».
FUNK = «LEFT»!
«SIN».
ОПЕР_СР = «<»!
«>»!
«<=»!
«>=»!
«<>»!
«=».
EOG
2. Побудуємо матрицю передування вихідної граматики відповідно до вимог методу паралельного передування:
Матриця має конфлікти:
* Рядок 1, стовпець 31: 1 - конфлікт типу =, <
* Рядок 2, стовпець 32: 1 - конфлікт типу =, <
* Рядок 3, стовпець 32: 1 - конфлікт типу =, <
* Рядок 6, стовпець 36: 1 - конфлікт типу =, <
* Рядок 7, стовпець 36: 1 - конфлікт типу =, <
* Рядок 8, стовпець 37: 1 - конфлікт типу =, <
* Рядок 11, стовпець 29: 1 - конфлікт типу =, <
* Рядок 11, стовпець 41: 1 - конфлікт типу =, <
* Рядок 21, стовпець 29: 4 - конфлікт типу>, X
* Рядок 22, стовпець 29: 4 - конфлікт типу>, X
* Рядок 23, стовпець 29: 4 - конфлікт типу>, X
* Рядок 24, стовпець 29: 4 - конфлікт типу>, X
* Рядок 25, стовпець 29: 4 - конфлікт типу>, X
* Рядок 26, стовпець 29: 4 - конфлікт типу>, X
* Рядок 35, стовпець 29: 1 - конфлікт типу =, <
Налагодження
Для наочності побудуємо дерево:
Конфлікт 1-го типу:
Для уникнення конфліктів 1-го типу введемо нові правила:
Л_ВИР = Л_ВИР «EQU» Л_ОПЕР11!
Л_ОПЕР1.
Л_ОПЕР11 = Л_ОПЕР1.
Конфлікт ліквідований і рекурсія збережена.
При ліквідації конфліктів 1-го типу зникають конфлікти 4-го типу.
Отримаємо нову безконфліктну граматику:
ВИРАЗ = А_ВИР!
Л_ВИР.
Л_ВИР = Л_ВИР «EQU» Л_ОПЕР11!
Л_ОПЕР1.
Л_ОПЕР11 = Л_ОПЕР1.
Л_ОПЕР1 = Л_ОПЕР1 «XOR» Л_ОПЕР22!
Л_ОПЕР1 «OR» Л_ОПЕР22!
Л_ОПЕР2.
Л_ОПЕР22 = Л_ОПЕР2.
Л_ОПЕР2 = Л_ОПЕР2 «AND» Л_ОПЕР3!
Л_ОПЕР3.
Л_ОПЕР3 = «NOT» ЗНАК!
ЗНАК.
ЗНАК = А_ВИР ОПЕР_СР А_ВИР2.
А_ВИР2 = А_ВИР.
А_ВИР = А_ВИР «+» А_ОПЕР11!
А_ВИР «-» А_ОПЕР11!
А_ОПЕР1.
А_ОПЕР11 = А_ОПЕР1.
А_ОПЕР1 = А_ОПЕР1 «*» А_ОПЕР22!
А_ОПЕР2.
А_ОПЕР22 = А_ОПЕР2.
А_ОПЕР2 = А_ОПЕР2 «MOD» А_ОПЕР3!
А_ОПЕР3.
А_ОПЕР3 = А_ОПЕР4 «^« А_ОПЕР3!
А_ОПЕР4.
А_ОПЕР4 = FUNK «(» А_ВИР2 »)"!
FUNK «(» ІД_К1 »)"!
«(» А_ВИР2 »)»!
ІД_К.
ІД_К1 = ІД_К.
ІД_К = ВД!
Конст.
ВД = «DOUBLE»!
«INTEGER»!
«STRING».
Конст = «КОНСТ_10»!
«КОНСТ_16»!
«КОНСТ_2».
FUNK = «LEFT»!
«SIN».
ОПЕР_СР = «<»!
«>»!
«<=»!
«>=»!
«<>»!
«=».
EOG
Побудуємо матрицю передування безконфліктної граматики:
4. Розробка сканера
1) Визначаємо лексеми мови
Табл.1. Лексеми мови
Позначення лексем и | Сенс лексеми |
до онст _10 | Десяткова константа |
конст_16 | Шістнадцяткова константа (префікс & H) |
конст_2 | Двійкова константа (префікс & B) |
ід_р | Ідентифікатор (integer, double або string) |
sin | Синус дійсного числа |
left | Функція роботи з рядками |
not | Логічне «НІ» |
and | Логічне «І» |
or | Логічне «АБО» |
xor | Виключне «АБО» |
роздільник | Пробіл |
+ | Арифметична операція додавання |
- | Арифметична операція віднімання |
* | Арифметична операція множення |
mod | Арифметична операція цілочисельне ділення |
^ | Арифметична операція піднесення до степеня |
оо | Операція відносини (результат - логічний) |
( | Відкриваюча дужка |
) | Закриваюча дужка |
2) розробляти иваем базу даних сканера
Табл.2. Таблиця одно-літерних | Табл.3. Таблиця класів літер | ||||||
термінальних символів | |||||||
ТТС1 | KTL | ||||||
«А» ... «Z» «A» «C» ... «K» «M» ... «Z» | Букв и | б |