An attribute grammar can describe more of the structure of a programming language than a context free grammar such as BNF.
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.
Attribute grammars are grammars to which have been added attributes, attribute computation functions and predicate functions.
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_typePredicate: <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
