The job of the compiler is to translate your program from one set of instructions into another. In high-level languages, you translate higher-level instructions that are easy to read and write for people to lower-level instructions that are easy for machines to execute.
Since the compiler needs to perform a conversion of one set of symbols into another set of symbols, it builds some internal model of the program that you are writing. In a sense, we can say that the compiler understands the program, for some definition of understands.
If the compiler builds an internal model or understands your program in some other way, we can also harness the power of compiler to make the compiler check for the correctness of the program. We can make the compiler impose and enforce certain styles or guarantees that your program must obey. We have already seen an example...