Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная работа №2

.pdf
Скачиваний:
19
Добавлен:
03.05.2015
Размер:
309.26 Кб
Скачать

19

ки, одиночных символов, заключенных в одинарные кавычки и знаков

операции конкатенации +.

6.Входной язык содержит последовательность вызовов процедур, разделенных символом «;» (точка с запятой). Вызов процедуры должен состоять из имени процедуры и списка параметров. В качестве параметров могут выступать идентификаторы, целые десятичные числа без знака, шестнадцатеричные числа, десятичные числа с плавающей точкой.

7.Входной язык содержит последовательность вызовов процедур, разделенных символом «;» (точка с запятой). Вызов процедуры должен состоять из имени процедуры и списка параметров. В качестве параметров могут выступать идентификаторы, строковые константы, заключенные в двойные кавычки и одиночные символы, заключенные в одинарные кавычки.

8.Входной язык содержит последовательность вызовов процедур, разделенных символом «;» (точка с запятой). Вызов процедуры должен состоять из имени процедуры и списка параметров. В качестве параметров могут выступать идентификаторы и римские цифры со знаком. (Римскими считать числа записанные большими буквами X, V и I)

9.Входной язык содержит последовательность описаний массивов

всоответствии со спецификацией языка Паскаль, разделенных символом «;» (точка с запятой). Считать, что массивы могут содержать только элементы скалярных типов integer, real, byte, word и char.

10.См. вариант №9, но размер массива должен указываться с помощью римских чисел.

11.Входной язык содержит последовательность описаний записей (record) в соответствии со спецификацией языка Паскаль, разделенных

20

символом «;» (точка с запятой). Считать, что записи могут содержать

только поля скалярных типов integer, real, byte, word, char и строки string

свозможным указанием длины строки в квадратных скобках.

12.Входной язык содержит последовательность описаний констант в соответствии со спецификацией языка Паскаль. Константы могут быть целыми десятичными числами со знаком, целыми шестнадцатеричными числами, целыми десятичными числами с плавающей точкой, строками или символами.

13.Входной язык содержит последовательность команд ассемблера в форме: <метка>: <команда> <операнд1>,<операнд2> (метка, а также один или оба операнда могут отсутствовать). В качестве операндов мо-

гут выступать регистры процессора 80х86, идентификаторы, целые де-

сятичные числа или целые шестнадцатеричные числа. (Предусмотреть наличие не менее 6 допустимых команд).

Требования к программе

1.Длину идентификаторов и строковых констант считать ограни-

ченной 32 символами. Программа должна допускать наличие коммента-

риев неограниченной длины во входном файле. Форму организации комментариев предлагается выбрать самостоятельно.

2. Необходимо организовать разбиение входного файла на слова и добавление полученных слов в таблицу лексем. Нужно помнить про отличия таблицы лексем от таблицы идентификаторов. Способы орга-

низации таблиц из предыдущей лабораторной работы здесь нельзя ис-

пользовать.

21

3.Таблица должна состоять из трех полей в соответствии с табли-

цей 1. Поле «Значение» заполнять не обязательно, однако тогда это

придется сделать при выполнении четвертой лабораторной работы.

4.Реализовать алгоритм работы спроектированного конечного ав-

томата.

5.Выполнить проверку работы программы на нескольких вариан-

тах входных наборов, в том числе ошибочных.

Требования к оформлению отчета

Отчет должен содержать следующие разделы:

1.Задание по лабораторной работе.

2.Описание КС-грамматики входного языка в форме Бэкуса-

Наура.

3.Граф конечного автомата для распознавания цепочек (в соот-

ветствии с вариантом задания).

4.Блок-схема алгоритмов или другое графическое представление

(UML-диаграмма, структурная схема, и т.п.).

5.Выводы по проделанной работе.

Основные контрольные вопросы

1.Что такое трансляция, компиляция, транслятор, компилятор?

2.Из каких процессов состоит компиляция? Расскажите об общей структуре компилятора.

3.Какую роль выполняет лексический анализ в процессе компи-

ляции?

4.Как связаны лексический и синтаксический анализ?

22

5.Дайте определение цепочки, языка. Что такое синтаксис и се-

мантика языка?

6.Какие существуют методы задания языков? Какие дополни-

тельные вопросы необходимо решить при задании языка программиро-

вания?

7.Что такое грамматика? Дайте определения грамматики.

8.Как выглядит описание грамматики в форме Бэкуса-Наура.

9.Какие классы грамматик существуют? Что такое регулярные грамматики?

10.Дайте определения контекстно-свободной грамматики, выво-

димости цепочки, непосредственной выводимости, длины вывода.

11. Что такое конечный автомат? Дайте определение детерминиро-

ванного и недетерминированного конечных автоматов.

12. Какие проблемы необходимо решить при построении сканера на основе конечного автомата?

Пример выполнения работы

Рассмотрим пример анализа лексем, представляющих собой цело-

численные константы без знака в формате языка Си. В соответствии с требованиями языка, такие константы могут быть десятичными, вось-

меричными либо шестнадцатеричными. Восьмеричной константой счи-

тается число, начинающееся с 0 и содержащее цифры от 0 до 7; шест-

