Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Лекции по конструированию компиляторов - Глава 6. Контекстные условия языков программирования

6.1. Описание областей видимости и блочной структуры

Задачей    контекстного    анализа    является    установление
правильности использования  объектов. Наиболее  часто решаемой
задачей   является   определение   существования   объекта   и
соответствия его использования контексту, что осуществляется с
помощью анализа типа объекта.
Таким образом  необходимо хранить  объекты, их  типы,  уметь
находить  эти   объекты  и   определять  их  типы,  определять
характеристики контекста. Совокупность доступных в даной точке
объектов  будем  называть  "средой".  Обычно  среда  программы
состоит из частично упорядоченного набора компонент

E={DS1,...DSn}.

Каждая компонента  - это  множество объявлений, представляющих
собой пары :

DSi={},

где под  типом будем  подразумевать  полное  описание  свойств
объекта (объектом,  в  частности,  может  быть  само  описание
типа).
Между компонентами  DSi и  DSj имеет  место  отношение  "DSi
включает DSj"  тогда и только тогда, когда любой объект из DSi
может  быть   доступен  из   DSj  (конкретный  способ  доступа
определяется  правилами  видимости  языка),  но  не  наоборот.
Компоненты образуют  дерево. Это  дерево соответствует  блокам
или процедурам (рис. 6.1

                     +-------------+
                     |  Корневая   |
                     | компонента  |
                     | (программа) |
                     +-------------+
               +---------+  |  +--------+
               |            |           |
         +-----------++-----------++-----------+
         | процедура || процедура || процедура |
         | (блок)    ||   (блок)  ||  (блок)   |
         +-----------++-----------++-----------+
             /|\            /|\         /|\

                            Рис. 6.1

Обычными операциями при работе со средой являются:
- включить объект в компоненту среды;
- найти объект в среде и получить доступ к его описанию;
- образовать в среде новую компоненту, определенным  образом
связанную с остальными;
- удалить компоненту из среды.

Компоненты среды  могут быть  именованы. Поиск  в среде обычно
ведется  с   учетом  упорядоченности  компонент.  Среда  может
включать в  себя как  компоненты,  полученные  при  трансляции
"текущего" текста программы, так и "внешние" компоненты.
Для обозначения  участков программы,  в которых  доступны те
или иные  описания, используются  понятия "область действия" и
"область  видимости".   Областью  действия  описания  является
процедура (блок),  содержащая описание,  со всеми  входящими в
нее (подчиненными  по дереву)  процедурами (блоками). Областью
видимости  описания  называется  часть  области  действия,  из
которой исключены  те подобласти,  в которых  по тем  или иным
причинам описание недоступно.
В разных языках понятия области действия и области видимости
уточняются  по-разному.  В  дальнейшем  изложение  ведется  на
примере языка Модула -2.

6.2. Структура среды Модулы-2

Имеются  четыре   рода  языковых  конструкций,  которые  могут
содержать  описания:   1)  программный   модуль   или   модуль
реализации; 2)  модуль определения; 3) процедура; 4) локальный
модуль.
"Корневую" компоненту  среды в Модуле-2 образует программный
модуль или  модуль реализации.  Объекты этой  компоненты могут
быть описаны  в самом  модуле или  могут быть импортированы из
других  модулей   определений.   Такой   импорт   может   быть
квалифицированным  (from   M  import   X,Y,   ...;)   или   не
квалифицированным (import M;).

 Экспортирующий       Компонента       Импортирующий
 локальный модуль        среды         локальный модуль
+------------+        +------------+     +------------+
| MODULE M1; |        |   +----+   |     | MODULE X1; |
| EXPORT A1;-+--------+-->| A1 |---+--+  | IMPORT A1; |
| .........  |        |   +----+   |  |  |            |
+------------+        |            |  +--+------> A1  |
                      |            |     +------------+
+--------------+      |            |
| MODULE M2;   |      |            |     +------------+
| EXPORT       |      |   +----+   |     | MODULE X2; |
| QUALIFIED A2-+------+-->| M2 |   |     | FROM M2    |
| ............ |      |   +----+   |     | IMPORT A2; |
+--------------+      |     v      | +---+---->A2     |
                      |   +----+   | |   +------------+
                      |   | A2 |---+-+
                      |   +----+   |
+-----------------+   |            |
| MODULE M3;      |   |   +-----+  |
| EXPORT M31;-----+---+-->| M31 |  |     +-------------+
|  +-------------+|   |   +-----+  |     | MODULE X3;  |
|  | MODULE M31; ||   |   +-----+  |     | IMPORT A31; |
|  | EXPORT A31;-++---+-->| A31 |--+-----+--> A31      |
|  | ..........  ||   |   +-----+  |  |  +-------------+
|  +-------------+|   |            |  |
| ................|   |            |  |  +-------------+
+-----------------+   |            |  |  | MODULE X    |
                      |            |  |  | IMPORT M31; |
                      |            |  +--+---> A31     |
                      v            v     +-------------+

