REFERATUA.ORG.UA — База українських рефератів




Реферат на тему:

Читання лексем виразу

Вираз є послідовністю лексичних одиниць (лексем) чотирьох різновидів: сталі, імена (позначення функцій), знаки операцій та дужки. Виділення лексем із виразу називається його лексичним аналізом. Лексеми виділяються в ході побудови внутрішнього подання виразу багаторазовим розв'язанням задачі добування чергової лексеми виразу.

Тут ми представимо розробку модуля, що забезпечує все необхідне для добування лексем. Створюючи цей модуль, ми повністю відділяємо обробку лексем виразу від їх добування. Якщо колись нам доведеться міняти добування лексем, ми внесемо зміни лише в цей модуль.

1. Алгоритм добування лексеми

Розв'язання задачі добування чергової лексеми буде описано функцією getlx. За її виконання обчислюється ознака того, чи є ще лексема у вхідній послідовності символів, і за її наявності вона присвоюється параметру-змінній функції. Помістимо функцію getlx і допоміжні для неї засоби в модуль Glx.

Алгоритм добування лексеми має такий загальний вигляд:

відшукати перший символ лексеми;

ifвідшукали

then

прочитати символи лексеми та

створити її подання

else

зафіксувати відсутність лексеми.

2. Модуль розпізнавання лексем

У цьому модулі треба означити все необхідне для читання лексем. За межами модуля використовуються тип st8 імен, типи лексем Tlx та їх різновидів Ttlx, а також функція getlx. Означення цих типів та заголовок функції мають бути в інтерфейсному розділі модуля.

У розділі реалізації означимо необхідні сталі, а також масив Namf, що зберігає множину імен функцій. Означимо змінні Bcon, Bnam, Bops, Bpar та Blex для зберігання множин символів, якими починаються лексеми відповідних різновидів, та їх об'єднання. Ініціалізацію всіх цих змінних задає процедура glxinit, виклик якої записується в розділі ініціалізації модуля. Останньою в розділі реалізації записується основна функція getlx, а перед нею – допоміжні для неї підпрограми та інші означення.

Отже, модуль Glx, записаний мовою Турбо Паскаль, має такий загальний вигляд:

Unit Glx ( input, output );

Interface

type st8=string[8];

Ttlx = (con, nam, ops, par, err);

Tlx = record

case stl : Ttlx of

con : (numb : real);

nam : (name : st8 );

ops : (sig : char);

par : (prt : char);

err : (wrlx : st8 )

end;

function getlx ( var lx : Tlx ) : boolean;

Implementation

const fnum = 2; {кількість імен функцій}

var Namf : array [ 1..fnum ] of st8;

Bcon, Bnam, Bops, Bpar, Blex : setof char;

procedure glxinit; ... end;

... { Допоміжні для getlx означення}

function getlx; ... end;

Begin

glxinit

End.

Одразу наведемо процедуру ініціалізації:

procedure glxinit;

begin

Bcon := [ '0'..'9' ]; Bnam := [ 'a'..'z' ];

Bops := [ '+', '*', '-', '/' ]; Bpar := [ '(', ')' ];

Blex := Bcon + Bnam + Bops + Bpar;

Namf[1] := 'sin'; Namf[2] := 'cos'

end;

3. Функція getlx

Будемо вважати, що вираз записано в тексті, між його лексемами можуть бути пропуски в довільній кількості, і що вираз може займати кілька рядків тексту. Інших уточнень поки що не робимо. Текст читається по одному символу, і нехай

читання й повернення наступного символу тексту задає функція getc.

Нехай останній прочитаний символ тексту, який ми називаємо поточним, зберігається в глобальній у модулі змінній tempc. Вона ініціалізується символом ' ' (пропуск), тобто перед виразом штучно додається пропуск.

Добування лексеми починається з пошуку її першого символу у вхідній послідовності. Нехай

пошук першого символу описується функцією getbglx.

З її виклику повертається або перший символ лексеми, або, коли лексеми вичерпано, символьна стала chr(0), яку можна вважати "фіктивним символом". Іменування цієї сталої ім'ям finch додамо до означень модуля.

'+', '*', '-', '/'

'(', ')'

інший символ

con

nam

ops

par

err


Подальша обробка лексеми залежить від її різновиду й визначається її першим символом. Нехай позначає цифру з діапазону '0'..'9', а – літеру з 'a'..'z'. Залежність різновиду від першого символу лексеми (за її наявності) подамо так:

Щоб добути знак операції чи дужку, досить узяти поточний символ.

Добування сталих та імен (елементів типу real і st8) опишемо функціями відповідно getcon і getnam.

Побудуємо функції getcon і getnam так, щоб після виконання їх виклику поточним був символ, наступний за останнім символом добутої лексеми. У такому разі до обробки знаків операцій і дужок додамо указання переходу до наступного поточного символу tempc := getc. Імена, що не є іменами функцій із масиву Namf, будемо вважати помилковими лексемами. Якщо лексема подається змінною lx типу Tlx, то залежно від першого символу лексеми потрібно виконати такі дії:

 lx.stl := con; lx.numb := getcon;

 lx.name := getnam;

iflx.name представлено в Namf then lx.stl := nam

else lx.stl := err;

'+', '*', '-', '/'  lx.stl := ops; lx.sig := tempc; tempc := getc;

'(', ')'  lx.stl := par; lx.prt := tempc; tempc := getc;

інше  lx.stl := err; lx.wrlx := tempc; tempc := getc;

В усіх випадках повертається значення true – ознака наявності лексеми. За символу finch повертається false. Наведена залежність є основою функції getlx:

function getlx ( var lx : Tlx ) : boolean;

begin

getlx := true; tempc := getbglx;

if tempc in Bcon then

begin

lx.stl := con; lx.numb := getcon

end

else

if tempc in Bnam then

begin

lx.name := getnam;

if isfn ( lx.name ) then lx.stl := nam

else lx.stl := err

end

else

if tempc in Bops then

begin

lx.stl := ops; lx.sig := tempc; tempc := getc

end

else

if tempc in Bpar then

begin

lx.stl := par; lx.prt := tempc; tempc := getc

end

else

if tempc = finch then

getlx := false

else

begin

lx.stl := err; lx.wrlx := tempc; tempc := getc

end

end;

Функція isfn перевірки, чи представлено ім'я lx.name в масиві Namf, залишається для самостійної розробки.

4. Допоміжні


 
Загрузка...