Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 [ 36 ] 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

int а

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

а:=4 или а + b или read (a) и здесь а будут прикладными реализациями.

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

Во многих языках один и тот же идентификатор может использоваться для представления в разнтх частях программы различнтх объектов. В таких случаях структура программы помогает различать эти объекты, например

begin int a:

end;

begin char a

end .

В первом блоке а имеет вид ref int в Алголе 68 (т. е. ее значение относится к объекту вида int), а во втором- ref char. Так, в этих двух блоках а представляет два разнтх объекта.

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

1. Определяющая реализация идентификатора появляется (текстуально) раньше любой прикладной реализации.

2. Все описания в блоке помещаются непосредственно за begin, т. е. раньше всех операторов или предложений.

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

4. В одном и том же блоке идентификатор не может описываться более одного

раза.

Свойства 3 и 4 присущи практически всем языкам с блочной структурой, свойство 2 характерно для Алгола 60, а свойство 1 представляет собой ограничение, имеющееся в некотортх реализациях этого языка.

Допустим, что синтаксис описаний идентификаторов задается правилами:

DEC -real IDSinteger IDS boolean IDS IDS -id IDS -IDS, id а блок определяется как BLOCK-begin DECS; STATS end



DECS -DECS; DEC DECS-> DEC STATS-STATS;s STATS-s

Таблица символов может иметь такую структуру, как показано ни в любой

betr-

1Юе /

lype

type

Put- (i I

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

Для представления таблицы символов могут использоваться следующие структуры:

mode btab = struct (int leuno, ref idlist idl, ref btab next) mode idlist = struct (int id, type, ref idlist next id)

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

ref btab bptr := nil (нулевой указатель) и выполняются действия, связанные с входом в блок и втходом из него:

BLOCK-begin <AI> DECS; STATS<A2>end

<A1>

bptr := heap btab := (In plusab 1, nil, bptr)

Здесь In представляет номер уровня текущего блока (т.е. глубину вложения) и первоначально является нулем.

<А2>

begin In minusab 1; bptr : = next of bptr end

Предусмотрено также действие для каждой определяющей реализации идентификатора. Это действие появляется в грамматике следующим образом: IDS -id<A3>

IDS, id<A3>

(Заметим, что левая рекурсия позволит нам специфицировать особое действие, связанное с первым идентификатором в списке, а правая рекурсия - конкретное действие для последнего идентификатора.)



Это действие таково:

(A3)

begin ref idlist pnil = nil ; ref idlist ptr : = idl of bptr; bool error : = false ; while pir isnl pnil do

if id of ptr = iden then error : = true ; ptr : = pnil

ptr := next id of ptr od;

if error then print ( ("identifier", iden,"already declared")) else idl of bptr : = heap idlist : = (iden, type, idl of bptr) fi

iden - имя идентификатора, type - его тип. Здесь проверяется, был ли идентификатор уже описан в блоке или нет.

С прикладной реализацией идентификатора связано действие А4, которое отыскивает в таблице символов тип идентификатора:

A4>

begin bool found := false; ref idlist pnil = nil ; ref btab bnil = nil; ref btab b: = bptr; while b isnt bnil and not found do ref idlist ptr : = idl of b ;

while ptr isnt pnil and not found

if id of ptr= iden then type := type of ptr: found : - true fi;

ptr := next id of ptr od;

ft : = next of b od;

if not found

then print ("identifier not dec/ami"):

idl of bptr : = heap idlist : = (iden, default type, idl of hptr):

type : = default tvpe

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

На этом мы завершаем рассмотрение операций, производимтх с таблицей символов, которые требуются для нашего простого языка.

В таблице символов настоящего компилятора может содержаться другая



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 [ 36 ] 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69