Атрибутные МП-автоматы отличаются от обыкновенных МП-автоматов тем, что символы и состояния снабжены атрибутами, которые обрабатываются в процессе его работы. Атрибутный МП-автомат обладает следующими свойствами:
1) Все входные, выходные и магазинные символы, а также состояния имеют конечное число атрибутов.
2) На каждом шаге работы атрибутного МП-автомата значения атрибутов нового состояния, нового верхнего символа магазина (если этот шаг не выталкивание из магазина) и выходных символов вычисляются как функция атрибутов старого состояния, верхнего символа магазина и входного символа (если это не пустой шаг).
Определение 4.3.3. [17]. Атрибутный МП-преобразователь – это система из 11 объектов:
M = <Q, I, Y, Г, , q, Z, A, C, u, v>,
где Q – конечное множество состояний;
I – конечное множество входных символов;
Y – конечное множество выходных символов;
Г – конечное множество магазинных символов;
qQ – начальное состояние;
ZГ – начальный магазинный символ;
A – множество возможных значений атрибутов;
С – функция из QI
Y
Г во множество неотрицательных целых чисел, определяющая, сколько атрибутов имеет каждый символ; посредством
будет обозначаться расширение С на множество { Q
I
Y
Г}*, получаемое, если положить
(
) =
и
(
) = С(
)+С(
), где
– пустой символ,
– символ,
– цепочка символов;
uAC(q) – множество значений атрибутов для начального состояния;
v AC(q) – множество значений атрибутов для начального магазинного символа;
– отображение {Qx {I
{
}}xГ} во множестве конечных множеств четверок, такое, что если
(r,
,
) содержит (p,
,
, f), то p
Q,
Г*,
Y* и f – вычислимая функция, кроме того всякие две четверки в
(r,
,
) отличаются по крайне мере одной из трех своих компонент.
Атрибутный МП-преобразователь называют детерминированным, если:
1) для любых rQ и
Г всякий раз, когда
(r,
,
) не пусто,
(r,
,
) пусто для всех
;
2) отображает аргумент во множество, состоящее не более чем из одного элемента.
Конфигурация атрибутного МП-преобразователя — это четверка (r, х, , у), где r — атрибутное состояние, х — цепочка атрибутных входных символов,
— цепочка атрибутных магазинных символов, у — цепочка атрибутных выходных символов. Если конфигурация имеет вид (rg,
h, x,
,
, y), где r — состояние со множеством атрибутов g,
I
{
} имеет множество атрибутов h,
— магазинный символ со множеством атрибутов i, и
(r,
,
) содержит (р, n,
, f), то мы пишем:
(rg, h, x,
,
, y)
(
,
x,
,
, y),
где ,
,
– это p,
,
, соответственно с атрибутами, вычисленными в результате применения функции f к атрибутам из g, h, i.
Рефлексивное транзитивное замыкание отношения обозначается как
*
Если
(qu, x, Zv,)
*(p,
,
, y),
т.е. цепочку называют трансляцией цепочки х, выполняемой атрибутным МП-преобразователем.
Теорема 4.3.1. [17]. Любую трансляцию, определяемую L-атрибутной трансляционной грамматикой, у которой входная грамматика является LL(1)-грамматикой, можно выполнить на атрибутной детерминированной МП-машине с концевым маркером.
Доказательство данной теоремы [17] является, no-существу, описанием алгоритма построения атрибутного МП-преобразователя по трансляционной LL(K)-грамматике. Воспроизведем основные шаги этого алгоритма.
Пусть I — входное множество трансляционной грамматики, Y — множество операционных символов (символов действий), N — множество нетерминалов. Перенумеруем правила грамматики числами от 1 до га, где m — число правил в грамматике. Пусть в правой части i-го правила содержится ni символов.
Атрибутный МП-преобразователь имеет вид
M = <{q}, I, Y, {z}{(i, j) | 1
i
m, 0
j
n},
, q, Z, A, C, u, v>,
где q, Z – произвольные новые имена, А – множество значений атрибутов грамматики, u – произвольно, C, v, определяют ниже.
Для I
Y значение С(
) равно числу атрибутов, которыми обладает
в грамматике. Для Z C(Z) =
, для q C(q) = max C(
), где
. Для каждого магазинного символа вида (i, j) значение C((i, j)) равно сумме числа атрибутов первых j = 1 символов правой части i-го правила и числа унаследованных атрибутов нетерминала, стоящего в левой части правила.
Атрибутный МП-автомат выполняет нисходящий разбор. Когда магазинный символ (i, j) находится наверху магазина, значения унаследованных атрибутов левой части 1-го правила и всех атрибутов первых j символов правой части известны — они равны значениям соответствующих атрибутов состояния (для j-ro символа правой части) и верхнего символа магазина (для первых j = 1 символов его правой части).
Магазинный символ Z используется только лишь для инициализации работы магазина и после первого же такта работы автомата выталкивается из магазина. Символ Z в первом такте заменяется на (i, 0)—это означает, что начальный символ грамматики разворачивается по i-му правилу. При этом символ (i, 0) имеет столько атрибутов, сколько имеется унаследованных атрибутов у начального символа грамматики, а их значения полагаются равными значениям, которые заданы для унаследованных атрибутов в грамматике.
Когда верхний символ магазина имеет вид (i, j), где j = ni, это означает, что i-е правило применилось успешно.
Очередное действие автомата — подмножеству атрибутов состояния присваиваются значения атрибутов левой части правила, а верхний символ выталкивается из магазина. При этом значения унаследованных атрибутов равны значениям соответствующих атрибутов символа (i, j). Значения синтезированных атрибутов вычисляются по значениям атрибутов символа (i, j) и состояния q.
Действия МП-автомата, когда верхним символом магазина является символ (i, j), где j<n, зависят от того, является ли (j+1) символ правой части правила входным, нетерминальным или операционным. Во всех этих случаях символ (i, j) будет замещен символом (i, j+1), а значения атрибутов этого символа будут вычисляться по значениям атрибутов символа (i, j) и состояния q. Действия же автомата для различных типов символа (i, j+1) будут различны. Обозначим (j+1)-й символ 1-го правила через а и рассмотрим основные случаи.
Случай 1. , т.е. а — входной символ. Если
совпадает с текущим входным символом, то атрибутам состояния q присваиваются значения атрибутов символа
.
Случай 2. Y, т.е.
— операционный символ. Унаследованные атрибуты для
вычисляются по значениям атрибутов символа (i, j) и состояния q. Синтезированные атрибуты вычисляются после нахождения значений унаследованных. После этого символ
вместе со значениями его атрибутов выводится на выходную ленту МП-преобразователя.
Случай 3. , т.е.
— нетерминальный символ. МП-преобразователь выбирает k-e правило, левой частью которого является а, и помещает на верх магазина (над символом (i, j+1)) символ (k, 0), присваивая его атрибутам значения унаследованных атрибутов символа. Впоследствии, когда символ (i, j+1) вновь станет верхним символом магазина (после выталкивания символа (k, nk)), значения атрибутов символа
будут равны значениям некоторых атрибутов состояния.
Пример 4.3.2. Процесс построения атрибутного МП-преобразователя рассмотрим на примере трансляции оператора описания переменных в некотором гипотетическом языке программирования. Будем полагать, что описание переменных задается, например, в виде:
real i1, i4, i9.
Здесь символ ik является идентификатором, индекс k является атрибутом, причем значением этого атрибута служит указатель на позицию таблицы идентификаторов, сопоставленную данному идентификатору. Для каждого идентификатора во время трансляции необходимо выполнить операцию ALLOCATE. В результате выполнения этой операции в позицию таблицы идентификаторов, соответствующую данному, заносится адрес ячейки памяти, выделяемой этому идентификатору. Будем считать, что для идентификатора выделяется одна ячейка памяти. Выделяются ячейки последовательно, начиная с ячейки с адресом 50. Операция ALLOCATE реализуется одноименной семантической программой, которая имеет два входных параметра: указатель на соответствующую позицию таблицы идентификаторов, а также адрес выделенной для идентификатора ячейки памяти.
Описанный содержательно процесс трансляции (семантика) оператора описания переменных может быть формально задан с помощью L-атрибутной трансляционной грамматики, приведенной на рис. 4.11 [17].
Нижние символы возле символов грамматики — имена атрибутов, верхние — имена магазинных символов для МП-преобразователя, задаваемые в виде пары (i, j), где i — номер правила, j — позиция символа в правиле. Для входной цепочки real i1, i4, i9, данная грамматика порождает следующую активную цепочку:
real i1, {ALLOCATE}1, 50, i4 { ALLOCATE}4, 51, i9 {ALLOCATE}9,52
Для построения атрибутного МП-преобразователя, выполняющего такие трансляции, будем использовать результаты теоремы [17].
Y = {{ALLOCATE}a2,x2} – множество операционных символов;
Sx1, z2 – наследуемый х1, синтезируемый z2
Rx1, x2 – наследуемый х1, синтезируемый х2
{ALLOCATE}a2,x2 – наследуемые а2, х2
Рис. 4.11. L-атрибутная трансляционная грамматика для оператора описания переменных
Имеем:
{q} = {q, ДОПУСТИТЬ, ОТВЕРГНУТЬ} – множество состояний МП-преобразователя;
I = {real, ia1, ,} – множество входных символов;
Г = {#, (1,0), (1,1), (1,2), (1,3), (2,0), (2,1), (2,2), (3,0)) – множество магазинных символов. Отображение зададим в виде равенств вида
(q, x, y) = (q,
,
),
где х – входной символ, у – магазинный символ, – новый магазинный символ (или цепочка символов),
– выходной символ. Если x =
, то это означает — любой входной символ без сдвига входной ленты, если
=
, то выполняется только выталкивание символа из магазина, если
=
, — на выходную ленту ничего не записывается. Имеем:
(q, real, (1, 0)) = (q, (1, 3), (1, 2), (1, 1),
);
(q, i, (1, 1)) = (q,
,
);
(q,
, (1, 2)) = (q,
, (1, 2));
(q, , , (1, 3)) = (q, (2,0),
);
(q,
, (2, 0)) = (q, (2, 3), (2, 2), (2, 1),
);
(q, i, (2, 1)) = (q,
,
);
(q,
, (2, 2)) = (q,
, (2, 2));
(q, , , (2, 3)) = (q, (2,0),
);
(q,
, (2, 3)) = (q, (3,0),
);
(q,
, (1, 3)) = (q, (3,0),
);
(q,
, (3, 0)) = (q,
,
);
(q,
, #) = (ДОПУСТИТЬ,
,
);
Во всех других ситуациях автомат переходит в состояние ОТВЕРГНУТЬ.
Последовательность конфигураций МП-преобразователя при выполнении трансляции входной цепочки real i1, i4 – будет следующей:
(q0,0,0, real i1, i4 , #(1,0)50,0,
)
(q50,0,0, i1, i4 , #(1,3)0,0 (1,2)0,0 (1,1)0,
)
(q50,1,0, , i4 , #(1,3)51,0 (1,2)1,50
)
(q50,1,51, i4 , #(2,0)51,0 (1,2)1,50)
(q50,1,51, , #(2,3)0,0 (2,2)0,0 (2,1)0,0 (1,2)1,50)
(q50,4,51, , #(2,3)52,0 (2,2)4,51 (1,2)1,50)
(q50,4,51, , #(3,0)52,52 (1,2)1,50 (2,2)4,51)
(q50,4,51, , #(1,2)1,50 (2,2)4,51)
(ДОПУСТИТЬ,, #(1,2)1,50 (2,2)4,51)
Таким образом, на выходной ленте атрибутного МП-преобразователя будет сформирована следующая операционная часть активной цепочки:
{ALLOCATE}1,50, {ALLOCATE}4,51.