From: | Nick Rothwell <nick@an-teallach.com> |
Newsgroups: | comp.compilers |
Date: | 8 Jun 1996 18:33:10 -0400 |
Organization: | Compilers Central |
References: | 96-06-010 |
Keywords: | OOP |
> I thought you could
> alternatively make up the parse tree of objects, like Statement,
> ConditionalBlock, Loop, etc.
The compiler I've built (in C++) for a polymorphically-typed language
is done in precisely this way.
> A ConditionalBlock would contain the
> condition and the respective code to be executed.
Ah: there we diverge. This is, as John says. heading towards syntax-directed
translation. Leaving that issue aside, it is still quite feasible to parse
source code into objects. I use a slightly-hacked YACC which generates a
parse tree of objects, rather than passive data. Objects are subclassed
according to which generic type of statement they represent (So,
CSynExpression is all expressions, with CSynExpressionIDENT,
CSynExpressionCOND, and so on as subclasses).
Every object knows how to compile itself to an intermediate code, with
respect to some context which deals with scoping and closures. Hence, each
parse tree can compile itself via its constituent objects.
The intermediate code generated is also a (very flat) tree of
objects. Needless to say, each instruction knows how to assemble
itself in a similar manner. (And the resulting code knows how to load
itself.)
I take the code generation as far as a bytecode-like stream (actually,
longword-based) for a fairly conventional abstract machine.
> Then I thought that kind of parser would require much more memory than
> with the traditional approach and much more function calls would have to
> be made to build the tree.
Very possibly. In fact, since the (Milner-style) polymorphic
typechecker is object-based as well (every syntax phrase knows how to
typecheck itself, every type knows how to unify with others,
etc. etc.), a lot of the space goes there.
But then, all the front-end C++ is garbage collected anyway, using an
"explicit" variant of the Cheney copying collector; it just requires
all collectable objects to be able to identify their internal
pointers.
I should point out that none of the above is really a revelation. When
in Rome, speak Latin. When building a compiler in C++, make proper use
of objects. Innovation in this respect is emergent rather than
intentional.
> At the end, only the performance of the compiler counts
I disagree: many other things count, such as clarity, correctness,
maintainability, flexibility, portability, and so on. Neither my
front-end or back-end are speed demons compared to commercial native
compilers, but our priorities and constraints are very different.
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.