Аналізуючі автомати
Канонічний аналізуючий автомат та граф переходів. Розщеплення функцій станів вхідного ланцюжка. Розщеплений канонічний автомат і шість станів виштовхування. Виконання роботи обома автоматами аналогічними послідовностями тактів, синтаксичний аналізатор.
Рубрика | Математика |
Вид | курсовая работа |
Язык | украинский |
Дата добавления | 01.11.2011 |
Размер файла | 864,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
Міністерство освіти і науки України
Національний університет “Львівська політехніка”
- Кафедра прикладної математики
- Курсова робота
- з курсу "Дискретна математика"
- на тему:
- "Аналізуючі автомати"
Львів - 2010
У даній курсовій роботі розглянуто аналізуючи автомати. Означення аналізую чого автомату, зведені аналізучі автомати, напівзведені аналізуючи автомати. В додатку подано програму яка використовує аналізуючи автомати.
Зміст
Вступ
Канонічний аналізуючий автомат
Розщеплення функцій станів
Узагальнення на LR(k) аналізатори
Висновок
Список використаної літератури
Додаток
Вступ
Використані поняття:
Нехай задано скінченний автомат
тоді пара
називається конфігурацією автомата М. Такт автомата М представляється бінарним відношенням +, яке визначене на конфігураціях.Запис + означає, що для існують такі конфігурації, , такі що +, для всіх 0 ? к ? і. С+С' означає, що С+С' для деякого і ?0, а С+С' означає що С+С' для деякого і ?1.
Граматика буде LR(k)-граматикою, якщо для будь-якого правого виводу в кожній правовиводимому ланцюжку можна виділити основу і визначити яким нетерміналом її треба замінити, доходячи при цьому до k-го символу cправа від правого основи.
Канонічний аналізуючий автомат
Означення. Нехай
G=(N, ?, P, S) - LR(0)-граматика і (Г, Т0) - її множина LR(0)-таблиць.
Означимо не повністю детермінований автомат М, званий канонічним аналізуючим автоматом, як п'ятірку
, де
(1) Г - множина станів,
(2) - множина можливих вхідних символів (символи з ? знаходиться на вхідній стрічці, а символи з Г - в магазині, тому Г - не лише множина станів, але й підмножина входів аналізуючого автомата)
(3) ? - відображення множини в Г, означене так:
(а) якщо - стан перенесення, то для всіх ,
(б) якщо - стан згортання, який викликає згортання за правилом А
>? і (тт. ) то ,
(в) у решті випадків не визначено.
Канонічний аналізуючий автомат є скінченним перетворювачем з побічними ефектами, пов'язаними з магазином. Його поведінку можна описати в термінах конфігурацій, що представляють собою четвірки вигляду(?, Т, ?, ?), де
(1) ? - вміст магазину (верхній символ, розміщений справа),
(2) Т - керуючий стан,
(3) ? -непереглянута частина вхідного ланцюжка,
(4) ? - породжений до цього моменту вихідний ланцюжок.
Кроки автомата можна зобразити за допомогою відношення +, заданого на множині конфігурацій. Якщо Т - стан перенесення і ?(Т, а) = Т', писатимемо +. Якщо Т викликає згортання за правилом А>? з номером і і , то пишемо +для всіх ? довжини ¦?¦- 1. Якщо ¦?¦= 0, то +. В цьому випадку Т і Т' співпадають. Відмітимо, що якщо у верхівці магазину може знаходитись символ керуючого стану, то виходить конфігурація звичайного LR-алгоритму розбору.
Відношення +, +і +визначаються звичайним чином.
Початкова конфігурація - це конфігурація вигляду , а допускаюча конфігурація має вигляд . Якщо +, то ? називається розбором, породженим автоматом М для ланцюжка ?.
Приклад. Розглянемо LR(0)-граматику G з правилами
(1) S>aA
(2) S>aB
(3) A>bA
(4) A>c
(5) B>bB
(6) B>d
які породжують регулярну множину ab*(c+d) нижче представлена множина з десяти LR(0)-таблиць(табл. 1) для G.
Т0 , Т2 , Т3 - стани перенесення. Таким чином ми отримали аналізуючий автомат з правилами перенесення
?(Т0, a) = Т2 ?(Т5, b) = Т5
?(Т2, b) = Т5 ?(Т5, c) = Т6
?(Т2, c) = Т6 ?(Т5, d) = Т7
? (Т2, d) = Т7
Знайдемо правила переходу для стану згортання Т3, Т4, Т6, Т7, Т8, Т9.Таблиця Т3 викликає згортання за правилом S>aA. Так як і то єдиним правилом для Т3 буде ?(Т3, Т0) = Т1.Таблиця Т7 викликає згортання за правилом B>d. Так як , і , то за правилами для Т7 будуть
?(Т7,Т2) = Т4 і ?(Т7,Т5) = Т9.
Дія Прехід
табл. 1
E |
S |
A |
B |
a |
c |
C |
d |
||
Т0 |
S |
Т1 |
? |
? |
Т2 |
? |
? |
? |
|
Т1 |
A |
? |
? |
? |
? |
? |
? |
? |
|
Т2 |
S |
? |
Т3 |
Т4 |
Т0 |
Т5 |
Т6 |
Т7 |
|
Т3 |
1 |
? |
? |
? |
? |
? |
? |
? |
|
Т4 |
2 |
? |
? |
? |
? |
? |
? |
? |
|
Т5 |
S |
? |
Т8 |
Т9 |
X |
Т5 |
Т6 |
Т7 |
|
Т6 |
4 |
? |
? |
? |
? |
? |
? |
? |
|
Т7 |
6 |
? |
? |
? |
? |
? |
? |
? |
|
Т8 |
3 |
? |
? |
? |
? |
? |
? |
? |
|
Т9 |
5 |
? |
? |
? |
? |
? |
? |
? |
Множина LR(0)-таблиць Повністю правила згортання такі:
? (Т3,Т0) = Т1 ? (Т8,Т2) = Т4
? (Т4,Т0) = Т1 ? (Т6,Т5) = Т8
? (Т6,Т2) = Т3 ? (Т7,Т5) = Т9
? (Т7,Т2) = Т4 ? (Т8,Т5) = Т8
? (Т8,Т2) = Т3 ? (Т9,Т5) = Т9
Граф переходів аналізуючого автомата зображено на мал. 1.
Якщо на вхід подати ланцюжок abc, то він пройде послідовність конфігурацій
е, Т0, abc, е)+(Т0, Т2, bc,е)
+(Т0Т2, Т5, c, е)
+( Т0Т2Т5, Т6, е, е)
+( Т0Т2, Т5, Т8, е, 4)
+( Т0Т2, Т3, е, 43)
+( Т0, Т1, е, 431)
Таким чином для вхідного ланцюжка abc аналізуючий автомат породжує розбір 431.
мал. 1 Граф переходів канонічного автомату
Розщеплення функцій станів
Використання аналізуючого автомата для побудови аналізаторів має низку переваг перед іншими підходами. Наприклад, часто можна розщепити функції деяких станів і зв'язати їх з двома різними послідовними станами. Якщо стан А розщеплюється на два стани А1 і А2, а В - на В1 і В2, то іноді можна сполучити, наприклад, А2 і В2, в той час коли сполучити А і В не можливо. Так як об'єм роботи, виконаної в станах А1 і А2 (або В1 і В2), дорівнює об'єму роботи виконаної в стані А (або В), то загальна кількість роботи в результаті розщеплення не збільшується. Разом з тим, якщо сполучити стани, то можна досягти економії.
Кожен стан згортання розщепимо на два стани: стан виштовхування і наступний за ним стан опитування. Припустимо, що Т - стан згортання, який викликає згортання за правилом A>а з номером і. При розщепленні стану Т утворюється стан виштовхування, єдина функція якого - видалити верхні ¦?¦- 1 символів з магазину. Якщо ? = е, то в стані виштовхування у верхівку магазину записується ім'я Т. Крім того, в стані виштовхування породжується номер правила і.
Після цього керуючий пристрій переходить у стан опитування, в якому з'ясовується ім'я стану, який знаходиться в даний момент на вершині магазину, наприклад U, і відбувається перехід в стан GOTO(U, A).
канонічний автомат граф такт аналізатор
Викидання Стан виштовхування
¦?¦- 1 символів
Згортання і Видача і
визначити стан у Стан
верхівці магазину опитування
Старий стан згортання Розщеплений стан згортання
У графі переходів стан згортання Т можна замінити станом виштовхування з тим самим іменем Т і станом опитування, позначеним Т', всі дуги як входили в старий Т, так само будуть входити в новий стан Т, а дуги, які виходили із старого Т, тепер будуть виходити з Т'. Одна непомічена дуга іде з нового Т в Т'. Це перетворення відображено на мал. 2 де правило і це A>а.
Приклад. На мал. 1 показано розщеплений автомат, побудований за аналізуючим автоматом. Стан перенесення зображений квадратами, стан виштовхування - трикутниками, а стани опитування і допуску - кружечками.
Для того, щоб порівняти поведінку цього розщепленого автомату з поведінкою автомату з прикладу, приведеного в попередньому розділі (канонічний аналізуючий автомат), розглянемо послідовність тактів, пройдену розщепленим автоматом при розборі вхідного ланцюжка abc:
(е, Т0, abc, е) +(Т0, Т2, bc,е)
+(Т0Т2, Т5, c, е)
+( Т0Т2Т5, Т6, е, е)
+( Т0Т2Т5, Т'6, е, 4)
+( Т0Т2Т5, Т8, е, 4)
+( Т0Т2, Т'8, е, 43)
+( Т0Т2, Т3, е, 43)
+( Т0, Т'3, е, 431)
+( Т0, Т1, е, 431)
Нехай М1 і М2 - два аналізуючі автомати для граматики . Називатимемо М1 і М2 еквівалентними, якщо для будь-якого вхідного ланцюжка ? вони породжують один і той самий розбір або обидва видають сигнал про помилку, прочитавши однакову кількість вхідних символів.
Якщо канонічний і розщеплений канонічний автомати працюють паралельно, легко зауважити, що їх магазини співпадають щоразу коли розщеплений автомат переходить у стан переносу чи опитування. Тому має бути зрозумілим що ці два автомати еквівалентні.
Розщеплений аналізуючий автомат можна спростити двома способами. Перший полягає в тому, що дії деяких станів не потрібні і повністю виключаються. Другий спосіб полягає в тому, що нерозрізнені стани сполучаються. В першому випадку виключаються деякі стани опитування.
Автомат, отриманий з розщепленого канонічного автомата після деяких спрощень, будемо називати напівприведеним.
Приклад. Розглянемо розщеплений аналізуючий автомат мал. 3. Стани Т3 і T'4 мають по одному переходу - цей перехід є мічений символом Т0. В результаті наших перетворень ці стани і переходи в Т0 будуть виключені. Отриманий напівприведений автомат мал. 4.
мал. 3
Розщеплений канонічний автомат
мал. 4
Напівзведений автомат
Теорема. Розщеплений канонічний аналізуючий автомат М1 і його напівприведений автомат М2 еквівалентні.
Доведення[2,125]. В результаті дій, спричинених у стані опитування, вміст магазину не змінюється. Більше того, якщо зі стану опитування Т є тільки один перехід, то стан, яким помічений цей перехід, повинен знаходитися у верхівці магазину щоразу, коли М1 переходить в стан Т. Це твердження випливає з означення канонічного автомата і функції GOTO. Таким чином, перше перетворення не пливає на послідовність операцій з магазином, входом чи виходом, здійснюваних автоматом.
Означення. Нехай
- напівприведений аналізуючий автомат,
де q0 - початковий стан, а q1 - стан допуску. Відмітимо що . Символом е будемо "відмічати" не відмічені переходи. Будемо говорити, що p і q з Q 0-нерозрізнені, і писати , якщо граф переходів для М задовольняє одну з наступних умов:
(1) p і q обидва є станами перенесення;
(2) p і q обидва є станами опитування;
(3) p і q обидва є станами виштовхування, і в цих станах автомат видаляє з магазину однакову кількість символів і породжує один і той самий номер правила(тт. в станах p і q автомат згортається за одним і тим самим правилом);
(4) p = q = q1 (заключний стан).
У решті випадків p і q 0-розрізнені. Зокрема, стани різних типів завжди 0-розрізнені.
Будемо говорити, що p і q к-нерозрізнені, і писати , якщо вони
(к-1)нерозрізнені і задовольняють одну з наступних умов:
(1) p і q є станами перенесення і
(а) для будь-якого дуги, помічені символом а, або виходять і з p, і з q, або не виходять ні з p, ні з q; якщо дуги, помічені символом а, виходять з p і q і входять в p' і q' відповідно, то p' і q' (к-1)-нерозрізнені;
(б) нема стану опитування з переходами, поміченими в p і q, в
(к-1)-нерозрізнені стани;
(2) p і q є станами виштовхування і дуги, які виходять з них ведуть в
(к-1)-нерозрізнені стани;
(3) p і q є станами опитування і для всіх станів s або p і q обидва мають
перехід на s, або обидва його не мають (в першому випадку переходи ведуть в ) (к-1)-нерозрізнені стани;
В решті випадків стани p і q будемо називати к-розрізненими. Говоритимемо, що p і q нерозрізнені і писатимемо , якщо вони к-нерозрізнені для будь-якого к ? 0. В іншому випадку p і q називатимемо розрізненими.
Лема. Нехай
- напівзведений автомат. Тоді:
(1) для всіх к існує відношення еквівалентності на Q,
(2) якщо = , то = = … .
Приклад. Розглянемо напівзведений автомат (мал. 4). Пригадавши множину LR(0)-таблиць, за якими було побудовано цей автомат(табл. 1
), можна побачити що всі шість станів виштовхування викликають згортання за різними правилами, це означає, що вони 0-розрізнені. Стани решти типів за означенням є 0-нерозрізнені з станами того ж типу, отже класи еквівалентності такі: .
Для того щоб знайти , відмітимо, що стани Т2 і Т5 1-розрізнені, тому що з Т'6 в 0-розрізнені стани Т3 і Т8 існують переходи з мітками Т2 і Т5 відповідно. Далі Т0 1-розрізнений з Т2 і Т5, оскільки з першого є перехід з міткою а, а з останніх нема. Т'6 і T'7 1-розрізнені, бо з них є переходи в 0-розрізнені стани, помічені іменем Т2. Аналогічно пари станів Т'6 і Т'9, T'7 і T'8, T'8 і T'9, 1-розрізнені. Решта пар, які є 0-нерозрізненими, також і 0-нерозрізнені. Таким чином, класи еквівалентності відношення , які мають більше одного елемента, - це і . Очевидно що = .
Означення. Нехай - напівзведений автомат. Позначимо через Q' множину класів еквівалентності відношення . Клас еквівалентності, якому належить q, позначатимемо [q]. Зведеним автоматом для М1 називатимемо автомат , де
(1),
(2) для всіх і ,
(3) для всіх q i p
Приклад. В попередньому прикладі ми знайшли що і . Зведений автомат для автомата мал. 4 зображений на мал. 5.
Стани вибрані в якості представників двох класів еквівалентності, яким належать більше двох елементів.
З означення відношення випливає, що означення приведеного автомата коректне, тт. правила (2) і (3) означення не залежать від вибору представника класу еквівалентності.
Неважко показати, що приведений і напівприведений автомати є еквівалентні. По суті, обидва автомата виконуватимуть аналогічні послідовності тактів. Стан зведеного автомата представляє клас еквівалентності відповідного стану, який належить напівзведеному автомату.
Теорема. Нехай М1 - напівзведений автомат і М2 - відповідний зведений автомат. Тоді для будь-якого і ? 0 існує така послідовність що
+
тоді і лише тоді, коли
+,
де Т0 - початковий стан автомату М1, а [u] означає клас еквівалентності, якому належить u.
Наслідок. М1 і М2 еквівалентні.
мал. 5 Зведений автомат
Узагальнення на LR(k) аналізатори
Канонічний аналізуючий автомат можна побудувати також і на множині LR(k)-таблиць для LR(k)-граматик з k > 0. Проаналізуємо випадок k = 1. Аналізуючий автомат в цьому випадку багато в чому буле аналогічний до канонічного аналізуючого автомату для LR(0)-граматики, не враховуючи того, що про кожну окрему таблицю не можливо сказати, чи є ця таблиця таблицею опитування, згортання чи таблицею допуску.
Як і раніше, кожній таблиці буде відповідати стан автомату. Знаходячись у конфігурації , автомат діє так:
(1) Знаходить аванланцюжок a = FIRST(?)
(2) Приймає рішення про те, чи потрібно виконати перенесення чи згортання, тт. якщо Т = <f, g>, то обчислюється f(а).
(а) якщо f(а) = стан перенесення, то автомат переходить у конфігурацію , де і .
(б) якщо f(а =стан згортання і і правило і це A>?, де ¦?¦= r > 0, то автомат переходить в конфігурацію , де , якщо = <f',g'>.(Якщо правило має вигляд A>е, то виникає конфігурація , де .)
(в)Якщо f(а) = допуск або помилка, то автомат зупиняється, і повідомляє, що заданий ланцюжок або допущений, або відкинутий.
Можна по-різному розщеплювати стани автомата так, щоб операції з магазином були виділеними, маючи при цьому на увазі сполучити в майбутньому спільні операції. Тут наведемо наступну схему розщеплення станів.
Нехай Т - стан відповідний до таблиці Т = <f, g>. Розщепимо його на стан читання, заштовхування, виштовхування і опитування:
(1) утворимо стан читання Т, в якому зчитується наступний вхідний
символ. (стан читання показаний на малюнку кружечками.)
(2) Якщо f(а) = стан перенесення, утворим заштовхування і проведемо дугу, помічену символом а, з стану читання в цей стан заштовхування. Якщо g(a) = T', проведемо непомічену дугу з у стан читання T'. Стан заштовхування має подвійний ефект. Вхідний символ а видаляється з вхідного ланцюжка, і ім'я таблиці Т заштовхується в магазин.(стан заштовхування позначений на малюнках квадратами.)
(3) Якщо f(а) = стан згортання і, утворим стан виштовхування Т1 і стан опитування Т2. З Т в Т1 проведена дуга, помічена символом а. Якщо правило і це A>?, то в стані Т1 з магазину видаляється ¦?¦ - 1 символ і породжується номер правила і. Якщо ? = е, то в стані Т1 в магазин записується номер вихідної таблиці Т. (стани виштовхування позначені трикутниками). Після цього з Т1 в Т2 проведемо непомічену дугу. В стані Т2 виясняється, який символ знаходиться зараз у верхівці магазину. Якщо містить T', а , то проведемо з Т2 в стан читання Т'' дугу, помічену символом T'.(стан опитування також позначатимемо кружечками. Мітки на дугах відрізнятимуть ці стани від стану читання.)
Таким чином, якщо f(а) = стан перенесення і f(b) = стан згортання і, то стан Т буде виглядати як показано(мал. 6Ошибка! Источник ссылки не найден.).
(3) Стан допуску не розщепляється.
мал. 6
Приклад. Розглянемо LR(1)-граматику з правилами:
(1)S > AB
(2)A > aAb
(3)A > e
(4)B > bB
(5)B > b
табл. 2
a |
b |
e |
S |
A |
B |
a |
b |
||
Т0 |
S |
3 |
X |
Т1 |
Т2 |
X |
Т3 |
X |
|
Т1 |
X |
X |
A |
X |
X |
X |
X |
X |
|
Т2 |
X |
S |
X |
X |
X |
Т4 |
X |
Т5 |
|
Т3 |
S |
3 |
X |
X |
Т6 |
X |
Т3 |
X |
|
Т4 |
X |
X |
1 |
X |
X |
X |
X |
X |
|
Т5 |
X |
S |
5 |
X |
X |
Т7 |
X |
Т5 |
|
Т6 |
X |
S |
X |
X |
X |
X |
X |
Т8 |
|
Т7 |
X |
X |
4 |
X |
X |
X |
X |
X |
|
Т8 |
X |
2 |
X |
X |
X |
X |
X |
X |
Множина LR(1)-таблиць
Аналізуючий автомат, отримано в результаті застосування описаної вище процедури розщеплення станів, зображено на мал. 7. Число станів розщепленого автомата для LR(1)-граматики можна зменшити декількома способами:
(1) Якщо зі стану опитування виходить лише одна дуга, то цей стан
опитування можна відкинути. Це спрощення аналогічне LR(0)-спрощенню.
(2) Нехай Т - такий стан читання, що в кожному шляху, який веде в Т, остання дуга, яка входить в стан виштовхування, завжди помічена одним і тим самим вхідним символом або символом е. Тоді стан читання можна виключити. (можна побачити, що в цьому випадку стан виштовхування має лише одну дугу і вона помічена цим символом.)
Приклад. Розглянемо автомат (мал. 7). В ньому три стани опитування зі степенем виходу 1, а саме . Ці стани і дуги, які виходять з них, можна відкинути.
Дослідимо стан читання Т6. В стан Т6 можна потрапити лише шляхами, які виходять з Т3 і Т'3 або з Т8 і Т'8. В обох випадках міткою попередньо вхідного символа слугує b, тт., якщо в стані Т3 або Т8 на вході з'явиться b, то автомат переходить у стан або для виконання згортання.
Символ b залишається у вхідному ланцюжку доти, поки автомат, який знаходиться в стані Т6, не прочитає його і не вирішить перейти в стан для виконання перенесення.
Оскільки відомо, що b насправді з'являється у вхідному ланцюжку, то стан Т6 зайвий; в стані автомат може помістити ім'я стану Т6 в магазин, не зчитуючи наступного вхідного символу, оскільки автомат досягнув стану Т6, то цим вхідним символом мусить бути b.
Аналогічно можна виключити стан Т2.
Отриманий в результаті автомат зображено схемою на мал. 8.
мал. 7 Розщеплений автомат LR(1)-граматики
мал. 8
Напівзведений автомат
Висновок
Якщо LR-таблиці розміщуються в керуючому пристрої синтаксичного аналізатора, то кожну таблицю можна розглядати як стан автомата, який реалізує LR-алгоритм розбору. Такий автомат можна розглядати як такий що використовує магазинну пам'ять скінченний автомат. Можна мінімізувати число станів цього автомату таким чином зменшивши об'єм роботи. В додатку наведений приклад використання аналізуючих автоматів у нисхідному синтаксичному аналізі.
Список використаної літературитури
1. А.Ахо, Дж. Ульман. Компиляторы. Принципы, техгологии, инструменты. - М.:Вильямс 2003.
2. А.Ахо, Дж.Ульман. Теория синтаксического анализа, перевода и компиляции. - М.: Мир, 1978, т. 2.
Додаток
Програмна реалізація синтаксичного аналізу з допомогою аналізуючих автоматів.
Опис програми:
Програма аналізує введений рядок і вказує на належнічність, чи не належність його до заданої граматики. Програма реалізована на мові програмування С++, у середовищі Microsoft Visual Studio 6.0.Граматика вводиться у файл. Ввід рядка проводиться з клавіатури. Програма працює на будь-якому комп'ютері з операційною системою Windows. Для коректної роботи програми необхідно привести граматику до такого вигляду:
де,
А, В - нетермінали;
?,? - довільна стрічка терміналів.
Опис класів використаних у програмі:
SyntaxAnalyze:
cache - змінна необхідна для оптимізації і прискорення роботи функції.
rules - контейнер який містить правила граматики і по суті є множиною керуючих таблиць.
in - файлова змінна з допомогою якої реалізується зв'язок з граматикою яка збережена в файлі.
void Construct() - функція яка будує множину керуючих таблиць.
SyntaxAnalize(char * name_in) - конструктор який приймає ім'я файла.
Tree* Analyze(int start, int finish, char neterminal, string rez) - основна функція яка проводить аналіз введеной стрічки.
Tree:
Об'єкти класу являть собою вузли дерева виводу введеного рядка.
Neterminal - зберігає інформацію про нетермінал.
m_left_terminals - зберігає термінальні символи які знаходяться зліва від нетерміналів.
m_right_terminals - зберігає термінальні символи які знаходяться зправа від нетерміналів.
Tree *m_left_branch, *m_right_branch - зберігають вказівники на відповідно ліву і праву дочірні вітки.
int m_begin_lex, m_end_lex - зберігає початок і кінець підстрічки відповідно.
rule_numver - зберігає номер правила за яким розбиралась підстрічка.
Tree() - конструктор без параметрів.
Tree& operator = (const Tree &rop) - перегружений оператор присвоєння.
Tree(Tree &rop) -конструктор копій.
Контрольний приклад
Для заданої граматики:
S-AB
A-aC
B-bA
C-c
Вводимо стрічку:
acbac
Отримуємо результат:
Код програми:
Файл Analyz.h
#include<vector>
#include<map>
#include<fstream>
#include"tree_of_life.h"
#ifndef _GRAm_
#define _GRAm_
class SyntaxAnalize
{
private:
map<pair<pair<int, int>, char>, Tree*> cache;
map<char,vector<string> > rules;
ifstream in;
void Construct();
public:
SyntaxAnalize(char * name_in)
{
in.open(name_in, ios::in);
Construct();
}
Tree* Analyze(int start, int finish, char neterminal, string rez);
};
#endif
Файл tree_of_life.h
#include <vector>
using namespace std;
#ifndef TREE_OF_LIFE_H
#define TREE_OF_LIFE_H
class Tree
{
public:
char Neterminal;
string m_left_terminals;
string m_right_terminals;
Tree *m_left_branch, *m_right_branch;
//Tree *m_father_branch;
int m_begin_lex, m_end_lex;
int rule_numver;
Tree()
{
m_left_branch = NULL;
m_right_branch = NULL;
}
Tree& operator = (const Tree &rop)
{
m_begin_lex = rop.m_begin_lex;
m_end_lex = rop.m_end_lex;
m_left_branch = rop.m_left_branch;
m_right_branch = rop.m_right_branch;
m_left_terminals = rop.m_left_terminals;
m_right_terminals = rop.m_right_terminals;
Neterminal =rop.Neterminal;
return *this;
}
Tree(Tree &rop)
{
m_begin_lex = rop.m_begin_lex;
m_end_lex = rop.m_end_lex;
m_left_branch = rop.m_left_branch;
m_right_branch = rop.m_right_branch;
m_left_terminals = rop.m_left_terminals;
m_right_terminals = rop.m_right_terminals;
Neterminal =rop.Neterminal;
}
};
#endif
Файл funkcii.cpp
#include <iostream>
#include <string>
#include "Analiz.h"
using namespace std;
void SyntaxAnalize::Construct()
{
int y = 1;
int x = y+++y;
char neterminal;
string temp = "";
string temp_rule = "";
vector<string> bufer;
while(!in.eof())
{
in >> temp;
neterminal = temp[0];
temp = temp + '|';
for (int i = 2; i < temp.length(); ++i)
{
if (temp[i] == '|')
{
bufer.push_back(temp_rule);
temp_rule = "";
continue;
}
temp_rule = temp_rule + temp[i];
}
rules.insert(pair<char,vector <string> >(neterminal, bufer));
bufer.clear();
}
rules.begin();
for(int i = 'A'; i < 'Z'+1; ++i)
{
neterminal = i;
for(int j = 0; j < rules[i].size(); ++j)
{
cout << neterminal << '-';
cout << rules[i][j]<< '\n';
}
}
}
Tree* SyntaxAnalize::Analyze(int start, int finish, char neterminal, string rez)
{
pair<pair<int, int>, char> p = make_pair(make_pair(start, finish), neterminal);
Tree branch;
branch.m_begin_lex = start;
branch.m_end_lex = finish;
branch.Neterminal = neterminal;
if (cache.find(p) != cache.end())
{
//branch.m_left_branch = cache[p];
return cache[p];
}
for (int i = 0; i < rules[neterminal].size(); ++i)
{
int begin = start;
int end = finish;
bool fl_left = false;
bool fl_right = false;
int left = 0;
int right = rules[neterminal][i].size() - 1;
string temp_part_of_rule;
while(begin <= finish)
{
if (rules[neterminal][i][left] == rez[begin])
{
++left;
++begin;
}
else
fl_left = true;
if (rules[neterminal][i][right] == rez[end])
{
--end;
--right;
}
else
fl_right = true;
if (fl_left && fl_right)
break;
}
if(begin > end && left > right)
{
for(int j = start; j <= finish;++j)
temp_part_of_rule = temp_part_of_rule + rez[j];
branch.m_left_terminals = temp_part_of_rule;
branch.rule_numver = i;
cache[p] = new Tree (branch);
return cache[p];
}
for (int j = start; j < begin; ++j)
temp_part_of_rule = temp_part_of_rule + rez[j];
branch.m_left_terminals = temp_part_of_rule ;
temp_part_of_rule = "";
for (int k = end+1; k <= finish; ++k)
temp_part_of_rule = temp_part_of_rule + rez[k];
branch.m_right_terminals = temp_part_of_rule ;
if (left == right && isupper(rules[neterminal][i][left]))
{
branch.m_left_branch = Analyze(begin, end,rules[neterminal][i][left], rez);
if(branch.m_left_branch != NULL)
{
cache[p] = new Tree(branch);
return cache[p];
}
}
if(left + 1 == right && isupper(rules[neterminal][i][left]) && isupper(rules[neterminal][i][right]))
{
for(int j = begin; j < end; ++j)
{
fl_left = false;
fl_right = false;
branch.m_left_branch = Analyze(begin, j,rules[neterminal][i][left], rez);
if (branch.m_left_branch != NULL)
fl_left = true;
branch.m_right_branch = Analyze(j+1, end,rules[neterminal][i][right], rez);
if (branch.m_right_branch != NULL)
fl_right = true;
if (fl_left && fl_right)
{
cache[p] = new Tree (branch);
return cache[p];
}
else
continue;
}
}
}
cache[p] = NULL;
return NULL;
}
Файл main.cpp
#include "Analiz.h"
#include <iostream>
using namespace std;
void main()
{
Tree *noda;
string input;
char temp[100];
SyntaxAnalize grama("gramatyka.txt");
bool fl_continue = true;
char c;
while(fl_continue)
{
fl_continue = false;
cout << "Enter string!\n";
cin >> temp;
for(int i =0; temp[i];++i)
input += temp[i];
noda = grama.Analyze(0,input.length(),'S',input);
if (noda)
cout << "Ok\n";
else
cout << "Error!\n";
cout << "continue?(y/n)\n";
cin >> c;
if (c == 'y')
fl_continue = true;
}
}
Размещено на Allbest.ru
Подобные документы
Способи формування функції виходу в автоматі Мілі та автоматі Мура. Кодування станів: кількість регістрів, побудова таблиці переходів. Структурна схема автомата: пам'ять, дешифратор, схема функцій збудження пам'яті. Методика синтезу керуючого автомату.
курсовая работа [410,2 K], добавлен 31.01.2014Побудова графічної схеми алгоритму та розмітка станів автомата, графа та кодування, структурної таблиці. Синтез комбінаційних схем для функцій збудження тригерів і вихідних сигналів. Представлення функції в канонічних формах алгебр Буля, їх мінімізація.
курсовая работа [902,8 K], добавлен 27.08.2014Методи зведення до канонічної форми задач лінійного програмування. Визначення шляхів знаходження екстремумів функцій графічним способом. Побудова початкового опорного плану методом "північно-західного" напрямку. Складання двоїстої системи матриць.
контрольная работа [262,0 K], добавлен 08.02.2010Перевірка гіпотези про нормальний розподіл параметрів загального аналізу крові для компенсованого, субкомпенсованого та декомпенсованого станів за кишкової непрохідності. Перевірки гіпотез про рівність середніх значень та про незалежність параметрів.
курсовая работа [3,8 M], добавлен 13.08.2010Зведення до канонічного вигляду кривих і поверхонь другого порядку методом ортогональних перетворень, побудова їх за заданими канонічними рівняннями. Визначення лінійних операторів та квадратичних форм. Власні вектори та значення лінійного оператора.
курсовая работа [1,9 M], добавлен 13.11.2012Построение таблицы поведения автомата и соответствующего графа. Нахождение системы булевых функций для возбуждения T-триггеров, реализующих функции "пси". Определение булевой функции для реализации функции "фи". Составление логической схемы автомата.
курсовая работа [96,7 K], добавлен 27.04.2011Обчислення меж гіперболічних функцій та замінна змінного. Порівняння гіперболічних і зворотних до них функцій. Диференціювання зворотних гіперболічних функцій, невизначений інтеграл. Розкладання гіперболічних функцій по формулах Тейлора та Маклорена.
курсовая работа [2,0 M], добавлен 11.02.2011Математична постановка задач пошуку умов повної керованості в лінійних стаціонарних динамічних системах керування. Представлення систем диференційних рівнянь управління в просторі станів. Достатні умови в критеріях повної керованості Е. Гільберта.
дипломная работа [2,0 M], добавлен 16.06.2013Побудова графіків реалізацій вхідного та вихідного процесів, розрахунок функцій розподілу, математичного сподівання, кореляційної функції. Поняття та принципи вивчення одномірної функції розподілу відгуку, порядок конструювання математичної моделі.
контрольная работа [316,2 K], добавлен 08.11.2014Декартова система координат. Построение композиции отображений. Проверка полноты системы функций. Построение логической схемы однотактного триггера на заданном элементе памяти с использованием канонического метода структурного синтеза конечных автоматов.
контрольная работа [225,5 K], добавлен 18.02.2015