Attribute Grammar

An attribute grammar can describe more of the structure of a programming language than a context free grammar such as BNF.

Static Semantics

Some characteristics of programming languages are difficult or impossible to describe with BNF. Type compatibility rules are difficult to describe. The common rule that all variables must be declared before they are referenced is impossible to specify in BNF. the static semantics of a language has to do with the syntax of a language. They are so named because the analysis required to check the static semantics can be done at compile time.

Basic Concepts

Attribute grammars are grammars to which have been added attributes, attribute computation functions and predicate functions.

Attributes
similar to variables in the sense that they can have values assigned to them
associated with grammar rules
Attribute computation functions
aka semantic functions
associated with grammar rules
specify how attribute values are computed
Predicate functions
associated with grammar rules
state some of the syntax and static semantic rules of the language

Attribute Grammars defined

An attribute grammar is a grammar with the following additional features:

The following is a simple attribute grammar:

actual_type synthesized attribute associated with nonterminals <var> and <expr> Used to store actual type, int or real of a variable or expression. For variables actual type is intrinsic. For expressions actual type is determined from actual types of the child nodes

expected_type: inherited attribute associated with nonterminal <expr>. Used to store the type, int or real, expected for the expression

Syntax rule Semantic Rule
<assign>--><var>=<expr>
<expr>.expected_type<--<var>.actual_type
<expr>--><var>[2] + var[3]
       
Semantic rule:
<expr>.actual_type <--
   if (<var>[2].actual_type = int) and
      <var>[3].actual_type=int)
   then int
   else real
   end if
Predicate:
<expr>.actual_type=<expr>.expected_type
<expr>--> <var>
Semantic rule:
<expr>.actual_type <-- <var>.actual_type
Predicate:
<expr>.actual_type = <expr>.expected type
<var>-->A | B | C Semantic Rule
<var>.actual_type<--look-up(<var>.string)

Parse tree for A=A+B