Generating an Interpretive Language Implementation From a Layered Operational Model Michael J. Oudshoorn
Chris D. Marlin
E-mail:
[email protected] Phone: +61 8 228 5833 Fax: +61 8 223 1206
E-mail: marlin@cs. inders.edu.au Phone: +61 8 201 2662 Fax: +61 8 201 3626
Department of Computer Science, The University of Adelaide, G.P.O. Box 498, Adelaide, S.A. 5001 Australia
Discipline of Computer Science, Flinders University of S.A., G.P.O. Box 2100, Adelaide, S.A. 5001 Australia
Abstract | This paper describes a technique for the automatic generation of an interpretive im-
plementation for a programming language from a layered operational semantic description of the language. Layers in the semantic model represent levels of abstraction which correspond to the needs of various classes of user of the semantic description (programmers, language designers, and so on). The layers are built one atop the other, with the innermost layer of the model being based on the algebraic speci cation of abstract data types. Dierent kinds of user can thus use the same language de nition, examining it to diering levels of detail. The complete layered programming language de nition can be submitted to a system which automatically generates an interpretive implementation of the language. The implementation will hence be consistent with the description of the language being used by each kind of user. In particular, this technique presents many advantages for language designers, since aspects of the language description within any of the layers may be altered and a new experimental implementation obtained.
1 Introduction Programming languages are frequently speci ed using some natural language, such as English; this is especially true of languages in wide use, such as Pascal, Ada and COBOL. In order to reduce the possibility of ambiguity, such de nitions have large amounts of technical jargon. However, this creates problems for users of the resulting language speci cations, such as compiler writers and programmers, since the speci cations are dicult to read and understand, while not fully eliminating ambiguities. These diculties can be illustrated by considering the history of the Pascal language de nition over the twelve-year period from 1970 to 1982. This period saw several documents become the de nitive one [2, 13, 14, 15, 29], with increasing amounts of technical jargon incorporated into each revised language standard. For languages speci ed in this manner, it is common to nd two compilers for the language behaving in dierent ways, although supposedly both conforming to the same language de nition. It is becoming increasingly obvious that natural language is not the ideal medium for the communication of language semantics between the designer, compiler writer and programmer. Current trends are toward 1
formal techniques such as attribute grammars [26], denotational semantics [6, 25] and the Vienna De nition Method [1]. Such formalisms are more precise than natural language and many have the additional advantage that they lend themselves to the automatic generation of compiler components. However, language speci cations written using these formalisms are frequently dicult to understand and hence not suitable for use by some classes of potential user of the speci cation (such as programmers). Thus, it is usual for a programming language to have its semantics speci ed in a number of ways { such as through textbooks, formal semantic descriptions, natural language speci cations, and so on. Interestingly, it is most common in such situations for a natural language speci cation to represent the ocial de nition of a language; this is the case, for example, with Ada [27] and Pascal [2]. Not surprisingly, having multiple speci cations of a language creates further problems: in particular, these speci cations are likely to be inconsistent. The interpretive implementation technique described in this paper is based on the use of a layered semantic model, the layers of which represent levels of abstraction corresponding to the needs of various classes of user of the semantic description. Thus, a programmer might be expected to consult only the uppermost layer of the model, whereas a language designer would want to examine deeper layers as well. Unlike the (potentially mutually inconsistent) multiple speci cations mentioned above, these layers form a single language de nition which caters for the disparate needs of these diverse classes of user. This paper describes ATLANTIS (A Tool for LANguage de niTion and Interpreter Synthesis), a system which generates an interpretive implementation from a speci cation written using the layered semantic model. The implementation generated by ATLANTIS is thus consistent with all the layers of the language speci cation and will appear to all classes of reader of the language speci cation to be a faithful implementation according to that speci cation. This bene ts all classes of user of the speci cation, but is particularly important to the designer of the speci ed language, since it provides an implementation prototype of the language. ATLANTIS allows a language designer to design, de ne and implement a new programming language as a single activity. Furthermore, the designer can easily modify any aspect of the language speci cation and then obtain another experimental language implementation which is consistent with the new de nition. Since the interpreter mimics the formal language de nition, the language designer is able to compare the interpreter's observed behaviour with its intended behaviour and gain some assistance in producing a language de nition which corresponds to what the language designer intended. After the design of the language is complete, the interpreter acts as a correct implementation of the language against which more ecient compilers can be compared. ATLANTIS represents an improvement over current technology and formalisms in that it provides a practical langauge de nition from which an interpreter can be generated whilst providing a structured de nition which caters for the disparate needs of potential readers. Furthermore, since an implementation is generated directly from the language de nition, a language designer can evaluate the language at various times of its development. Section 2 provides a brief summary of the model which underlies the ATLANTIS system. Section 3 considers the language de nition process, discussing the manner in which ATLANTIS de nes the syntax and 2
Definition of the Language Features
High Level Operations
Algebraic Specifications of ADTs
Figure 1. The structure of the ATLANTIS model. semantics of a language and the way in which this de nition is transformed to produce an implementation prototype. The nal section puts forward some conclusions and gives an indication of planned future work.
2 Language speci cation The model which forms the basis for ATLANTIS is a multi-layer information structure model based on abstract data types (ADTs); this model is described more fully in [20, 22]. The semantics of language features is given in terms of manipulations of some data structures known as information structures. Basing the model on ADTs provides the necessary degree of formality to enable the automatic derivation of an implementation prototype, and provides the key to the layering within the model. The innermost layer de nes the information structures used in the model in terms of ADTs, these being speci ed algebraically using the techniques in [7, 8, 11]. The middle layer combines ADT manipulations into operations known as high-level operations (HLOs) and the outermost layer describes the language features. Readers of the language de nition are then able to read to the depth they require; each layer is accompanied by a natural language commentary, which is not considered to be a part of the language de nition proper. The structure of the model is illustrated in Figure 1. Note that the semantics of a language feature is described in terms of transformations on the information structures in an operational fashion. Three aspects of a language de nition are catered for by the ATLANTIS system: the lexical, syntactic and semantic aspects. The lexical symbols are de ned rst, their de nition taking the form shown in Figure 2. In order to facilitate alteration of the language de nition during the design phase, the designer must specify a token to match each of the keywords and symbols of the programming language. Hence, if the designer wishes to change a keyword, only one change needs to be made to the language de nition. Operators are also de ned in this lexical section and it is here that their precedence level and associativity is speci ed. Finally, special lexical tokens are de ned in terms of an EBNF de nition, as shown in Figure 2. These special tokens have a speci c form or structure to which they must adhere, rather than a prede ned sequence of predetermined characters arranged in a certain order as for reserved words such as \begin". Typical special lexical tokens include identi ers, strings and comments. 3
Language Example is Case Independent Keywords { { Comments are as in Ada. begin sym begin; plus n+; { { \n+" represents the plus sign. Operators :::
plus
2
left; { { precedence of 2 and left-associative.
:::
Special
{ { nl denotes the set of all uppercase { { and lowercase letters. { { f g+ denotes one or more { { occurrences of Figure 2. An extract from the lexical portion of an ATLANTIS de nition. identi er
fnlg+;
:::
:::
BLOCK:
%% Pass 2: call Scope Rules Pass 2; %% [ LABEL DECLARATION PART ] [ CONSTANT DEFINITION PART ] [ TYPE DEFINITION PART ] [ VARIABLE DECLARATION PART ] [ PROCEDURE AND FUNCTION DECLARATION PART ] %% Pass 1: call Scope Rules Pass 1; %% STATEMENT PART
Figure 3. De nition of a Pascal block. The second and third aspects of a programming language de niton are closely related. ATLANTIS uses EBNF to specify the language syntax and intersperses the semantic de nition throughout the EBNF to clearly indicate the places where the semantic actions occur. The result is a syntactic de nition of the language which is similar in appearance to yacc [16], but diers from it in that EBNF (rather than BNF) is used to describe the language syntax. Furthermore, dierent nonterminal symbols may have identical syntactic derivations which may be decorated with dierent semantic actions. Figure 3 shows an example of the mixed syntax and semantics for the de nition of a Pascal block, according to that described less formally in [2]. Uppercase identi ers represent syntactic units which may be de ned elsewhere. Text enclosed between \[ ]" denotes optional objects. Semantic regions are delimited by \%%" and correspond to calls to semantic routines in the outermost layer of the information structure model mentioned earlier. If the language requires multiple passes to describe its semantics, then the pass on which the semantic action is to have an eect is speci ed, using the notation \Pass n: ". All actions within a semantic region are evaluated during the speci ed pass. If no particular pass is speci ed, then the semantic actions will be applied during the rst pass by default. This technique not only ties the semantic actions to the syntax of the language, breaking it into multiple passes to highlight the relationship between aspects of the language, but also encourages the separation of the static and dynamic semantics. This separation makes the language de nition easier to use, both when developing the language initially and when reading and understanding the de nition. This is unlike :::
:::
4
PROCEDURE DECLARATION: procedure sym ident %% Pass 1: call add procedure to symbol table; call create block; %% %% Pass 2: call enter block; call inherit via scope rules(nonlocal); %% FORMAL PARAM LIST semicolon DECLARATION SEQUENCE %% Pass 1: call inherit via scope rules(local); %% BLOCK;
Figure 4. An example of syntax and associated semantic actions. most natural language descriptions, which mix the two semantic aspects in an almost inseparable manner (see [2, 27], for example), and most other formal techniques which describe the static semantics well, but fail to fully capture the dynamic semantics (attribute grammars), or capture the dynamic semantics in such with such a terse and mathematical notation that renders it useless to the majority of potential users (denotational semantics). The result of the ATLANTIS approach is a syntactic de nition of the language which is reasonably easy to read and understand, while simultaneously having the semantic description rmly embedded within it, as shown in Figure 4. The semantic de nitions are based on the information structure model mentioned earlier. The semantics of the programming language is de ned through the execution to the semantic regions which constitute the outermost layer of the model. The execution of a semantic region involves calls on a number of semantic routines; examples of these calls are to be found in Figure 4. The semantic routines are de ned as HLOs mentioned earlier. In this manner, manipulations on the underlying information structure model are speci ed. The middle layer of the model presents the HLOs used in the language de nition. These HLOs have the external appearance of parameterized procedures and functions. The HLOs employ operations provided by the ADT de nitions in the layer below to perform the necessary information structure manipulations. Figure 5 provides the de nition of the HLO \inherit via scope rules" used in Figure 4. Comments in Figure 5 provide an explanation of the events which take place within the HLO. The instructions within a HLO consist of calls to other HLOs, execution of primitive ADT operations to manipulate the data structures and the use of assignment sequencing constructs such as for-loops and if-statements. The constructs available for use within ATLANTIS can all be formally de ned. The innermost layer of the semantic de nition of a programming language gives the de nition of the information structures used. This de nition is given in terms of a collection of ADT de nitions in the style of the ADJ group [8] and Guttag [11]. The ADTs can be shown to be consistent and suciently-complete (i.e., 5
procedure inherit via scope rules (decl: declaration) is
{{ inherit from the parent block any identi ers which are not already {{ present in the current block, provided that they are de ned as being {{ local or nonlocal as speci ed by the parameter decl.
var parent: sym table; var attrib, new attrib: attributes; var this block: block table; begin { { inherit via scope rules
{ { Locate the parent block. parent := father(sym); { { If the parent's symbol table is non empty if info de ned(parent) then { { For each object in the parent's symbol table for i in 1:size of block(current block(parent)) loop attrib := get attributes i(current block(parent), i); { { If it is the sort of object we are looking for if equal declaration(decl, return declaration(attrib)) then new attrib := new attributes; { { Copy the attributes and store in the current block's symbol table { { if it is not already de ned there. new attrib := copy(attrib); new attrib := insert declaration(new attrib, nonlocal); if info de ned(sym) then { { If the current block already has a symbol table this block := current block(sym); if not boolean(member of block(this block, return name(attrib))) then sym := de ne current block(sym, insert into block(this block, return name(new attrib), new attrib)); ; :::
:::
:::
else
{ { Otherwise create a symbol table and insert the value. this block := block table.new block; sym := de ne current block(sym, insert into block(this block, return name(new attrib), new attrib));
; pool;
;
; end; { { inherit via scope rules Figure 5. An example of a HLO used in ATLANTIS. showing that a unique result exists for every conceivable situation) [8, 11], providing a rigorous framework for the model. As already mentioned, the outermost layer of the model involves calls on HLOs, whose de nitions in turn directly involve the ADT operations. It is thus possible to expand the de nitions of semantic routines into the corresponding ADT manipulations. Hence, showing consistency and sucient6
completeness for each ADT of the model indicates that these properties are maintained by the entire language de nition. Figure 6 provides an example of an ADT de nition which may be found within an ATLANTIS de nition of a programming language.
3 Generating an interpreter An outline of the ATLANTIS system is shown in Figure 7; note that the components which have double outlines are supplied and are used unaltered, whereas those with a single outline are generated from the language de nition. The lexical and syntactic parts of an ATLANTIS language de nition are carefully checked for internal consistency and translated into input suitable for lex [18] and yacc respectively, in order to generate the appropriate annotated parse tree. In the case of the syntactic component of an ATLANTIS de nition, this involves the translation of the EBNF productions to BNF and the merging of rules which share common syntactic derivations, whilst ensuring that the appropriate semantic action can still be located when the interpreter driver traverses the generated parse tree. The generated scanner produces a token stream from a program written in the speci ed language; these tokens are passed to the generated parser. This parser, in turn, checks the source for syntactic errors and ags them accordingly. If no syntax errors are detected, then a parse tree is produced. The parse tree is annotated with calls to semantic routines produced from the description of the semantics of the langauge in the ATLANTIS de nition. Semantic analysis uses the parse tree, interpreting the program by performing a post-order traversal. Several tree traversals are performed, corresponding to the passes in the semantic de nition of the language, with the appropriate semantic actions executed as necessary to build and manipulate the appropriate information structures. The result of the source program is re ected in the state of the information structure when all the necessary passes over the parse tree are complete. The ATLANTIS system provides a tool which encourages the formal de nition of a programminglanguage by providing an automated mechanism which results in a language implementation which adheres precisely to the de nition. The correspondence between the language de nition and the language implementation allows the language designer to design and test new language concepts. By using the information structure model approach to language de nition, the language designer is forced to consider all aspects of the programming language semantics carefully; by using the generated interpreter, the language designer can check that the semantic de nition corresponds to the intended behaviour. The code generation phase of a compiler is targeted at a speci c architecture and the production of a compiler rather than an interpreter from the formal language de nition would then tie the de nition to that architecture and make the de niton less useful as a result. The interpreter produced by ATLANTIS is sucient to allow language design experiments to be conducted and the results evaluated, as well as acting as a benchmark against which to compare hand-crafted compilers; it also provides programmers with an executable version of the language de nition.
7
ADT block info [attributes]; sorts block info/string type, attributes, integer, boolean; where string type has equal string: string type string type ! boolean; integer has equal integer: integer integer ! boolean; integer has add integer: integer integer ! integer; syntax new block: ! block info; empty block: block info ! boolean; add to block: block info string type attributes ! block info; block info string type attributes ! block info;S insert into block: delete from block: block info string type ! block info ferrorg; member of block: block info string type ! boolean; associated attributes: block info string type ! attributes; S get object i: block info integer ! string typeS ferrorg; get attributes i: block info integer ! attributes ferrorg; size of block: block info ! integer; S alter block: block info string type attributes ! block info S ferrorg; alter member i: block info integer attributes ! block info ferrorg; semantics declare block: block info; axioms
str 1, str 2: string type; att 1, att 2: attributes; i: integer;
empty block(new block) = true; empty block(add to block(block, str 1, att 1)) = false; delete from block(new block, str 1) = error; delete from block(add to block(block, str 1, att 1), str 2) = if equal string(str 1, str 2) then block; else add to block(delete from block(block, str 2), str 1, att 1); ; (5) member of block(new block, str 1) = false; (6) member of block(add to block(block, str 1, att 1), str 2) = if equal string(str 1, str 2) then true; else false; ; (7) associated attributes(new block, str 1) = error; (8) associated attributes(add to block(block, str 1, att 2), str 2) = if equal string(str 1, str 2) then att 1; else associated attributes(block, str 2); ; (9) get object i(new block, i) = error; (10) get object i(add to block(block, str 1, att 1), i) = if equal integer(size of block(add to block(block, str 1, att 1)), i) then str 1; else get object i(block, i); ; Figure 6. An example of an ADT used in ATLANTIS. (1) (2) (3) (4)
8
(11) get attributes i(new block, i) = error; (12) get attributes i(add to block(block, str 1, att 1), i) = if equal integer(size of block(add to block(block, str 1, att 1)), i) then att 1; else get attributes i(block, i); ; (13) size of block(new block) = 0; (14) size of block(add to block(block, str 1, att 1)) = add integer(size of block(block), 1); (15) alter block(new block, str 1, att 1) = error; (16) alter block(add to block(block, str 1, att 1), str 2, att 2) = if equal string(str 1, str 2) then add to block(block, str 1, att 2); else add to block(alter block(block, str 2, att 2), str 1, att 1); ; (17) alter member i(new block, i, att 1) = error; (18) alter member i(add to block(block, str 1, att 1), i, att 2) = if equal string(str 1, str 2) then add to block(block, str 1, att 2); else add to block(alter member i(block, i, att 2), str 1, att 1); ; (19) insert into block(block, str 1, att 1) = if member of block(block, str 1) then alter block(block, str 1, att 1); else add to block(block, str 1, att 1); ; Figure 6. Continued.
source file
lex
lex definition
scanner token stream
language definition
ATLANTIS
yacc definition
yacc
parser annotated parse tree
semantic routines
Figure 7. The ATLANTIS system. 9
interpreter
The semantic routines referred to in Figure 7 are a pool of Ada routines generated from the semantic actions and HLOs of the language de nition. As the underlying model of ATLANTIS is based on ADTs, it is necessary to translate the ADT speci cations into Ada packages. This is the only aspect of the language de nition for which ATLANTIS does not automatically generate the corresponding implementation component. These ADTs are manually translated into Ada packages which behave in precisely the manner dictated by the ADT speci cations. Although it is initially labour intensive, this aspect of the interpretive implementation has a high degree of reuseability, as the ADTs used to describe one language are often used again in the de nition of another language. Hence, an investment of time in the manual translation of ADT speci cations to Ada packages is rewarded later when a subsequent language de nition is produced. Commonality of ADT speci cations between diering language de nitions not only ensures the high degree of reusability of the Ada packages, but also results in a rm basis on which dierent languages may be compared. ATLANTIS may be modi ed to incorporate techniques for the automatic generation of ADT implementations from ADT speci cations using the technology developed for the Larch [12, 28] and OBJ [17, 24] systems. As an illustration of the operation of ATLANTIS, consider the parse tree in Figure 8, which would be produced according to the rules in Figure 4 and the following input:
procedure foo (a: integer); var i: integer; begin end; :::
Performing a post-order traversal over the annotated parse tree results in the execution of the semantic actions at locations corresponding to their place in the rules of the language de nition in Figure 4. If the language de nition requires multiple passes to correctly specify its semantics, then multiple passes over the parse tree will be performed; in the case of Figure 4, two passes are required. Figure 8 shows semantic actions, si, attached to leaf nodes of the parse tree. These semantic actions are executed when the node is left for the nal time during the post-order traversal in the relevant pass over the tree. This results in the need to incorporate empty leaf nodes in the parse tree to which semantic actions can be attached if no other node is acceptable or available. In the case of Figure 8, the rst pass over the resultant parse tree invokes the semantic routines speci ed for execution during this pass. This builds an information structure which can be further modi ed by the semantic routines speci ed for execution during the second pass over the parse tree. Using an information structure model of a programming language as the basis of program execution will not lead to an ecient implementation. However, this implementation is an accurate representation of the language semantics. As mentioned earlier, the reason for generating an interpreter rather than a compiler at this stage is to ensure that the language de nition remains free of any machine dependencies.
10
PROCEDURE_DECLARATION
PROCEDURE_SYM
procedure
IDENT s1
foo
ε s2
FORMAL_PARAM_LIST
SEMICOLON
...
DECLARATION_SEQUENCE s3
BLOCK
...
Figure 8. A generated parse tree.
4 Conclusions and future work.
The approach described in this paper encourages formality in language design by gathering together activities which have traditionally been distinct: language design, de nition and implementation. Generating an implementation from the language de nition allows the designer to experiment with and fully explore language design issues in the con dence that the generated implementation precisely matches the formal de nition. Language designers are encouraged to produce a formal de nitions of new languages through the generation of a low cost implementations based directly on their de nitions. Such implementations provide language designers with the opportunity to check language de nitions to enure that they accurately re ect the intended semantics. Since the formal de ntion is layered, users examining various layers in an ATLANTIS description will all have access to an implementation consistent with the layers concerned. Programmers, normally preferring an informal natural language exposition because such descriptions are easier to read, will be able to answer questions about a language by reading to a depth most appropriate to them. Compiler writers, requiring a more precise de nition, are provided with a precise and complete speci cation based on abstract data types. Finally, the language designer bene ts by using ATLANTIS since an implementation is obtained with little additional eort as a result of designing and de ning the language. Currently, the scanner and the parser are automatically generated from a language de nition; the translation of the semantic routines and HLOs to Ada routines is also performed automatically. Although the principal aim of ATLANTIS is not the generation of a production quality compiler generating native code, future development could proceed in this area by employing a code generator generator [4, 5, 9, 10] to produce a more ecient compiler. De nition of the necessary instructions for a speci c machine architecture can be kept separate from the language de nition. The present ATLANTIS system only handles sequential languages { extensions which are required to handle parallel programming languages are currently being considered. In order to provide the same bene ts to the developers of parallel languages, the underlying information structure model needs to be enhanced. Work is proceeding in this area through the introduction of a new layer, directly above the ADT layer, to handle several processes trying to simultaneously access the information structures; this layer employs shared data abstractions (SDAs), as described in [3, 19, 21, 23]. However, until the issues involved in the de nition 11
of parallel programming languages is more fully explored, it remains unclear which generation technique is most appropriate for the automatic translation of ADT speci cation. These issues are currently being investigated; in the meantime ATLANTIS will continue with the hand translation of ADT speci cations into Ada. The introduction of SDAs into ATLANTIS would then provide a language de nition technique able to describe both sequential and parallel languages, whilst providing a formal and readable language de nition from which an interpreter or compiler prototype can be produced automatically.
References [1] D. Bjrner and C.B. Jones (Editors). The Vienna Development Method: The Meta-Language, Volume 61 of Lecture Notes in Computer Science. Springer-Verlag, Berlin, 1978. [2] BSI. Speci cation For Computer Programming Language Pascal. British Standards Institution, London, 1982. Publication BS 6192:1982. [3] D.H. Freidel. Modelling Communication and Synchronization in Parallel Programming Languages. Ph.D. thesis, Department of Computer Science, The University of Iowa, Iowa City, Iowa, May 1984. Available as Technical Report 84-01. [4] M. Ganapathi and C.N. Fischer. Description{driven code generation using attribute grammars. In Conference Record of the Ninth Annual ACM Symposium on Principles of Programming Languages, pages 108{119, Albuquerque, New Mexico, January 1982. [5] M. Ganapathi and C.N. Fischer. Ax grammar driven code generation. ACM Transaction an Programming Languages and Systems, Volume 7, Number 4, pages 560{599, October 1985. [6] H. Ganzinger. Denotational semantics for languages with modules. In D. Bjrner (editor), Formal Description of Programming Concepts, pages 3{23. North{Holland, Amsterdam, 1982. [7] J.A. Goguen, J.W. Thatcher and E.G. Wagner. An initial algebra approach to the speci cation, correctness and implementation of abstract data types. In R.T. Yeh (editor), Current Trends in Programming Methodology, Volume 4, Chapter 5, pages 80{149. Prentice-Hall, Englewood Clis, New Jersey, 1978. [8] J.A. Goguen, J.W. Thatcher, E.G. Wagner and J.B. Wright. Initial algebra semantics and continuous algebras. Journal of the ACM, Volume 24, Number 1, pages 68{95, 1977. [9] S.L. Graham. Table{driven code generation. IEEE Computer, Volume 13, Number 8, pages 25{34, August 1980. [10] S.L. Graham, R.R. Henry and R.A. Schulman. An experiment in table driven code generators. In Proceedings of the SIGPLAN'82 Symposium on Compiler Construction, pages 32{43, Boston, Massachusetts, June 1982. (Also in ACM SIGPLAN Notices, Volume 17, Number 6, June 1982). [11] J.V. Guttag. Notes on type abstraction (Version 2). IEEE Transactions on Software Engineering, Volume SE{6, pages 13{23, January 1980. [12] J.V. Guttag, J.J. Horning and J.M. Wing. The Larch family of speci cation languages. IEEE Software, Volume 2, Number 5, pages 24{36, September 1985. [13] ISO. Second DP 7185 { Speci cation for the Computer Programming Language Pascal. International Organization for Standardization (ISO), December 1980. [14] ISO. First DP 7185 { Speci cation for the Computer Programming Language Pascal. International Organization for Standardization (ISO), May 1980. 12
[15] K. Jensen and N. Wirth. Pascal User Manual and Report. Springer-Verlag, New York, second edition, 1978. [16] S.C. Johnson. Yacc { yet another compiler-compiler. Technical Report No. 23, Bell Laboratories, Murray Hill, New Jersey, July 1975. [17] C. Kirchner, H. Kirchner and J. Meseguer. Operational semantics of OBJ-3. In T. Lepisto and A. Salomaa (editors), Automata, Languages and Programming, pages 287{301. Springer-Verlag, Berlin, 1988. Volume 317 of Lecture Notes in Computer Science. [18] M.E. Lesk. Lex { a lexical analyser generator. Technical Report Computer Science No. 59, Bell Laboratories, Murray Hill, New Jersey, October 1975. [19] W.R. Mallgren. Formal Speci cation of Interactive Graphics Programming Languages. MIT Press, Cambridge, Massachusetts, 1983. [20] C.D. Marlin and M.J. Oudshoorn. Using abstract data types in a model of the data control aspect of programming languages. Australian Computer Science Communications, Volume 7, Number 1, pages 19{1 { 19{10, February 1985. [21] C.D. Marlin, M.J. Oudshoorn and D.H. Freidel. A model of communication in Ada using shared data abstractions. In S.G. Akl, F. Fiala and W.W. Koczkodaj (editors), Advances in Computing and Information { ICCI'90, pages 443{452. Springer-Verlag, Berlin, 1990. Volume 468 of Lecture Notes in Computer Science. [22] M.J. Oudshoorn and C.D. Marlin. A layered, operational model of data control in programming languages. Computer Languages, Volume 16, Number 2, pages 147{165, 1991. [23] M.J. Oudshoorn, K.J. Ransom and C.D. Marlin. Abstract data types: Converting from sequential to parallel. In P.A. Bailes (editor), Engineering Safe Software, pages 285{298. Australian Computer Society, Sydney, New South Wales, July 1991. Proceedings of the 1991 Australian Software Engineering Conference. [24] S. Sidhar. An implementation of OBJ2: An object-oriented language for abstract program speci cation. In K.V. Nori (editor), Foundations of Software Technology and Theoretical Computer Science, pages 81{95. Springer-Verlag, Berlin, 1986. Volume 241 of Lecture Notes in Computer Science. [25] R.D. Tennent. The denotational semantics of programming languages. Communications of the ACM, Volume 19, Number 8, pages 437{453, August 1976. [26] J. Uhl, S. Drossopoulou, G. Persch, G. Goos, M. Dausmann, G. Winterstein and W. Kirchgassner. An Attribute Grammar for the Semantic Analysis of Ada, Volume 139 of Lecture Notes in Computer Science. Springer-Verlag, Berlin, 1982. [27] U.S. Department of Defense. The Programming Language Ada Reference Manual, ANSI/MIL-STD1815A-1983. United States Department of Defense, Washington, D.C., 1983. [28] J.M. Wing. Writing Larch interface language speci cations. ACM Transactions on Programming Languages and Systems, Volume 9, Number 1, pages 1{24, January 1987. [29] N. Wirth. The programming language Pascal. Acta Informatica, Volume 1, Number 1, pages 35{63, January 1971.
13