Грамматика атрибутов - это формальный способ определения атрибутов для создания формальная грамматика, связывающая эти атрибуты со значениями. Оценка происходит в узлах абстрактного синтаксического дерева , когда язык обрабатывается некоторым парсером или компилятором.
Атрибуты делятся на две группы: синтезированные атрибуты и унаследованные атрибуты. Синтезированные атрибуты являются результатом правил оценки атрибутов и могут также использовать значения унаследованных атрибутов. Унаследованные атрибуты передаются от родительских узлов.
В некоторых подходах синтезированные атрибуты используются для передачи семантической информации вверх по дереву синтаксического анализа, в то время как унаследованные атрибуты помогают передавать семантическую информацию вниз и через него. Например, при создании средства языкового перевода, такого как компилятор, его можно использовать для присвоения семантических значений синтаксическим конструкциям. Кроме того, можно подтверждать семантические проверки, связанные с грамматикой, представляющие правила языка, не переданные явно в определении синтаксиса.
Грамматики атрибутов могут также использоваться для перевода синтаксического дерева непосредственно в код для некоторой конкретной машины или на некоторый промежуточный язык.
Одно из преимуществ грамматик атрибутов заключается в том, что они могут передавать информацию из любого места в абстрактное синтаксическое дерево в любое другое место, контролируемым и формальным образом.
Грамматики атрибутов были изобретены Дональдом Кнутом и Питером Вегнером. В то время как Дональд Кнут считается автором общей концепции, Питер Вегнер изобрел унаследованные атрибуты во время разговора с Кнутом. Некоторые зарождающиеся идеи восходят к работе Эдгара Т. «Неда» Айронса, автора IMP.
Ниже приводится простая контекстно-свободная грамматика, которая может описывать язык, состоящий из умножения и сложения целых чисел.
Expr → Expr + TermExpr → TermTerm → Term * FactorTerm → FactorFactor → "(" Expr ")" Фактор → целое число
Следующая грамматика атрибутов может использоваться для вычисления результата выражения, записанного в грамматике. Обратите внимание, что в этой грамматике используются только синтезированные значения, и поэтому она является грамматикой с S-атрибутами.
Expr 1→ Expr 2+ Term [Expr 1.value = Expr 2.value + Term .value] Expr → Term [Expr .value = Term . значение] Термин 1→ Термин 2* Фактор [Термин 1.value = Термин 2.value * Фактор .value] Член → Фактор [Член .value = Фактор .value] Фактор → "(" Выражение ")" [Фактор .value = Выражение .value] Фактор → целое число [Фактор .value = strToInt (integer. str)]
Синтезированный атрибут вычисляется из значений атрибутов дочерних элементов. Поскольку сначала должны быть вычислены значения дочерних элементов, это пример восходящего распространения. Чтобы формально определить синтезированный атрибут, пусть - формальная грамматика, где
Затем, учитывая строку нетерминальных символов и имя атрибута , является синтезированным атрибутом, если выполняются все три из этих условий:
Унаследованные Атрибут в узле дерева синтаксического анализа определяется с использованием значений атрибутов в родительском элементе или братьях и сестрах. Унаследованные атрибуты удобны для выражения зависимости конструкции языка программирования от контекста, в котором она появляется. Например, мы можем использовать унаследованный атрибут, чтобы отслеживать, появляется ли идентификатор слева или справа от назначения, чтобы решить, нужен ли адрес или значение идентификатора. В отличие от синтезированных атрибутов, унаследованные атрибуты могут принимать значения от родителей и / или братьев и сестер. Как и в следующем примере,
, где A может получать значения из S, B и C. B может принимать значения из S, A и C. Точно так же C может принимать значения из S, A, и B.