Compilers consit of front (analysis part) and back (code generation part).
Code in a source language is analyzed, intermediary data structure generated, such as Abstract Syntax Tree, then from it code in target language generated.
Purpose for this is that we can use many front and many back parts, translating from many source languages (such as C, Pascal, Java) to many target languages (for example machine codes for different processors, or other programming language such as C).
Parsers (analysis and intermediary structure generation parts) are created by designing and writing grammar in any form, including tree if neccessary, then using automated tool such as JAVACC or writing parser code manually.
Code generation part is simple in it's most basic idea - traverse tree, analyze it, look for certain patterns (not only leaves) then remove them from tree and generate code in target language, instruction by instruction.
In advanced compilers there are many other methods for improving such process, such as including code optimization part before generating code (for example by transforming intermediary data structure).
Source: , my own programming experience (i wrote parser professionally before).
See also: Context-Free Grammars.