+-------------------+ v            v
| MODULE M4;        | |   +-----+  |
| EXPORT M41;-------+-+-->| M41 |  |     +-------------+
|  +---------------+| |   +-----+  |     | MODULE X4;  |
|  | MODULE M41;   || |      v     |     | FROM M41    |
|  | EXPORT        || |   +-----+  |     | IMPORT A41; |
|  | QUALIFIED A41;|+-+-->| A41 |--+-----+----> A41    |
|  | ..........    || |   +-----+  |  |  +-------------+
|  +---------------+| |            |  |  +--------------+
| ..................| |            |  |  | MODULE X     |
+-------------------+ |            |  |  | IMPORT M41;  |
                      |            |  +--+-->A41        |
                      |            |     +--------------+
+-----------------+   |    +----+  |
| MODULE M5;      |   |    | M5 |  |      +-------------+
| EXPORT          |   |    +----+  |      | MODULE X5;  |
| QUALIFIED M51;--+---+-+     v    |      | FROM M5     |
|  +-------------+|   | |  +-----+ |      | IMPORT M51; |
|  | MODULE M51; ||   | +->| M51 |-+------+-> M51.A51   |
|  | EXPORT A51;-++---+-+  +-----+ |      +-------------+
|  | ..........  ||   | |     v    |
|  +-------------+|   | |  +-----+ |
| ................|   | +->| A51 | |
+-----------------+   |    +-----+ |
+-------------------+ |    +----+  |
| MODULE M6;        | |    | M6 |  |      +-------------+
| EXPORT            | |    +----+  |      | MODULE X6;  |
| QULIFIED M61;-----+-+-+     v    |      | FROM M6     |
|  +---------------+| | |  +-----+ |      | IMPORT M61; |
|  | MODULE M61;   || | +->| M61 |-+------+--> M61.A61  |
|  | EXPORT        || |    +-----+ |      +-------------+
|  | QUALIFIED A61;|+-+-+     v    |
|  | ............  || | |  +-----+ |
|  +---------------+| | +->| A61 | |
| ..................| |    +-----+ |
+-------------------+ +------------+

                         Рис. 6.2

В первом  случае импортированные объекты становятся элементами
среды данного  модуля, во  втором - сам импортированный модуль
становится элементом  среды, а его объекты могут быть доступны
через указание имени модуля (M.X).
Область действия  объектов, описанных  в  локальном  модуле,
может состоять  из  самого  этого  локального  модуля  или  из
охватывающего  его   блока,  если   объект  экспортируется  из
локального модуля.  Схему импорта  в  локальный  модуль  можно
пояснить рис.  6.2.  Существует  предопределенная  компонента,
объекты которой  доступны во всех других компонентах (если они
там не  переопределены). Эта  компонента включает  в себя типы
данных такие как, integer, real, boolean, char, word, address,
proc, константы  true, false,  nil, процедуры adr, tsize, cap,
small, chr, inc, dec, float, halt, hihg, odd, ord, trunc, val,
excl, incl, max, min, size, abs.
Элементом  описания   может  быть  процедура  или  локальный
модуль, имеющие свой список описаний. Процедура образует новую
компоненту среды, а локальный модуль - нет (рис. 6.3).
Объекты локального  модуля являются  объектами  охватывающей
компоненты, но  с ограниченными  областями  видимости.  Внутри
локального  модуля  доступны  те  и  только  те  объекты  этой
компоненты, которые  явно импортированы  в локальный модуль. И
наоборот: объекты  локального модуля могут быть экспортированы
в охватывающую  компоненту. В  то же  время объекты  процедуры
образуют новую  компоненту, поскольку  объекты этой компоненты
могут быть  доступны в  процедуре. Конфликт  имен при  этом не
противоречит  определению   компоненты:  объект   охватывающей
компоненты может  быть виден  (если внутри данной процедуры не
описан объект с тем же именем).

              Модуль (программный или реализации)
              +------------+
              |   Среда    |:=true;
2:if Find(Val,Env)Nil
  then Error("Identifire declared twice");
  end;
  Entry:=Include(Val,Env);
  Entry@.Object:=ProcObject.

Помещение процедуры;  ищем объект  с данным  именем в  текущей
компоненте; Entry  - указатель  на вход  для  процедуры.  Если
объект с таким именем уже есть, - ошибка.

RULE
Declaration ::= 'module' Ident Mod_Head Block ';'
SEMANTICS
var M:Import_Pair;
    V:Element;
if Find(Val,Env)Nil
then Error("Identifire declared twice")
end;
Entry:=Include(Val,Env);
Entry@.Object:=LocalModuleObject;
Kind:=false;
3: for M in Imp_Set do Inc_Imp(M,Env);
   end;
if (Mode=NotQual) then
 for V in Entry@.Exp_Set do Export(V,Env);
end end.

