Object-Oriented Compiler Construction
Object-Oriented Compiler Construction
Object-Oriented Compiler Construction
Object Orientation
objects information hiding, state encapsulation
methods develop by divide and conquer
messages debug by instrumentation
classes reuse between projects
inheritance reuse within and between projects
class libraries many pre-fabricated algorithms and data structures
Compiler Construction
Symbol Table
container for descriptions of (mostly user-defined) symbols
lex locates a description by key (identifier),
elsewhere it is passed by reference,
syn and sem contribute information
symbol table and symbols can be objects
object advantage
inheritance encapsulate and share lookup mechanism,
separate it from actual description
objects encapsulate and hide description information
class libraries provide containers, lookups, and value representations
3
Parse Tree
given a rudimentary grammar:
sum: product | sum ’+’ product
product: term | product ’*’ term
term: identifier | literal
object advantage
methods automate divide and conquer to implement sem, gen, and run
inheritance simplifies implementation, e.g., for related operators
class libraries extensible compiler kit as a reusable universal back end,
includes sem that can be modified by inheritance and overwriting,
sem generates a persistent execution tree for run
4
Execution
id: x
+
int: 10
object advantage
objects persistence provides cheap, platform-independent image store
methods reuse between compilation (e.g., constant expressions) and runtime
5
Semantic Analysis
id: x
+
int: 10
during a traversal of the parse tree, result types are computed and checked for the nodes
sem is a method for each class of nodes and augments parse tree with conversion nodes,
types are modeled as unique objects,
type’s methods generate simplified, persistent runtime tree
object advantage
methods automate divide and conquer to implement sem
class libraries allow reuse of types and semantic analysis of expressions
inheritance permits restricting and extending a library type’s capabilities
6
Types
id: x
+
int: 10
sem:
for children: sem // sets children’s types
for children:
if child.type.supports(’+’, otherType):
type = child.type.result(’+’, otherType)
break
if type not set: error // impossible operation
7
Syntax Analysis
object advantage
objects parser objects encapsulate lookahead and follow sets,
goal objects encapsulate state of phrase recognition,
both can be used for automatic error recovery
methods automate divide and conquer for LL(1) checking and parsing,
goals avoid the need for parser action syntax within grammar
messages provide precise semantics for shift and reduce even in EBNF
8
Alt Seq
successful parsing hinges on determining which route to take through the graph,
i.e., on certain lookahead and follow sets being mutually distinct
discover algorithm to compute the sets by inspecting syntax graph building blocks,
implement it as methods for classes like Alt and Seq representing the blocks
object approach leads from visual discovery to functioning implementation
9
interface Visitor {
tree accept: visitor visit (SomeClass node);
// for each kind of node class
visit:this }
a Visitor object is sent to the root of the tree, which calls it back;
Visitor objects must implement a visit method for each node class,
the node class must provide access to the node’s children
Visitor support can be generated by a tree-building parser such as jjtree
fairly difficult to extend or inherit, but permits adding new traversals later
tree sem
object advantage
methods Visitor enforces divide and conquer
inheritance combined with overloading permits refinement of initially very
coarse traversal rules and reuse between projects
10
Conclusion
objects information hiding, state encapsulation
methods develop by divide and conquer
messages debug by instrumentation
classes reuse between projects
inheritance reuse within and between projects
class libraries many pre-fabricated algorithms and data structures