надцатеричная константа должна начинаться с последовательности символов 0x и может содержать цифры и буквы от A до F (будем рас-

сматривать только прописные буквы). Остальные числа считаются деся-

23

тичными (правила их записи напоминать, наверное, не стоит). Будем считать, что всякое число завершается символом конца строки .

Рассмотренные выше правила могут быть записаны в форме Бэкуса-

Наура в грамматике целочисленных констант без знака языка Си (тер-

минальные символы грамматики выделены жирным шрифтом).

G({S,G,X,H,Q,Z},{0...9,A...F, },P,S)

P:S G |Z |H |Q G

1|2|3|4|5|6|7|8|9|G0|G1|G2|G3|G4|G5|G6|G7|G8|G9|Z8|Z9|Q8|Q9

H X0|X1|X2|X3|X4|X5|X6|X7|X8|X9|XA|XB|XC|XD|XE|XF| H0|H1|H2|H3|H4|H5|H6|H7|H8|H9|HA|HB|HC|HD|HE|HF

X Zx

Q Z0|Z1|Z2|Z3|Z4|Z5|Z6|Z7|Q0|Q1|Q2|Q3|Q4|Q5|Q6|Q7

Z 0

Хорошо видно, что данная грамматика является регулярной грамма-

тикой (леволинейной). Конечный детерминированный автомат

M’({N,Z,X,H,Q,G,S,ER}, {0...9,A...F, }, ,N,{S}), который распознает язык, заданный этой грамматикой, изображен на рисунке 2. Начальным состоянием автомата является состояние N. В автомат дополнительно введено особое состояние ER, обозначающее ошибку в распознавании цепочки символов. На графе автомата дуги, идущие в это состояние, не нагружены символами. По принятому соглашению они обозначают функцию перехода по любому символу, кроме тех символов, которыми уже помечены другие дуги, выходящие из той же вершины графа. Такое

24

соглашение принято, чтобы не загромождать обозначениями граф авто-

мата (на рис. 2 такие дуги и состояние ER выделены пунктиром).

0...7

8,9

8,9

Z

0

N X

1...9

Q

0...7

 

 

S

 

 

 

 

 

 

x

 

 

 

 

H

 

 

 

 

8...9,A...F

 

 

 

 

8...9,A...F

 

 

 

 

ER

 

 

 

 

G

 

 

 

1...9

 

 

Рисунок 2. Граф конечного детерминированного автомата, распознающего

грамматику целых чисел языка Си

Можно написать программу, моделирующую работу указанного ав-

томата. Ниже приводится текст функции на языке Паскаль, его реали-

зующей. Результат функции истинный (True), если входная цепочка символов принадлежит входному языку автомата. Границей цепочки считается символ с кодом 0 (#0), в функции он искусственно добавляет-

ся в конец цепочки.

В программе переменная iState отображает текущее состояние авто-

мата, переменная i является счетчиком символов входной строки. Ко-

нечно, рассмотренная программа может быть оптимизирована (напри-

25

мер, можно сразу же прекращать разбор по обнаружению ошибки), но в данном примере оптимизация не выполнялась, чтобы можно было четко отследить соответствие между программой и построенным автоматом.

type

TAutoState = ( AUTO_N, AUTO_Z, AUTO_X, AUTO_Q, AUTO_H, AUTO_G, AUTO_ER, AUTO_S );

function RunAuto (sInput: string): Boolean;

 

var

 

iState : TAutoState;

 

i : integer;

 

begin

 

sInput := sInput + #0;

 

iState := AUTO_N;

 

i := 0;

 

repeat

 

i := i + 1;

 

case iState of

 

AUTO_N:

 

case sInput[i] of

 

‘0’:

iState := AUTO_Z;

‘1’..’9’:

iState := AUTO_G;

else

iState := AUTO_ER;

end;

 

AUTO_Z:

 

case sInput[i] of

 

‘0’..’7’:

iState := AUTO_Q;

‘8’,’9’:

iState := AUTO_G;

‘x’:

iState := AUTO_X;

#0:

iState := AUTO_S;

else

iState := AUTO_ER;

end;

 

AUTO_X:

 

case sInput[i] of

 

‘0’..’9’:

iState := AUTO_H;

‘A’..’F’:

iState := AUTO_H;

else

iState := AUTO_ER;

end;

 

AUTO_Q:

 

case sInput[i] of

 

‘0’..’7’:

iState := AUTO_Q;

‘8’,’9’:

iState := AUTO_G;

#0:

iState := AUTO_S;

else

iState := AUTO_ER;

end;

 

26

AUTO_H:

 

case sInput[i] of

 

‘0’..’9’:

iState := AUTO_H;

‘A’..’F’:

iState := AUTO_H;

#0:

iState := AUTO_S;

else

iState := AUTO_ER;

end;

 

AUTO_G:

 

case sInput[i] of

 

‘0’..’9’:

iState := AUTO_G;

#0:

iState := AUTO_S;

else

iState := AUTO_ER;

end;

 

AUTO_ER:

iState := AUTO_ER;

end {case};

 

until (sInput[i] = #0);

 

RunAuto := (iState = AUTO_S);

 

end; { RunAuto }