You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mrql.apache.org by Apache Wiki <wi...@apache.org> on 2013/04/10 19:13:04 UTC
[Mrql Wiki] Update of "GenDoc" by LeonidasFegaras
Dear Wiki user,
You have subscribed to a wiki page or wiki category on "Mrql Wiki" for change notification.
The "GenDoc" page has been changed by LeonidasFegaras:
http://wiki.apache.org/mrql/GenDoc
Comment:
added the documentation for Gen
New page:
= Gen: A Java Package for Constructing and Manipulating Abstract Syntax Trees =
Gen is a Java preprocessor that extends the Java language with special
syntax to make the task of handling Abstract Syntax Trees (ASTs)
easier. Two classes are used by Gen: the class {{{Tree}}} that
captures an AST (with subclasses !VariableLeaf, !IntegerLeaf, !FloatLeaf,
!StringLeaf, and Node), and the class {{{Trees}}} that captures a list
of ASTs (see the [[#appendix|Appendix]] for the detailed API). A {{{Tree}}} is a tree-like data structure, which is used
for representing various tree-like data structures used in compiler
construction.
For example, the Java expression
{{{
new Node("Binop",
Trees.nil.append(new VariableLeaf("Plus"))
.append(new VariableLeaf("x"))
.append(new Node("Binop",
Trees.nil.append(new VariableLeaf("Minus"))
.append(new VariableLeaf("y"))
.append(new VariableLeaf("z")))))
}}}
constructs the AST {{{Binop(Plus,x,Binop(Minus,y,z))}}}. To make the
task of writing these tree constructions less tedious, Gen extends
Java with the syntactic form {{{#< >}}}. For example,
{{{#<Binop(Plus,x,Binop(Minus,y,z))>}}} is equivalent to the above
Java expression. That is, the text within the brackets {{{#< >}}} is
used by Gen to generate Java code, which creates the tree-like form
(an instance of the class {{{Tree}}}) that represents this
text. Values of the class {{{Tree}}} can be included into the form
generated by the {{{#< >}}} brackets by "escaping" them with a
backquote character (`). The operand of the escape operator (the
backquote operator) is expected to be an expression of type {{{Tree}}}
that provides the value to "fill in" the hole in the bracketed text at
that point (actually, an escaped string/int/float is also lifted to a
Tree).
For example, in
{{{
Tree x = #<join(a,b,p)>;
Tree y = #<select(`x,q)>;
Tree z = #<project(`y,A)>;
}}}
{{{y}}} is set to {{{#<select(join(a,b,p),q)>}}} and
{{{z}}} to {{{#<project(select(join(a,b,p),q),A)>}}}.
There is also bracketed syntax, {{{#[ ]}}}, for constructing instances of Trees.
The bracketed syntax takes the following form:
||<^|2> bracketed ::= || "#<" expr ">" || a Tree construction (an AST) ||
|| "#[" arg "," ... "," arg "]" || a Trees construction (a list of ASTs) ||
||<^|8> expr ::= || name || the representation of a variable name ||
|| integer || the representation of an integer ||
|| float || the representation of a float number ||
|| string || the representation of a string ||
|| "`" name || escaping to the value of {{{name}}} ||
|| "`(" code ")" || escaping to the value of {{{code}}} ||
|| name "(" arg "," ... "," arg ")" || the representation of a Node with zero or more children ||
|| "`" name "(" arg "," ... "," arg ")" || the representation of a Node with escaped name ||
||<^|3> arg ::= || expr || the representation of an expression ||
|| "..." name || escaping to a list of ASTs (Trees) bound to {{{name}}} ||
|| "...(" code ")" || escaping to a list of ASTs (Trees) returned by {{{code}}} ||
where {{{code}}} is any Java code.
The {{{#< `(code) >}}} embeds the value returned by the Java code {{{code}}} of type
{{{Tree}}} to the term representation inside the brackets.
For example, {{{#<`f(6,...r,g("ab",`(k(x))),`y)>}}} is equivalent to the
following Java code:
{{{
new Node(f,
Trees.nil.append(new IntegerLeaf(6))
.append(r)
.append(new Node("g",Trees.nil.append(new StringLeaf("ab"))
.append(k(x))))
.append(y))
}}}
If {{{f="h"}}}, {{{y=#<m(1,"a")>}}}, and {{{k(x)}}}
returns the value {{{#<8>}}}, then the above term is equivalent to
{{{#<h(6,g("ab",8),m(1,"a"))>}}}.
The three dots ({{{...}}}) construct is used to indicate a list of children in a Node.
Since this list is an instance of the class {{{Trees}}},
the type of {{{name}}} in {{{...name}}} is also {{{Trees}}}.
For example, in
{{{
Trees r = #[join(a,b,p),select(c,q)];
Tree z = #<project(...r)>;
}}}
{{{z}}} will be bound to {{{#<project(join(a,b,p),select(c,q))>}}}.
Finally, to iterate over Trees, use a for-loop:
{{{
for ( Tree v: #[a,b,c] )
System.out.println(v);
}}}
Gen provides a case statement syntax with patterns. Patterns match the
{{{Tree}}} representations with similar shape. Escape operators
applied to variables inside these patterns represent variable patterns, which
"bind" to corresponding subterms upon a successful match.
This capability makes it particularly easy to write functions
that perform source-to-source transformations. A function that simplifies
arithmetic expressions can be expressed easily as:
{{{
Tree simplify ( Tree e ) {
match e {
case plus(`x,0): return x;
case times(`x,1): return x;
case times(`x,0): return #<0>;
case _: return e;
}
}
}}}
where the {{{_}}} pattern matches any value.
For example, {{{simplify(#<times(z,1)>)}}} returns {{{#<z>}}},
since {{{times(z,1)}}} matches the second case pattern. The syntax of the case
statement is:
|| case_stmt ::= || "match" code "{" case ... case "}" || ||
|| case ::= || "case" pattern ":" code || ||
||<^|8> pattern ::= || name || exact match with a name ||
|| integer || exact match with an integer ||
|| float || exact match with a float number ||
|| string || exact match with a string ||
|| "`" name || match any Tree and bind {{{name}}} to the matched value ||
|| name "(" arg "," ... "," arg ")" || match with a Node with a given name and match the Node children ||
|| "`" name "(" arg "," ... "," arg ")" || match the Node children and bind {{{name}}} to the Node name ||
|| "_" || match any Tree ||
||<^|3> arg ::= || pattern || match with a pattern ||
|| "..." name || match with a list of ASTs (Trees) and bind {{{name}}} to the matched list ||
|| "..." || match any arguments ||
For example, the pattern {{{`f(...r)}}} matches any Node: when it is matched with
{{{#<join(a,b,c)>}}}, it binds {{{f}}} to the string {{{"join"}}}
and {{{r}}} to the list {{{#[a,b,c]}}}.
Another example is the following function that adds the terms {{{#<8>}}} and {{{#<9>}}}
as children to any Node {{{e}}}:
{{{
Tree add_arg ( Tree e ) {
match e {
case `f(...r): return #<`f(8,9,...r)>;
case `x: return x;
}
}
}}}
The special keyword fail is used in Gen to abort the current matching
and skip to the next case.
For example
{{{
match e {
case `f(...r,join(`x,`y),...s):
if (x.equals(y))
return #<`f(...r,`x,...s)>;
else fail;
case `x: return x;
}
}}}
will transform {{{join(`x,`y)}}} to {{{x}}} if {{{x}}} is equal to {{{y}}}
(it is not permitted to use a variable twice in a pattern, that is, {{{join(`x,`x)}}}
is an illegal pattern).
<<Anchor(appendix)>>
=== Appendix: The Tree API ===
The class {{{Tree}}} captures an AST, and the class {{{Trees}}} captures a list
of ASTs. A {{{Tree}}} is a tree-like data structure, which is used
for representing various tree-like data structures used in compiler
construction.
{{{
abstract class Tree {
public boolean is_node (); // is this a Node?
public boolean is_variable (); // is this a VariableLeaf?
public boolean is_long (); // is this a LongLeaf?
public boolean is_string (); // is this a StringLeaf?
public boolean is_double (); // is this a DoubleLeaf?
public String variableValue ();// return the variable name
public long longValue (); // return the long value
public String stringValue (); // return the string value
public double doubleValue (); // return the double value
}
class VariableLeaf extends Tree {
public VariableLeaf ( String s );
public String value ();
}
class LongLeaf extends Tree {
public LongLeaf ( long n );
public long value ();
}
class DoubleLeaf extends Tree {
public DoubleLeaf ( double n );
public double value ();
}
class StringLeaf extends Tree {
public StringLeaf ( String s );
public String value ();
}
class Node extends Tree {
public Node ( String n, Trees cs ); // construct a new Node with a given name n and children cs
public String name (); // Node label
public Trees children (); // Node children
}
}}}
where the {{{Trees}}} class represents a list of ASTs (a linked list):
{{{
class Trees implements Iterable<Tree> {
public Tree head(); // the head of the list
public Trees tail(); // the rest of the list (the list without the head)
public Trees ( Tree e, Trees t ); // construct a new list with head e and tail t
public final static Trees nil; // the empty list (same as #[])
public Trees cons ( Tree e ); // put the element e before the list
public Trees append ( Tree e ); // append the element e at the end of list (does not change 'this')
public Trees append ( Trees s ); // append the list s at the end of list (does not change 'this')
public boolean is_empty (); // is this an empty list?
public int length (); // return the list length
public Trees reverse (); // return the reverse of the list (does not change 'this')
public boolean member ( Tree e ); // is e a member of the list?
public Tree nth ( int n ); // return the nth list element
}
}}}
To iterate over Trees, one can use Java iterators:
{{{
Trees ts = ...;
for( Tree e: ts )
System.out.println(e);
}}}