How to Write a Compiler
Many programmers see writing a compiler as the ultimate challenge. Unfortunately, most programmers also see writing a compiler as an extremely complex and daunting task. Writing a compiler doesn't need to be complicated, however.
Before delving into the process of actually writing the compiler, a few key concepts must be learned.
One of the keys to understanding how a compiler works is to understand the concept of abstraction. For example, when you get into a car and start the engine, you are actually performing a large number of smaller steps. You are using your muscles to maneuver your body into the vehicle. You are placing the key into the ignition. You are then turning the key until the car starts.
In the same way, understanding a compiler requires us to step back and see the process as a series of larger tasks.
We need to:
- Accept an input file.
- Parse it.
- Convert the parsed form to another internal model.
- Produce an output file from the model.
Each of these steps is seen as a task, yet each consists of much smaller steps. Accepting an input file, for example, means checking for its existence, checking file permissions, and other related tasks. In the same way parsing the file requires breaking the contents into smaller and smaller units that we can then interpret according to the language's syntax.
What exactly is a compiler? Well, a compiler in its simplest form is a program that converts a higher-level language into a lower-level language. What does this mean? Well, a lower-level language is one that is closer to the target architecture, the actual CPU that the program will be running on.
For example, a compiler might translate C code into x86 assembly.
A term you often hear with 'compiler' is 'interpreter.' What is an interpreter? Basically an interpreter is a small program that instead of translating one language to another, merely interprets the file as it is, executing the instructions itself.
Confusing? Hopefully an example will clear things up:
XINTERP is an interpreter that accepts .x files. It opens the file, reads through the instructions, and uses its own internal code to execute the instructions contained in the .x file. XINTERP is not a compiler. It does no translation. It merely executes the file in place.
Now that you have an understanding of what a compiler is and what it is not, we can start writing your own compiler.