Помещение модуля;  ищем  объект  с  данным  именем  в  текущей
компоненте. Если  такой уже  есть, - ошибка. Заносим в текущую
компоненту  среды   объект-модуль.  Множество  Imp_Set  -  это
множество импортируемых  модулем    объектов.  Элементы  этого
множества  -   пары,   первая   компонента   которых   -   имя
импортируемого модуля,  вторая -  список импортируемых из него
объектов.   Если    вторая   компонента    Nil,   то    импорт
неквалифицированный. Если  импортируемый объект  M -  модуль и
если  M   импортируется  неквалифицированно   (IMPORT  M),  то
процедура Inc_Imp  включает M  в среду  текущего модуля;  если
импорт квалифицированный   (FROM  M IMPORT  ...), то  M  имеет
список  импорта   и  процедура   Inc_Imp  включает  в  текущую
компоненту те экспортируемые из M объекты, которые перечислены
в   списке   квалифицированного   импорта;   если   при   этом
импортируемый  объект  -  в  свою  очередь  модуль,  то  из  M
рекурсивно импортируется все его экспортные объекты.
  Атрибут  Mode   вычисляется  в   правиле  для   экспорта   и
определяет,  осуществляется   ли   квалифицированный   экспорт
(EXPORT QUALIFIED  ...) или нет (EXPORT ...). Процедура Export
в случае  неквалифицированного экспорта EXPORT   A1,A2,... все
объекты экспортного  списка модуля заносит в компоненту среды,
охватывающую  модуль;   если  Ai   -   модуль,   его   экспорт
обрабатывается рекурсивно;  если экспорт квалифицированный, то
в охватывающую модуль компоненту попадает только сам модуль со
списком экспорта.

RULE
Block ::= [( Declaration )] [ Block_St_Seq ] 'end' Ident
SEMANTICS
0:Init(Env);
  Pred:=@.

Атрибут Pred - указатель на охватывающий блок.

RULE
Mod_Head ::= [ Priority ] ';' [ ( Import ) ] [ Export ]
SEMANTICS
4E: Mode:=NotQual;
Entry@.Mode:=Mode;
Mode:=Mode;
0:Init(Imp_Set).

Инициализируется список  импорта.  Тип  экспорта  заносится  в
описание модуля.

RULE
Import ::= [ From ] 'import' ( Ident /',' ) ';'
SEMANTICS
var Tmp:Import_Pair;
0:Init(Imp_Set);
1E: Qual:=false;

3A:if Qual then Include(Val,Imp_Set)
   else Tmp.Name_Set:=Nil;
        Tmp.Imp_Name:=Name;
        Include(Tmp,Imp_Set)
   end;
if Qual then
        Tmp.Name_Set:=Imp_Set;
        Tmp.Imp_Name:=Name;
        Include(Tmp,Imp_Set)
end.

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

RULE
From ::= 'from'  Ident
SEMANTICS
Qual:=true;
Name:=Val.

RULE
Export ::= 'export'  [ Qual ]  ( Ident /',' )
SEMANTICS
0: Init(Entry@.Exp_Set);
2Е: Mode:=NotQual;
    Mode:=Mode;
3A: Include(Val,Entry@.Exp_Set).

Включить идентификатор  в экспортный  список модуля; множество
экспортируемых модулем объектов заносится в поле Exp_Set : Key
Name  Set   Of  Element  в  таблице  объектов,  поскольку  при
использовании квалифицированного  импорта или  обращении  M.V,
где M  - имя  модуля,  а  V  -  имя  экспортируемого  объекта,
необходимо иметь доступ к списку квалифицированного экспорта.

RULE
Qual ::= 'qualified'
SEMANTICS
Qual:=Qualified

RULE
Declaration ::= 'var' ( Var_Decl ).

RULE
Var_Decl ::= Ident_List ':' Type_Des ';'
SEMANTICS
var V:Name;
for V in Ident_Set do
   if (Find(V,Env)Nil)
   then Error("Identifire declared twice")
   end;
   Include(V,Env);
   V@.Object:=VarObject;
   V@.Type:=Exit;
end.

V -  рабочая переменная  для  элементов  списка.  Для  каждого
идентификатора из  множества Ident_Set сформировать объект-
переменную  в  текущей  компоненте  среды  с  соответствующими
характеристиками.

RULE
Ident_List ::= ( Ident /',' )
SEMANTICS
0:Init(Ident_Set);
1A:Include(Val,Ident_Set).

RULE
Type_Des ::= Ident
SEMANTICS
var P:pointer to Block;
P:=Block@;
repeat
  Exit:=Find(Val,P@.Env);
  if P@.Kind then P:=P@.Pred
  end;
until (ExitNIL)or(not P@.Kind);
if (Exit=NIL)
then Exit:=Find(Val,Env)
end;
if (Exit=Nil) then Error("тип не найден")
else if (Exit@.ObjectTypeObject) then
         Error("Not type object"); Exit:=Nil;
end  end.

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

          +--------------------+
          |                    |
          |          Block |  EnvEnv     |
          v |         |                   |
+-----> Imp_Set | Mod_Head |           Exp_Set
Назад | Оглавление | Вперед

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог