1

I've read about attribute grammars, but I haven't found out, how are the attributes often implemented?

To me they scream objects (of classes), but they could be also variables.

But are there any general rules as to how the attributes should be implemented in a practical implementation? Or is it free form?

Raphael
  • 73,212
  • 30
  • 182
  • 400
mavavilj
  • 579
  • 7
  • 23

3 Answers3

3

Attribute grammars are a conceptual tool. You are mixing this up with implementation details.

There are many parser generators around (check for example the Wikipedia pages on compiler compilers and comparison of parser generators). They all implement some flavor of attribute grammar, in actual use you aren't interested in a parse tree or a derivation. The most used ones are (direct descendants of) old designs, which predate the current object oriented craze, and write parsers implemented in languages like C, with no objects.

vonbrand
  • 14,204
  • 3
  • 42
  • 52
1

Broadly speaking, there are two approaches to implementing attribute grammars:

  1. Topological Sort

    A tool is used to analyze the definition of attributes and determine an evaluation order for them. This can be done by doing a topological sort on the attribute definitions with dependencies between them as the ordering. This order can then be baked into an implementation (e.g., through code generation). However, it is not always so straightforward. Evaluating an attribute grammar may require multiple passes over the tree or an arbitrary, source-dependent number of passes up and down the tree. It is my understanding that this has been the subject of academic research, but I am not familiar with any of the literature.

  2. Lazy Evaluation

    Each attribute is evaluated lazily on demand, and the result may or may not be cached. If a cycle is encountered at runtime, different strategies may be employed. Some tools fail to terminate (e.g. Happy "you can write an attribute grammar which fails to terminate. This generally happens when semantic rules are written which cause a circular dependency on the value of an attribute."). Other tools will detect the cycle and throw an exception. Some tools support calculating the fixed point if specifically requested (e.g. JastAdd Circular Attributes "The evaluation stops when the value equals that for the previous iteration."). Lazy evaluation seems to be the approach most modern tools use.

You could look at some of the attribute grammar tools for more details. I am aware of JastAdd (Lazy, Java), Happy (Lazy, Haskell), and Silver (Lazy, Java).

1

I do not know any specific implementations, but here are two ideas a annotate nodes w.r.t an attribute grammars:

  1. A recursive algorithm can evaluate top-down and bottom-up rules in two passes over the tree.

    You may want to implement it using the visitor pattern

  2. Use the iterator pattern.

    Note that the order of iteration is crucial -- decide between pre-, in- and post-order. In order to do emulate the recursive approach you need (at least) pre- and post-order, one after the other.

Raphael
  • 73,212
  • 30
  • 182
  • 400