Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая работа3 / Курсовик.doc
Скачиваний:
18
Добавлен:
01.05.2014
Размер:
1.6 Mб
Скачать

3. Описание этапа лексического анализа.

На входе лексического анализатора находится последовательность ASCII символов, представляющая программу на входном языке. Задача ЛА состоит в разделении этой последовательности на слова языка (лексемы).

  • чтение исходной программы и выделение из нее лексем;

  • построение таблиц идентификаторов и констант;

  • преобразование входной программы (поток символов) в поток токенов, в котором каждый токен представляет лексему.

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

3.1. Определение типов лексем.

Лексический анализатор исключает из текста исходной программы:

- незначащие (повторные) пробелы;

- символы табуляции и перевода строки;

- комментарии (между символами #).

Лексический анализатор не учитывает регистр символа.

Выделяются лексемы следующих типов:

  • идентификаторы (последовательность букв, не начинающаяся с цифры)

  • константы (числовые – целые, вещественные)

  • ключевые слова (void, main, if, else, for, printf, scanf, const, int, float, bool, goto, typedef)

  • знаки операций (+ - ++ -- ~~ * / && || ! = += -= *= /= < > >= <= == !=)

  • разделители ( , . ?: ; ( ) [ ] { } )

3.2. Определение синтаксиса лексем

Синтаксис лексем описывается с помощью автоматных грамматик.

      1. Определим типы токенов, записываемых в выходной поток.

Токен

Лексемы

Языковая конструкция

ID

gfd kj8 jg45gcv …

Последовательность букв и цифр, не начинающаяся с цифры.

Lab

CB

0 1

Логические константы

CI

123  3426 5 …

Целочисленные константы

CF

12.456 3.08 0.453 …

Вещественные константы

Str

“jhgjhvg”

Строковые константы

IF

if

Ключевое слово IF

ELSE

else

Ключевое слово ELSE

MAIN

main

Ключевое слово MAIN

VOID

void

Ключевое слово VOID

FOR

for

Ключевое слово FOR

GOTO

goto

Ключевое слово GOTO

PRINTF

printf

Ключевое слово PRINTF

SCANF

scanf

Ключевое слово SCANF

TYPEDEF

typedef

Ключевое слово TYPEDEF

CONST

const

Ключевое слово CONST

Type

int, float, bool

Базовые типы данных

Vector

vector

Ключевое слово Vector

GOp

+= -= *= /= =

Отношение присваивания

AddOp

+ -

Аддитивная операция

MOp

* /

Мультипликативная операция

RelOp

< > <= >= == !=

Операция отношения

UnOp

++ -- ~~

Унарная операция

LogOp

&& || !

Логическая операция

(

(

Разделитель (

)

)

Разделитель )

{

{

Разделитель {

}

}

Разделитель }

[

[

Разделитель [

]

]

Разделитель ]

,

,

Разделитель ,

.

.

Разделитель .

;

;

Разделитель ;

Sep

: ?

Разделители для условного присваивания

      1. Разработаем структуры данных (таблицы) для хранения лексем различных типов.

1

Идентификатор (ID), метка (Lab)

Индекс

Значение

0

n

2

Целочисленная константа (CI)

Индекс

Значение

0

m

3

Вещественная константа (CF)

Индекс

Значение

0

k

4

Ключевое слово (KeyW)

Индекс

Значение

0

void

1

main

2

if

3

else

4

for

5

goto

6

const

7

typedef

8

printf

9

scanf

10

vector

5

Разделитель (Separator)

Индекс

Значение

0

,

1

.

2

;

3

[

4

]

5

(

6

)

7

{

8

}

9

?:

6

Логическая операция (BOp)

Индекс

Значение

0

!

1

&&

2

||

7

Описатель (Type)

Индекс

Значение

0

int

1

float

2

bool

8

Унарная операция (UnOp)

Индекс

Значение

0

++

1

--

2

~~

9

Операция типа + (AOp)

Индекс

Значение

0

+

1

-

10

Операция типа * (MOp)

Индекс

Значение

0

*

1

/

11

Строковая константа (Str)

Индекс

Значение

0

t

12

Отношение (Rel)

Индекс

Значение

0

<

1

>

2

<=

3

>=

4

==

5

!=

13

Оператор присваивания (GOp)

Индекс

Значение

0

+=

1

-=

2

*=

3

/=

4

=

      1. Определим классы литер входного языка (литеры из одного класса одинаковым образом используются для образования лексем):

класс

терм. символ

литеры

латинская буква

a

a b c … z A B C …Z

цифра

n

0 1 2 3 4 5 6 7 8 9

операция типа +

+

+ -

операция типа *

*

* /

отицание

!

!

отношение

>

> <

операция типа и

&

| &

разделитель

,

( ) [ ] { } , . : ; ?

длина

~

~

кавычка1

кавычка2

знак комментария

#

#

      1. Определим внешние спецификации процедур, описывающих семантику перевода исходного текста программы в строку токенов. Токен будем представлять в виде двух чисел – номера таблицы и индекса в ней.

FormToken – формирует лексему (по приведенному ниже автомату), обращается к другим функциям для работы с таблицами, формирования и вывода токена во входной поток.

ReadL - читает очередную литеру из входного потока, определяет и возвращает ее класс (см. пп. 3).

F_ID (lex) – обрабатывает прочитанную лексему-идентификатор: ищет ее в таблице ключевых слов (KeyW, № 4), если находит – формирует токен, соответствующий ключевому слову – (4 x), где x – номер ключевого слова в таблице . Иначе ищет лексему в таблице типов (Type, №7), если находит, формирует токен (7 x) c соответствующим номером x. Иначе ищет лексему в таблице идентификаторов (ID, № 0), если находит, формирует соответствующий токен (0 x), если нет, то добавляет запись в таблицу идентификаторов и формирует токен (0 n+1), где k – номер последнего идентификатора в таблице до добавления записи.

F_C (i, lex) - обрабатывает прочитанную лексему-число. Если i=0, то ищет в таблице целых чисел (CI, № 1), если i=1 – в таблице вещественных (CF, № 2). Если находит, формирует соответствующий токен (1 x) для целого числа, где x – его номер или (2 y) для вещественного (y – его номер), если нет, то добавляет запись в таблицу и формирует токен (1 n+1) или (2 m+1).

F_Str (lex) - обрабатывает прочитанную лексему-строку. Ищет в таблице строковых констант (Str, № 14). Если находит, формирует соответствующий токен (14 x), если нет, то добавляет запись в таблицу и формирует токен (14 n+1).

F_O (k, lex) – обрабатывает полученную лексему. Ищет лексему в таблице № k, формирует и выводит в выходной поток токен (k x) с найденным индексом x и заданным номером таблицы k.

      1. Построим диаграммы конечных автоматов для каждой лексемы. Начальное состояние – S. Некоторые переходы нагружены процедурами, описанными выше. Некоторые из автоматов объединены.

идент-ры, кл. слова

цел. и вещ. константы

+ - ++ -- += -=

1* - F_ID;

1* - F_C (0); 2* - F_C (1)

1* - F_O (9); 2* - F_O (8)

3* - F_O (13).

! !=

> < >= <= ==

* / *= /= =

1* - F_O (6); 2* - F_O (12)

1* - F_O (12)

1* - F_O (10); 2* - F_O (13)

~~

&& ||

разделители

1* - F_O (3)

1* - F_O (8)

1* - F_O (5)

строковые константы

комментарии

1* - F_Str

      1. Построим общую диаграмму лексического анализатора (конечный автомат).

      1. Тестирование лексического анализатора.

Возьмем в качестве контрольного примера следующую программу на входном языке:

int a=3.2;

vector b[3];

void main()

{

b=[7 a 0.8];

if (b[2]==a)

printf (“a=”,a);

}

В результате работы лексического анализатора получим таблицы:

0

Идентификатор (ID)

Индекс

Значение

0

a

1

b

1

Цел. константа (CI)

Индекс

Значение

0

3

1

7

2

2

2

Вещ.константа (CF)

Индекс

Значение

0

3.2

1

0.8

11

Строковая константа (Str)

Индекс

Значение

0

a=

И поток токенов на выходе:

(7 0)

int

(5 6)

)

(1 2)

2

(0 0)

a

(5 7)

{

(5 4)

]

(11 4)

=

(0 1)

b

(12 4)

==

(2 0)

3.2

(11 4)

=

(0 0)

a

(5 2)

;

(5 3)

[

(5 6)

)

(4 10)

vector

(1 1)

7

(4 8)

printf

(0 1)

b

(0 0)

a

(5 5)

(

(5 3)

[

(2 1)

0.8

(11 0)

“a=”

(1 0)

3

(5 4)

]

(5 0)

,

(5 4)

]

(5 2)

;

(0 0)

a

(5 2)

;

(4 2)

if

(5 6)

)

(4 0)

void

(5 5)

(

(5 2)

;

(4 1)

main

(0 1)

b

(5 8)

}

(5 5)

(

(5 3)

[