АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

LL(1)-синтаксичний аналізатор для мови Pascal

Читайте также:
  1. D. Аналізатор спектру шуму
  2. Аналізатори людини - система зв'язку з навколишнім середовищем
  3. Будова і властивості аналізаторів.
  4. В Turbo Pascal строки программы могут иметь максимальную длину в 126 символов.
  5. Важкість праці: динамічні, статистичні, навантаження. Напруженість праці. Увага, напруженість аналізаторних функцій, емоційна і інтелектуальна напруженість, монотонність праці.
  6. Важкість праці: Динамічні, статичні навантаження. Напруженість праці. Увага, напруженість аналізаторних функцій, емоційна та інтелектуальна напруженість, монотонність праці.
  7. Види відчуттів. Пороги відчуттів. Чутливість аналізатора. Сенсибілізація.
  8. Властивості аналізаторів
  9. Застосування скінчених автоматів при розробці лексичних аналізаторів
  10. Лабораторний практикум побудови синтаксичних аналізаторів.
  11. Метод рекурсивного спуску програмування синтаксичних аналізаторів

Наведемо текст LL(1)-синтаксичного аналізатора для мови програмування Pascal, зробивши деякі пояснення:

- Синтаксичний аналізатор мови програмування Pascal використовує для виділення лексем з текстового файла функцію pascal_scaner(), яка при кожному звернені до неї виділяє з файла програми нову лексему. Коли сканер досягне кінця файла, то в подальшому EOF передається як нова лексема. Текст виділеної лексеми знаходиться в змінній lexema[], яка є зовнішньою змінною.

- Допоміжна функція index_elem () знаходить індекс (порядковий номер починаючи з нуля) у відповідному масиві терміналів або нетерміналів.

#include <stdio.h>

#include "mystand.h"

/* визначення структури стека синтаксичого аналiзатора */

#define MAX_STACK 200

int STACK[MAX_STACK], POS_STACK=0;

#define NULL_STACK() (POS_STACK? 0: 1)

#define COPY_STACK() (STACK[POS_STACK])

#define PUSH_STACK() (POS_STACK? --POS_STACK:0)

#define DOWN_STACK(c) (POS_STACK < MAX_STACK? STACK[++POS_STACK]=c,1: 0)

extern int pascal_scaner(void); // функція виділення нової лексеми

extern void scaner_close(void); // функція, що закриває вхідний файл

extern char lexema[]; // поточна вхідна лексема

extern int lexema_code; // код виділеної лексеми

extern int lexema_line; // рядок, з якого прочитана лексема

extern int lexema_pos; // позиція лексеми у рядку

extern int index_elem(int *, int, int);

// Зовнішні змінні для синтаксичного аналізатора:

// - таблиця управління LL(1) - синтаксичним аналізатором - TABL_LL1_UPR.

// Кількість рядків таблиці numnet - кількість нетерміналів граматики,

// кількість стовпчиків - (numtrm+1) - кількість терміналів в граматиці

// Допоміжна функція, яка визначає індекс термінала або нетермінала у

// відповідному масиві.

int index_elem(int *net_term, int num, int elem)

{ int i;

for (i=0; i < num; i++) if (*(net_term+i) = = elem) return i;

}

// Лексичний аналiзатор:

// - видiляє лексему в поле lexema,

// - в поле lexema_code заносить код лексеми.

// - аналізатор повертає E-епсилон слово(lexema_code==0), коли досягли ЕOF,

// iнакше код лексеми в полi lexema_code

// В lexema_line знаходиться номер рядка, з якого прочитана лексема.

// В lexema_pos знаходиться позиція в рядку, з якого прочитана лексема.

 

int ll1_parser_pascal(q,r)

struct node *q;

struct dnode *r;

{ struct node *qw; int i, line0, colomn, ind;

int upr;

/* початковi установки для синтаксичного аналiзатора */

STACK[0]=0; STACK[1]=*(q->pd); POS_STACK=1; ind=0; lexema_code=0;

/* головний цикл работи синтаксичного аналiзатора */

while (! NULL_STACK()) // поки стек не пустий

{ if (!ind) ind=1, pascal_scaner();

// A. Обробка при умовi, що на вершинi стека термiнал

if (COPY_STACK() >= 0)

{ if (COPY_STACK() == lexema_code)

{ ind=0; PUSH_STACK(); continue; }

// можливо короткий if

if (strcmp(NAME_ELEM(COPY_STACK()),"else") == 0)

{ PUSH_STACK(); PUSH_STACK(); continue; } // короткий if

// Синтаксична помилка

printf("Синтаксична помилка: рядок - %5.5i, позицiя -

%3.3i\n",lexema_line,lexema_pos);

printf("Пропущена лексема %s\n",NAME_ELEM(COPY_STACK()));

printf("Вершина стека - %s, вхiдна лексема - %s -

%s\n",NAME_ELEM(COPY_STACK()),lexema,NAME_ELEM(lexema_code));

scaner_close(); return(0);

}

// B. Обробка при умовi, що на вершинi нетермiнал

line0=index_elem(netname,numnet,COPY_STACK());

if (lexema_code) colomn=index_elem(terminal,numtrm,lexema_code);

else colomn=numtrm;

if (upr= *(TABL_LL1_UPR+line0*(numtrm+1)+colomn))

{ PUSH_STACK();

// пошук продукції в списку продукцій

for(qw=q,i=1; i < upr; i++,qw=qw->next);

// запис правої частини продукції в стек

for (i=qw->len-1; i > 0; i--) DOWN_STACK(*(qw->pd+i));

continue;

}

// Синтаксична помилка в програмi

printf("Синтаксична помилка: рядок - %5.5i, позицiя -

%3.3i\n",lexema_line,lexema_pos);

printf("Вершина стека - %s, вхiдна лексема - %s -

%s\n",NAME_ELEM(COPY_STACK()),lexema,NAME_ELEM(lexema_code));

scaner_close(); return(0);

} // кiнець цикла обробки стека

// Стек порожній: перевiримо стан справ на входi

if (! ind) pascal_scaner(); scaner_close();

if (lexema_code == 0) {

printf("\nВ програмi синтаксичних помилок немає\n");return(1);

}

else {

printf("\nЛогiчний кiнець програми знайдено до кiнця вхiдного файла\n");

return(0);

}

} // кiнець програми

 


1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.005 сек.)