On Interpreter-Oriented Definitions of Programming Languages

F. G. Pagan
1976 Computer journal  
The constructive approach to the formal definition of the semantics of programming languages has much in common with the notion that a language can be defined by an actual processor which compiles or interprets programs written in that language. The two approaches can be unified if the processor is written in a sufficiently powerful and expressive high-level language so that it closely models a formal definition for the processed language. The resulting processor has the conceptual clarity of
more » ... e formal scheme as well as the advantages of being executable on a real computer. These points are illustrated by exhibiting a formal definition of a minilanguage using the Vienna Definition Language and an equivalent definition using ALGOL 68. (Received December 1974) 1. Formal semantics of programming languages Hoare and Lauer (1974) have compared and contrasted implicit and constructive approaches to the formal definition of the semantics of programming languages. Implicit definitions are user-oriented and involve formal statements (axioms, etc.) about the properties of programs. Constructive definitions are more implementation-oriented and involve modelling the processing of programs. The constructive schemes might be further subdivided into those which are compiler-oriented and those which are interpreter-oriented. A compiler-oriented language definition primarily consists of the specification of a correspondence between programs and some notation (such as the lambda calculus) which is deemed to be 'fundamental' or is interpreted in a way independent of the language being defined. The present paper is concerned with interpreteroriented definitions, where emphasis is placed on modelling the performance of the actions specified by programs; the translation aspect is de-emphasised or absent, and the interpretation aspect is tailored to suit the defined language. The Vienna Definition Language or VDL (Lee, 1972; Lucas Lauer, and Stigleitner, 1968; Wegner, 1972 ) is probably the best-known formal interpreter-oriented scheme and is the only one considered in any detail in this paper. The bulk of a VDL definition of a particular language consists of instruction definitions specifying the operation of an abstract machine for interpreting programs conforming to a set of abstract syntax rules. A program in this abstract form can be thought of as an unordered tree with labelled branches containing all and only the semantically relevant information necessary for its interpretation. The notion of abstract syntax contributes to the overall conceptual clarity of a VDL definition and removes the necessity for an ad hoc intermediate or object language. Since VDL employs a high-level abstract machine, it has often been preferred to Garwick's proposal (1966) that the definition of a language should consist of an actual processor for the language. The task of constructing a VDL definition, however, is similar in many ways to the implementation of an actual interpreter. The main part of the work consists of writing the instruction definitions, which is very much like programming: the notation is essentially that of a programming language oriented towards tree manipulation. Thus the question arises as to why a sufficiently powerful, real programming language should not be used for this purpose. Some common programming devices are awkward to express in VDL, although the latter is nearly as complicated as many high-level languages; the resulting text is not always very concise or readable, and its understandability would not necessarily be diminished by re-expression in a modern programming language. Moreover, VDL 'programs' lack security from errors (e.g. mismatching of parameter types) and are not mechanically checked for consistency; this is a real disadvantage since manual simulation or proving is generally impractical. An interpreter-oriented language definition expressed in an actual programming language, i.e. a definition in terms of an actual processor, can be at least as good and perhaps better than one expressed in VDL, provided that the defining language is powerful and expressive enough to closely model the VDL scheme. This will be illustrated by using both VDL and ALGOL 68 (van Wijngaarden, 1974) to define a simple minilanguage for integer arithmetic. Informal description and concrete syntax of the minilanguage The language to be defined deals with integer data only, includes no declarations, and does not have a nested scope structure. Variables and constants are ALGOL-like, and the rest of the concrete syntax (the VDL term for the syntax of source programs) is specified by the following BNF production rules: :: = (series) ::= | ; (series) :: = | (read) | [ | (read) :: = 'read' :: = 'write' | , ::= (var) := (exp) (exp) :: = | (exp) :: = | | ((exp» ::= + | -| * | / ::= 'fi' ::= = | > | < | = < | > = |< loop> ::= 'to' 'do' 'end' A series consists of one or more statements separated by semicolons, and there are only five types of statement. A (read) or (write) statement causes the transfer of a number of values equal to the number of variables in the statement. In a loop statement, the number of repetitions of the series is determined by the value of the expression, which is evaluated once at the beginning. The assignment and conditional statements have the obvious ALGOL-like effects. All the arithmetic operators have the same precedence, and evaluation of expressions is from left to right except when modified by parentheses. A sample program follows: *Present address:
doi:10.1093/comjnl/19.2.151 fatcat:kngrnaiberbhhnugeaezxutxla