Chris Smith said
I don't write many book reviews for Amazon, but this book was so terrible I figured I had to. If you want to build your own .Net language and Compiler then you must have some understanding of the theoretical underpinnings of compilers - scanners, parsers, intermediate representation, etc.
This book not only skips the required theory, but avoids any technical depth to the degree of being nothing more than 400-page description of a crappy BASIC interpreter the author wrote.
Even if you want some lightweight reading on the subject of compilers or .Net in general, there just isn't enough meat here to justify picking this book up off the shelf.
W. A. Norris said
First, some clear demarcation about what this book isn't: if you want a book with a really strong theoretical background in compiler design, this isn't it. I have Programming Language Pragmatics by Scott, and I recommend it.
Second, if you want a book about compiling to IL for direct execution, this isn't that book either. Frankly, this book is poorly titled in that respect. I don't yet have Compiling for the .NET Common Language Runtime by Gough, but it supposedly focuses specifically on this topic.
So what is this book? It's a practical, highly readable book about how to build a scripting language interpreter in VB.Net. A compiler theory textbook can teach you the principles involved in scanning and parsing, but it's likely to leave you wondering how you actually put any of that to use in real code. This book fills in enough theory to have an idea of what you're doing (with a little to spare), and lets you dive right in and work with practical real-world algorithms and code for actually doing it.
If you are a working programmer and you want to add a scripting language to an application you've written, it's easy to conclude that it's way too complicated to do all that stuff. This book is a fantastic antidote for that. It goes through things like tokenization, formal grammars, and recursive descent parsing in plenty of detail, any anyone who understands the basic CS building blocks of data structures and algorithms should find the coverage easy to follow. The text sometimes meanders a little too much, but it's still far more readable than anything else on the topic that I've run across.
My main criticism of this book is that it's a lot better about how to read in a language than how to do something with the result once you've read it in. The included interpreter operates on top of its own limited stack-based virtual machine, and the parser emits opcodes for it. This isn't covered in nearly enough detail, and my sense is that it's because the author isn't really thrilled with his interpreter. My gut feel is that this is kind of a neither-fish-nor-foul solution. A powerful solution for emitting opcodes would generate legitimate IL for the CLR, which the author gives a brief overview of, but doesn't follow through enough to produce real-world code. By contrast, I think a simpler solution for purely interpreted code would produce directly evaluatable function, statement, and operator objects, and not worry about emitting a language or dropping variables on a stack. The author's solution would seem to lack either the performance advantage of the former solution, or the simplicity and conceptual clarity of the latter. The only advantage I can see is pedagogical: it teaches you how to generate opcodes from a parse tree without wading through the complexity of a real-world imtermediate form like IL, GNU RTL, or Java bytecode.
Still, as long as performance isn't paramount, this is a solution that will actually work as an interpreter for a scripting language in the real world. This book covers a lot of ground, without ever completely losing its practical approach. Even though there are some flaws, and some areas I would have loved to see covered in greater detail, this is a tremendously useful book for the right audience.
Meaux said
One of the most difficult things to do is to take a heady subject such as compiler development and break it into simple components and explain it without academic baggage. Nilges succeeded at this admirably. I have attempted to read several of the traditional books on compiler theory only to find myself dazed, confused, or bored to tears by the tedium. That Nilges succeeds in making this book so absorbing, readable, and incredibly mind-opening is amazing.
I now understand the purpose of lex/yacc/bison and I can read any advanced book on compiler development and have a much better understanding of the theory.
In addition, I can and have written my own domain-specific language based on his instruction. I couldn't ask for more. Thanks so much for such a wonderful book.
S. Wain said
It is very entertaining and well written. Does a great job of explaining a difficult topic. The sample code works great.
Eric W. Engler said
The book starts out explaing the standard notational language
used to define the syntax of a language: BNF (and extended BNF).
The authors VB6 EBNF-to-doc compiler "compiles" an EBNF
grammer into a documentation file! This is a novel idea
and it helps to show how EBNF relates to the syntax of the
language in question.
Although his presentation of EBNF is masterful, he didn't
use EBNF to generate the parser for his compiler. I expected
him to use a parser generator like ANTLR or coco/R to generate
a scanner and recursive decent parser automatically from
the grammer. Instead, he chose to "roll his own" scanner
and parser.
His scanner seems very good, and his discussion of
the scanner is thorough.
His parser is harder to judge by reading the book since he
kept getting off the main subject and he didn't really
explain the parsing code.
His code generator discussion has some nuggets of wisdom,
but is poorly organized.
One overriding concern with this author is that he
doesn't use terminology consistant with other
authors. He doesn't use common terms like p-code,
intermediate language, virtual machine, or the like.
His non-standard use of the word "assembling" is really
just a step that removes comments from his p-code!
The authors presentation can get off track frequently.
Its hard to find 5 pages in a row that stay on
subject completely. He also likes to quote famous people,
often out of context to the subject at hand.
His runtime interpreter (which some might call a virtual
machine) is called the "Nutty Professor Interpreter". The
heavy objects used in his design make for a terribly
inefficent runtime. His use of collections to implement
array elements is very elegant, but completely impractical
from a performance standpoint.
I like the author's concept of integrated testing, but
he seems to have left out the most important piece of the
testing architecture - a suite of test programs in the
target language.
I would have preferred these changes to the book:
1) a suite of test programs in basic.
2) compiler should save the pseudo-code into a file on
disk. His runtime "nutty professor" interpreter should
read from that pseudo-code file and execute the
program. This helps to separate the tiers.
3) his runtime architecture should have focused more
on efficiency. It's perhaps 100 times slower than any
other BASIC interpreter (maybe 1000 - I didn't
actually time it). And it should be faster than simple
interpreters because this uses a compiler in the
front-end - the runtime interpreter doesn't need to
analyze the syntax so it should be very fast.
4) he should NOT have implemented variants or user-defined
types. These took a lot of thought and effort which should
have been directed on the first 3 items instead.
Comments