Introduction to Compiler Design (Undergraduate Topics in Computer Science)
Format: PDF / Kindle (mobi) / ePub
This textbook is intended for an introductory course on Compiler Design, suitable for use in an undergraduate programme in computer science or related fields.
Introduction to Compiler Design presents techniques for making realistic, though non-optimizing compilers for simple programming languages using methods that are close to those used in "real" compilers, albeit slightly simplified in places for presentation purposes. All phases required for translating a high-level language to machine language is covered, including lexing, parsing, intermediate-code generation, machine-code generation and register allocation. Interpretation is covered briefly.
Aiming to be neutral with respect to implementation languages, algorithms are presented in pseudo-code rather than in any specific programming language, and suggestions for implementation in several different language flavors are in many cases given. The techniques are illustrated with examples and exercises.
The author has taught Compiler Design at the University of Copenhagen for over a decade, and the book is based on material used in the undergraduate Compiler Design course there.
Additional material for use with this book, including solutions to
selected exercises, is available at http://www.diku.dk/~torbenm/ICD
structure, like we did above. Exactly how the abstract syntax tree is represented and built depends on the parser generator used. Normally, the action assigned to a production can access the values of the terminals and nonterminals on the right-hand side of a production through specially named variables (often called $1, $2, etc.) and produces the value for the node corresponding to the left-hand-side either by assigning it to a special variable ($0) or letting it be the value of an action
table for the outer scope when exiting an inner scope. In the main text of the chapter, we don’t need to preserve symbol tables for inner scopes once these are exited (so a stack-like behaviour is fine), but in one of the exercises we will need this. 4.1 The Structure of an Interpreter An intepreter will typically consist of one function per syntactic category. Each function will take as arguments an abstract syntax tree from the syntactic category and, possibly, extra arguments such as symbol
array-lookup. However, this does not work if the sizes of these arrays are given at run-time. In this case, we need to use a variable to hold the base address of each array. The address is calculated when the array is allocated and then stored in the corresponding variable. This can subsequently be used as described in Trans Index above. At compile-time, the array-name will in the symbol table be bound to the variable that at runtime will hold the base-address. Dynamic allocation can also be
is indicated by indentation. Use the same vtable as Exercise 6.1 and use endlab as the endlabel for the whole statement. Exercise 6.10 In Fig. 6.5, while statements are translated in such a way that every iteration of the loop executes an unconditional jump (GOTO in addition to the conditional jumps in the loop condition. Modify the translation so each iteration only executes the conditional jumps in the loop condition, i.e., so an unconditional jump is saved in every iteration. You may have
Virtual Machine Specification, 2nd edn. Addison-Wesley, Reading (1999) 6. Muchnick, S.S.: Advanced Compiler Design and Implementation. Morgan Kaufmann, San Mateo (1997) Footnotes 1Note that the coordinate system, following computer-science tradition, is rotated 90° clockwise compared to mathematical tradition. Torben Ægidius MogensenUndergraduate Topics in Computer ScienceIntroduction to Compiler Design10.1007/978-0-85729-829-4_7© Springer-Verlag London Limited 2011 7. Machine-Code