|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.ObjectgeneralHelpers.TreeNode
public abstract class TreeNode
The base class for all AST nodes.
After lexical analysis and parsing, a Cool program is represented internally
by the Cool compiler as an abstract syntax tree. The project comes with a
definition of Cool abstract syntax trees (ASTs) built in. The AST package is
by far the largest piece of code in the base system and requires the most
time to learn. The learning process is made more complex because the AST code
is generated automatically from a specification in the file
cool-tree.aps
. While the generated code is quite simple and
regular in structure, it is also devoid of comments. This section serves as
the documentation for the AST package.
let
expressions, another
class of +
expressions, and so on. Objects of these classes
are nodes in Cool abstract syntax trees. For example, an expression
e1 + e2
is represented by a +
expression
object, which has two subtrees: one for the tree representing the expression
e1
and one for the tree representing the expression
e2
.
The Cool abstract syntax is specified in a language called APS. In APS
terminology, the various kinds of abstract syntax tree nodes (let
,
+
, etc.) are called constructors. (Don't confuse
this use of the term "constructor" with Java constructors; while similar,
this is a slightly different meaning taken from functional languages that
predate Java.) The form of the AST is described by a set of phyla.
Each phylum has one or more constructors.
Phyla are really just types. That is, instead of having one large group of
undifferentiated constructors, the constructors are grouped together
according to function, so that, for example, the constructors for expression
ASTs are distinguished from the constructors for class ASTs. The phyla are
defined at the beginning of cool-tree.aps
:
module COOL begin phylum Program; phylum Class_; phylum Classes = LIST[Class_]; phylum Feature; phylum Features = LIST[Feature]; phylum Formal; phylum Formals = LIST[Formal]; phylum Expression; phylum Expressions = LIST[Expression]; phylum Case; phylum Cases = LIST[Case];From the definition it can be seen that there are two distinct kinds of phyla: "normal" phyla and list phyla. "Normal" phyla each have associated constructors; list phyla have a fixed set of list operations.
Each constructor takes typed arguments and returns a typed result. The types may either be phyla or any ordinary Java type. In fact, the phyla declarations are themselves compiled into Java class declarations by an APS compiler. A sample constructor definition is
constructor class_(name : AbstractSymbol; parent : AbstractSymbol; features : Features; filename : AbstractSymbol) : Class_;This declaration specifies that the
class_
constructor takes
four arguments: an AbstractSymbol
(a type identifier) for the
class name, an AbstractSymbol
(another type identifier) for
the parent class, a Features
, and an
AbstractSymbol
for the filename in which the class definition
occurs. (the name class_
is chosen to avoid a conflict with
the Java keyword class.) The phylum Features
is
defined to be a list of Feature
's by the declaration
phylum Features = LIST[Feature];See ListNode for a description of the operations defined on AST lists.
To invoke the class constructor, you allocate a new node object supplying it
with the right arguments, e.g. new
class_(...)
. In
cool.cup
there is the following example of a use of the
class_
constructor:
class ::= CLASS TYPEID:n INHERITS TYPEID:p LBRACE optional_feature_list:f RBRACE SEMI {: RESULT = new class_(curr_lineno(), n, p, f, curr_filename()); :}Allocating a new
class_
object, builds a class_
constructor is applied only to arguments of the appropriate type. See Section
6.5 of the "Tour of Cool Support Code" and cool-tree.aps
to
learn the definitions of the other constructors. (Comments in cool-tree.aps
begin with two hyphens "--".)
NOTE: there is a real danger of getting confused because the same names are
used repeatedly for different entities in different contexts. In the example
just above, small variations of the name class are used for a
terminal (CLASS
), a non-terminal (class
), a
constructor (class_
), and a phylum (Class_
).
These uses are all distinct and mean different things. Most uses are
distinguished consistently by capitalization, but a few are not. When reading
the code it is important to keep in mind the role of each symbol.
The TreeNode class definition contains everything needed in an abstract syntax tree node except information specific to particular constructors.
Each of the constructors is a class derived from the appropriate phyla.
class_
constructor
has four data members:
Symbol name; Symbol parent; Features features; Symbol filename;Here is a complete use of one member:
class class_ extends Class_ { ... AbstractSymbol getParent() { return parent; } ... } ... Class_ c; AbstractSymbol p; c = new class(lineno, AbstractTable.idtable.add_string("Foo",3), AbstractTable.idtable.add_string("Bar"), new Features(lineno), AbstractTable.stringtable.add_string("filename")); p = c->get_parent(); // Sets p to the symbol for "Bar" ...It will be useful in writing a Cool compiler to extend the AST with new functions such as
getParent()
. Simply modify the cool-tree.java
file to add functions to the class of the appropriate phylum or constructor.
null
is not a valid component of any AST. Never
use null
as an argument to a constructor.
Utilities.fatalError()
is invoked to terminate execution and a stack trace is printed to the
console.
Field Summary | |
---|---|
protected int |
lineNumber
line in the source file from which this node came. |
Constructor Summary | |
---|---|
protected |
TreeNode(int lineNumber)
Builds a new tree node |
Method Summary | |
---|---|
abstract TreeNode |
copy()
Creates a copy of this node. |
protected AbstractSymbol |
copyAbstractSymbol(AbstractSymbol sym)
Copies an AbstractSymbol value. |
protected java.lang.Boolean |
copyBoolean(java.lang.Boolean b)
Copies a boolean value. |
abstract void |
dump(java.io.Writer out,
int n)
Pretty-prints this node to this output stream. |
protected void |
dumpAbstractSymbol(java.io.Writer out,
int n,
AbstractSymbol sym)
Dumps a printable representation of an AbstactSymbol value. |
protected void |
dumpBoolean(java.io.Writer out,
int n,
java.lang.Boolean b)
Dumps a printable representation of a boolean value. |
protected void |
dumpLine(java.io.Writer out,
int n)
Dumps a printable representation of current line number This method is used internally by the generated AST classes |
int |
getLineNumber()
Retreives the line number from which this node came. |
TreeNode |
set(TreeNode other)
Sets the values of this node object to the values of a given node. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
protected int lineNumber
Constructor Detail |
---|
protected TreeNode(int lineNumber)
lineNumber
- the line in the source file from which this node came.Method Detail |
---|
public abstract TreeNode copy()
public TreeNode set(TreeNode other)
other
- the other node
public int getLineNumber()
public abstract void dump(java.io.Writer out, int n) throws java.io.IOException
out
- the output streamn
- the number of spaces to indent the output
java.io.IOException
protected java.lang.Boolean copyBoolean(java.lang.Boolean b)
protected AbstractSymbol copyAbstractSymbol(AbstractSymbol sym)
protected void dumpBoolean(java.io.Writer out, int n, java.lang.Boolean b) throws java.io.IOException
java.io.IOException
protected void dumpAbstractSymbol(java.io.Writer out, int n, AbstractSymbol sym) throws java.io.IOException
java.io.IOException
protected void dumpLine(java.io.Writer out, int n) throws java.io.IOException
java.io.IOException
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |