We are interested in the automatic implementation of attribute grammars because of their suitability for specifying the semantic actions of compilers. The translation from source language to target language may be described by an attribute grammar in a natural, modular, and nonprocedural way just as context-free grammars are natural for specification of syntactic analysis. We present a method for converting the nonprocedural semantic description into an efficient procedure for performing the translation, which should be useful in a practical compiler-writing system. Three main ideas are the basis for the method proposed in this paper. The first is the choice of generalized tree traversal algorithms as a framework for constructing evaluators. A treewalk evaluator is a recursive routine receiving as a parameter a tree node to visit; while at a node it may evaluate semantic functions or call itself recursively to visit sons. Such a sequential evaluator avoids the expense of simulating parallelism on today's computers. The second idea is using dependency analysis to choose evaluation orders. The body of a treewalk evaluator is constructed by scheduling attribute evaluations in an order which will satisfy the dependency constraints when executed, enabling the evaluator to do its work without considering data dependencies at run time. Eliminating the overhead of a run-time scheduler greatly improves the efficiency of evaluation. The power of this approach is enhanced by the third main idea: the use of i/o graphs of nonterminals to schedule visits to subtrees. The sons of a node are treated as special semantic, functions which may be partially evaluated to yield certain output attributes when only some of the son's input attributes are available. With the relationship between each nonterminal's inputs and outputs being given by its i/o graph, the process of dependency analysis is able to determine at which points recursive calls should be made. This built-in knowledge of dependency constraints allows the evaluator to always go directly to the next point of evaluation, so that nondeterminism or searching through the semantic tree is necessary. The principle of our construction is to make a plan of action for every situation that can arise during evaluation. The notion of evaluation state is introduced to model the relevant aspects of the situation at a node. The planning algorithm performs dependency analysis in order to find a sequence of instructions that may be executed upon encountering a given situation or entry-state. Evaluators are constructed by an iterative process which repeatedly discovers new situations which can arise and makes plans to deal with them. At the same time a GOTO-table is built up which the completed evaluator will use to select plans for execution. The main data structure during construction is the history graph, which gives all possible evaluation sequences at a node in the form of a flowchart. The resulting evaluators may easily be generated directly in machine code. The construction given here will work for attribute grammars which are absolutely noncircular; for a grammar in this class, an evaluator's action at a node need not depend on the structure of the node's subtrees. The relaxation of this restriction to include "look-down" into subtrees is discussed in[Wa]and will be the subject of a future paper.
CITATION STYLE
Kennedy, K., & Warren, S. K. (1976). Automatic generation of efficient evaluators for attribute grammars. In Conference Record of the Annual ACM Symposium on Principles of Programming Languages (Vol. Part F130832, pp. 32–49). Association for Computing Machinery. https://doi.org/10.1145/800168.811538
Mendeley helps you to discover research relevant for your work.