Take a step back. A compiler is simply a program that translates a document in one language into a document in another language. Both languages ought to be well-defined and specific.
The languages do not have to be programming languages. They can be any language whose rules can be written down. You've probably seen Google Translate; that's a compiler because it can translate one language (say, German) into another (Japanese, perhaps).
Another example of a compiler is an HTML rendering engine. Its input is an HTML file and the output is a series of instructions to draw the pixels on the screen.
When most people talk about a compiler, they are usually referring to a program that translates a high-level programming language (such as Java, C, Prolog) into a low-level one (assembly or machine code). That can be daunting. But it's not so bad when you take a generalist's view that a compiler is a program that translates one language into another.
Can you write a program that reverses every word in a string? For example:
When the cat's away, the mice will play.
becomes
nehW eht s'tac yawa, eht ecim lliw yalp.
That's not a difficult program to write, but you need to think about some things:
- What is a "word"? Can you define which characters make up a word?
- Where do words start and end?
- Are words separated by only one space, or can there be more--or less?
- Does punctuation need to be reversed, too?
- What about punctuation inside a word?
- What happens to capital letters?
The answers to these questions help the language be well-defined. Now go ahead and write the program. Congratulations, you've just written a compiler.
How about this: Can you write a program that takes a series of drawing instructions and outputs a PNG (or JPEG) file? Maybe something like this:
image 100 100
background black
color red
line 20 55 93 105
color green
box 0 0 99 99
Again, you'll need to do some thinking to define the language:
- What are the primitive instructions?
- What comes after the word "line"? What comes after "color"? Likewise for "background", "box", etc.
- What is a number?
- Is an empty input file allowed?
- Is it OK to capitalize the words?
- Are negative numbers allowed?
- What happens if you don't give the "image" directive?
- Is it OK to not specify a color?
Of course, there are more questions to answer but if you can nail them down, you have defined a language. The program you write to do the translation is, you guess it, a compiler.
You see, writing a compiler isn't that difficult. The compilers you've used in Java or C are just bigger versions of these two examples. So go for it! Define a simple language and write a program to make that language do something. Sooner or later you're going to want to extend your language. For instance, you may want to add variables or arithmetic expressions. Your compiler will become more complex but you'll understand every bit of it because you wrote it yourself. That's how languages and compilers come about.