497
правок
Изменения
Нет описания правки
Грамматика называется '''S-атрибутной''', если с атрибутами выполняются только операции присваивания значений других атрибутов, а внутри транслирующих символов происходят обращения только к атрибутам этого транслирующего символа. То есть используются только синтезируемые атрибуты. Дерево разбора для такой грамматике всегда может быть аннотировано путем выполнения семантических правил снизу вверх, от листьев к корню.
}}
Рассмотрим пример S-атрибутной грамматики.
Выпишем все правила для грамматики арифметических выражений, добавив транслирующие символы и ассоциировав с каждым правилом грамматики список семантических правил.
{| style="background-color:#CCC;margin:0.5px"
!style="background-color:#EEE"| Правило грамматики
!style="background-color:#EEE"| Семантические правила
|-
|style="background-color:#FFF;padding:2px 30px"| $val\ E \to E + T\ \{ADD\ res = op_1 + op_2\}$
|style="background-color:#FFF;padding:2px 30px"| $ADD.op_1=E_1.val \\ ADD.op_2=T.val \\ E_0.val=ADD.res $
|-
|style="background-color:#FFF;padding:2px 30px"| $E \to T$
|style="background-color:#FFF;padding:2px 30px"| $E.val=T.val$
|-
|style="background-color:#FFF;padding:2px 30px"| $val\ T \to T \times F \ \{MUL\ res = op_1 + op_2\}$
|style="background-color:#FFF;padding:2px 30px"| $MUL.op_1=T.val \\ MUL.op_2=F.val \\ T_0.val=MUL.res$
|-
|style="background-color:#FFF;padding:2px 30px"| $T \to F$
|style="background-color:#FFF;padding:2px 30px"| $T.val=F.val$
|-
|style="background-color:#FFF;padding:2px 30px"| $F \to n$
|style="background-color:#FFF;padding:2px 30px"| $F.val=n.val$
|-
|style="background-color:#FFF;padding:2px 30px"| $F \to (E)$
|style="background-color:#FFF;padding:2px 30px"| $F.val=E.val$
|}
<картинка>
После разбора по таким правилам, в атрибуте $val$ корня дерева разбора будет лежать вычисленное значение выражения.
Для изящности можно добавить еще одно правило $S \to E$ и действие(семантическое правило) {print(E.val)}. Тогда сразу после разбора выражения будет напечатан его результат.
Хотя всегда можно переписать синтаксически управляемое определение таким образом, чтобы использовать только синтезируемые атрибуты, зачастую более удобно и естественно воспользоваться также и наследуемыми атрибутами.
Рассмотрим пример с L-атрибутной грамматики.
Выпишем правила и ассоциируем с ними действия(семантические правила) для грамматики объявления переменных:
{| style="background-color:#CCC;margin:0.5px"
!style="background-color:#EEE"| Правило грамматики
!style="background-color:#EEE"| Семантические правила
|-
|style="background-color:#FFF;padding:2px 30px"| $D \to TL$
|style="background-color:#FFF;padding:2px 30px"| $L.in = T.type$
|-
|style="background-color:#FFF;padding:2px 30px"| $T \to int$
|style="background-color:#FFF;padding:2px 30px"| $T.type = integer$
|-
|style="background-color:#FFF;padding:2px 30px"| $T \to real$
|style="background-color:#FFF;padding:2px 30px"| $T.type = real$
|-
|style="background-color:#FFF;padding:2px 30px"| $L \to L,id$
|style="background-color:#FFF;padding:2px 30px"| $L_1.in=L.in \\ addtype(id.entry, L.in)$
|-
|style="background-color:#FFF;padding:2px 30px"| $L_id \to id$
|style="background-color:#FFF;padding:2px 30px"| $addtype(id.entry, L.in)$
|}
Заметим, что в рассматриваемой грамматике присутствует левая рекурсия, в связи с чем некоторые наши примеры имеют искусственный характер, хотя и являются наглядными. Левую рекурсию устраним позже.
Рассмотрим, что происходит с атрибутами при [[Устранение_левой_рекурсии| устранения левой рекурсии]] из грамматики.