Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between implementing a compiler and an interpreter?

Tags:

I've read the whole Dragon Book recently (just for fun, I'm not really planning to implement an actual compiler), and I was left with this big question dangling in my head.

What is different between implementing a compiler and an interpreter?

To me a compiler is made up of:

  • Lexer
  • Parser (which builds the syntax tree)
  • Generate Intermediate code (like 3 address code)
  • Do all these crazy things to optimize if you want :-)
  • Generate "assembly" or "native code" from the 3 address code.

Now, obviously, the interpreter also has the same lexer and parser as the compiler.
But what does it do after that?

  • Does it "read" the syntax tree and execute it directly? (kind of like having an instruction pointer pointing to the current node in the tree, and the execution is one big tree traversal plus the memory management for the call stack) (and if so, how does it do it? I'm hoping the execution is better than a huge switch statement that checks what type of node it is)

  • Does it generate 3 address code and interpret that? (if so, how does it do it? Again, I'm looking for something more elegant than a mile long switch statement)

  • Does it generate real native code, load it into memory, and make it run? (at which point I'm guessing it's not an interpreter anymore, but more like a JIT compiler)

Also, at which point does the concept of "virtual machine" cut in? What do you use a virtual machine for in a language? (to be clear about my level of ignorance, to me a virtual machine is VMWare, I have no idea how the concept of VM applies to programming languages / executing programs).

As you can see, my question is quite broad. I'm mostly looking for not only which method is used but mostly to first understand the big concepts, and then get into how it works in detail. I want the ugly, raw details. Obviously, this is more a quest for references to things to read rather than expecting you to answer all these details in here.

Thanks!
Daniel


EDIT: Thank you for your answers so far. I realized my title was misleading though. I understand the "functional" difference between a compiler and an interpreter.
What i'm looking for is the difference as to how you implement an interpreter, vs a compiler.
I understand now how a compiler is implemented, the question is how an interpreter differs from that.

For example: VB6 is clearly both a compiler and an interpreter. I understand now the compiler part. However, I can not grasp how, when running inside the IDE, it could let me stop the program at any arbitrary point, change the code, and resume execution with the new code. That's just one tiny example, it's not the answer i'm looking for. What i'm trying to understand, as I explain below, is what happens after I have a parse tree. A compiler will generate new code from it in the "target" language. What does an interpreter do?

Thank you for your help!

like image 932
Daniel Magliola Avatar asked Jan 24 '09 00:01

Daniel Magliola


2 Answers

A compiler is a program that translates a program in one programming language to a program in another programming language. That's it - plain and simple.

An interpreter translates a programming language into its semantic meaning.

An x86 chip is an interpreter for x86 machine language.

Javac is a compiler for java to the java virtual machine. java, the executable application, is an interpreter for the jvm.

Some interpreters share some elements of compilation in that they may translate one language into another internal language that is easier to interpret.

Interpreters usually, but not always, feature a read-eval-print loop.

like image 115
plinth Avatar answered Dec 06 '22 16:12

plinth


A program is a description of work you want done.

A compiler converts a high-level description into a simpler description.

An interpreter reads a description of what to do and does the work.

  • Some interpreters (e.g. Unix shells) read the description one small piece at a time and act on each piece as they see it; some (e.g. Perl, Python) read the entire description, internally convert it to a simpler form and then act on that.
  • Some interpreters (e.g. Java's JVM, or a Pentium 4 chip) only understand a very simple description language that is too tedious for humans to work with directly, so humans use compilers to convert their high-level descriptions to this language.

Compilers never do the work. Interpreters always do the work.

like image 32
j_random_hacker Avatar answered Dec 06 '22 15:12

j_random_hacker