CONTEXT7 (1131451), страница 2
Текст из файла (страница 2)
Арибут Kind равен true для процедур и false для модулей. Env - множество объявлений блока. Pred - указатель на охватывающий блок.
Mod_Head :: Element * Entry;
SETOF Import_Pair Imp_Set;
bool Mode.
Imp_Set - множество импортируемых модулем объектов; тип Import_Pair - запись из двух полей: Imp_Name:Name - имя импортируемого объекта, и Name_Set:Set of Name - список импортируемых из модуля объектов, если импорт квалифицированный, и Nil, если неквалифицированный; Entry - указатель на вход для модуля; Mode - признак квалифицированного экспорта.
Import :: SETOF Name Imp_Set.
Imp_Set - список квалифицированного импорта.
Export :: bool Mode.
Mode - признак квалифицированного экспорта.
From :: bool Qual; TName Name.
Qual :: bool Qual.
Ident_List :: SETOF Name Ident_Set.
Type_Des :: Element * Exit.
Qual - признак квалифицированного импорта; Name - имя модуля, из которого делается импорт; Ident_Set - список идентификаторов; Exit - указатель на описание типа.
RULE
Declaration ::= 'procedure' Ident [ Formal_Param ] ';'
Block ';'
SEMANTICS
Element* Entry;
Kind<5>=true;
2:if (Find(Val<2>,Env<Block>)!=NULL)
Error("Identifire declared twice");
Entry=Include(Val<2>,Env<Block>);
Entry->Object=ProcObject.
Помещение процедуры; ищем объект с данным именем в текущей компоненте; Entry - указатель на вход для процедуры. Если объект с таким именем уже есть, - ошибка.
RULE
Declaration ::= 'module' Ident Mod_Head Block ';'
SEMANTICS
Import_Pair M;
Element * V;
if (Find(Val<2>,Env<Block>)!=NULL)
Error("Identifire declared twice");
Entry<3>=Include(Val<2>,Env<Block>);
Entry<3>->Object=LocalModuleObject;
Kind<4>=false;
3: for (M in Imp_Set<3>) Inc_Imp(M,Env<4>);
if (Mode<3>==NotQual)
for (V in Entry<3>->Exp_Set) Export(V,Env<Block>).
Помещение модуля; ищем объект с данным именем в текущей компоненте. Если такой уже есть, - ошибка. Заносим в текущую компоненту среды объект-модуль. Множество 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<0>);
Pred<0>=&<Block>.
Атрибут Pred - указатель на охватывающий блок.
RULE
Mod_Head ::= [ Priority ] ';' [ ( Import ) ] [ Export ]
SEMANTICS
4E: Mode<4>=NotQual;
Entry<0>->Mode=Mode<4>;
Mode<0>=Mode<4>;
0:Init(Imp_Set<0>).
Инициализируется список импорта. Тип экспорта заносится в описание модуля.
RULE
Import ::= [ From ] 'import' ( Ident /',' ) ';'
SEMANTICS
Import_Pair Tmp;
0:Init(Imp_Set<0>);
1E: Qual<1>=false;
3A:if (Qual<1>) Include(Val<3>,Imp_Set<0>);
else {Tmp.Name_Set=NULL;
Tmp.Imp_Name=Name<3>;
Include(Tmp,Imp_Set<Mod_Head>);
}
if (Qual<1>)
{Tmp.Name_Set=Imp_Set<0>;
Tmp.Imp_Name=Name<1>;
Include(Tmp,Imp_Set<Mod_Head>);
}.
Если импорт квалифицированный, то Name<1> - имя модуля, из которого делается импорт. В этом случае Imp_Set<0> - множество импортируемых из него объектов. Идентификатор включается в список импорта из модуля, иначе идентификатор - имя модуля и он включается в список импортируемых модулей. Если импорт квалифицированный, включить в список импорта модуля весь список импортируемых объектов.
RULE
From ::= 'from' Ident
SEMANTICS
Qual<0>=true;
Name<0>=Val<2>.
RULE
Export ::= 'export' [ Qual ] ( Ident /',' )
SEMANTICS
0: Init(Entry<Mod_Head>->Exp_Set);
2Е: Mode<2>=NotQual;
Mode<0>=Mode<2>;
3A: Include(Val<3>,Entry<Mod_Head>->Exp_Set).
Включить идентификатор в экспортный список модуля; множество экспортируемых модулем объектов заносится в поле Exp_Set : Key Name Set Of Element в таблице объектов, поскольку при использовании квалифицированного импорта или обращении M.V, где M - имя модуля, а V - имя экспортируемого объекта, необходимо иметь доступ к списку квалифицированного экспорта.
RULE
Qual ::= 'qualified'
SEMANTICS
Qual<0>=Qualified.
RULE
Declaration ::= 'var' ( Var_Decl ).
RULE
Var_Decl ::= Ident_List ':' Type_Des ';'
SEMANTICS
Element V;
for (V in Ident_Set<1>)
{if (Find(V,Env<Block>)!=NULL)
Error("Identifire declared twice");
V.Object=VarObject;
V.Type=Exit<3>;
Include(V,Env<Block>)
}.
V - рабочая переменная для элементов списка. Для каждого идентификатора из множества Ident_Set<1> сформировать объект-переменную в текущей компоненте среды с соответствующими характеристиками.
RULE
Ident_List ::= ( Ident /',' )
SEMANTICS
0:Init(Ident_Set<0>);
1A:Include(Val<1>,Ident_Set<0>).
RULE
Type_Des ::= Ident
SEMANTICS
Block * P;
P=&<Block>;
do{
Exit<0>=Find(Val<1>,P->Env);
if (P->Kind) P=P->Pred;
}
while (Exit<0>==NULL)&&(P->Kind);
if (Exit<0>==NULL)
Exit<0>=Find(Val<1>,Env<Prog>);
if (Exit<0>==NULL) Error("Type Description not found");
else if (Exit<0>->Object!=TypeObject)
{Error("Not type object");
Exit<0>:=Nil;
}.
Рабочая переменная P - указатель на ближайший охватывающий блок. Переходя от блока от блоку, ищем объект в его среде. Если не нашли, то, если блок - процедура, перейти к охватывающей. Если дошли до границы модуля, попытаться найти объект в предопределенной компоненте. Если объект нашли, надо убедиться, что он - тип.
Зависимости атрибутов на дереве разбора приведены на рис. 5.5.
Block Env
Dec_List
Declaration
Block
Env
Imp_Set Mod_Head Exp_Set
Imp_List
Export
Import Import
Imp_Set
From Ident Ident
Ident
Ident Ident Ident Ident
Рис. 5.5