1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00
cs2j/CSharpTranslator/antlr2/Translator/JavaPrettyPrinter.g

812 lines
24 KiB
Plaintext
Raw Permalink Normal View History

header {
using System.Collections;
using System.IO;
using System.Xml;
using TokenStreamHiddenTokenFilter = antlr.TokenStreamHiddenTokenFilter;
}
options {
language = "CSharp";
namespace = "RusticiSoftware.Translator";
}
/** Java 1.3 AST Pretty Printer
*
* Author: Kevin Glynn <kevin.glynn@scorm.com>
*
* This grammar is based on the java tree walker included in ANTLR examples
*
*/
class JavaPrettyPrinter extends TreeParser("RusticiSoftware.Translator.JavaTreeParser");
options {
importVocab = CSharpJava;
buildAST = false;
}
{
private int indentLevel = 0;
private const string INDENT = " ";
private bool indented = false;
private bool doIndent = true;
private const int MAX_TOKEN_TYPE=350; // imprecise but big enough
private TokenStreamHiddenTokenFilter filter;
private XmlTextWriter enumXmlWriter;
private ArrayList enumMembers = new ArrayList();
private bool inClassModifiers = false; // Filter out static, this isn't the right place but pending rewrite this is quickest.
/** walk list of hidden tokens in order, printing them out */
public void dumpHidden(TextWriter w, antlr.IHiddenStreamToken t) {
for ( ; t!=null ; t=filter.getHiddenAfter(t) ) {
w.Write(t.getText());
}
}
/// <summary>
/// Prints the text of the specified AST node
/// </summary>
/// <param name="w">The output destination.</param>
/// <param name="node">The AST node to print.</param>
private void Print(TextWriter w, AST node)
{
Print(w, node, null);
}
/// <summary>
/// Prints the text
/// </summary>
/// <param name="w">The output destination.</param>
/// <param name="node">The AST node to print.</param>
private void Print(TextWriter w, string text)
{
Print(w, null, text);
}
/// <summary>
/// Prints the text of the AST node if it exists, then the text if it exists
/// </summary>
/// <param name="w">The output destination.</param>
/// <param name="node">The AST node to print.</param>
private void Print(TextWriter w, AST node, string text)
{
if (doIndent && !indented) {
PrintIndent(w);
}
if (node != null)
{
w.Write(node.getText());
}
if (text != null)
{
w.Write(text);
}
if (node != null)
{
// disable for now
// dumpHidden(w, ((antlr.CommonASTWithHiddenTokens)node).getHiddenAfter());
}
}
private void PrintNL(TextWriter w)
{
w.Write("\n"); // Should we be switching to use Environment.NewLine?
//w.Write(Environment.NewLine);
if (doIndent) indented = false;
}
private void PrintNLIfReq(TextWriter w)
{
if (doIndent && indented)
PrintNL(w);
}
private void PrintIndent(TextWriter w)
{
for (int i = 0; i < indentLevel; i++) {
w.Write(INDENT);
}
if (doIndent) indented = true;
}
private void WriteStartEnum(AST node)
{
if (enumXmlWriter != null)
{
enumXmlWriter.WriteStartElement("enum");
enumXmlWriter.WriteAttributeString("id", node.getText());
}
}
private void WriteEndEnum()
{
if (enumXmlWriter != null)
{
enumXmlWriter.WriteEndElement();
}
}
private void WriteEnumMembers()
{
if (enumXmlWriter != null)
{
int num = 0;
foreach (AST node in enumMembers)
{
enumXmlWriter.WriteStartElement("member");
enumXmlWriter.WriteAttributeString("id", node.getText());
enumXmlWriter.WriteAttributeString("value", num.ToString());
enumXmlWriter.WriteEndElement();
num++;
}
}
}
/// <summary>
/// Prints standard text at the top of each output file
/// </summary>
/// <param name="w">The output destination.</param>
/// <param name="emitDate">Emit Translation Date as part of prelude.</param>
private void PrintFilePrelude(TextWriter w, Boolean emitDate)
{
String stdPrelude = @"
//
//
// This file was translated from C# to Java by CS2J (http://www.cs2j.com).
//
// This code is to be used for evaluation of the CS2J tool ONLY.
//
// For more information about CS2J please contact cs2jcontact@scorm.com
//
";
if (emitDate) {
//stdPrelude += "// Translated: " + DateTime.Now.ToString("s") + Environment.NewLine +
// "//" + Environment.NewLine;
stdPrelude += "// Translated: " + DateTime.Now.ToString("s") + "\n//\n" ; // Switch to Environment.NewLine??
}
stdPrelude += "\n";
w.Write(stdPrelude);
}
// keving: Found this precedence table on the ANTLR site.
/** Encodes precedence of various operators; indexed by token type.
* If precedence[op1] > precedence[op2] then op1 should happen
* before op2;
*/
private static int[] precedence = new int[MAX_TOKEN_TYPE];
static JavaPrettyPrinter()
{
for (int i=0; i<precedence.Length; i++) {
// anything but these operators binds super tight
// for example METHOD_CALL binds tighter than PLUS
precedence[i] = int.MaxValue;
}
precedence[ASSIGN] = 1;
precedence[PLUS_ASSIGN] = 1;
precedence[MINUS_ASSIGN] = 1;
precedence[STAR_ASSIGN] = 1;
precedence[DIV_ASSIGN] = 1;
precedence[MOD_ASSIGN] = 1;
precedence[SHIFTR_ASSIGN] = 1;
//precedence[BSR_ASSIGN] = 1;
precedence[SHIFTL_ASSIGN] = 1;
precedence[BIN_AND_ASSIGN] =1;
precedence[BIN_XOR_ASSIGN] = 1;
precedence[BIN_OR_ASSIGN] = 1;
precedence[QUESTION] = 2;
precedence[LOG_OR] = 3;
precedence[LOG_AND] = 4;
precedence[BIN_OR] = 5;
precedence[BIN_XOR] = 6;
precedence[BIN_AND] = 7;
precedence[NOT_EQUAL] = 8;
precedence[EQUAL] = 8;
precedence[LTHAN] = 9;
precedence[GTHAN] = 9;
precedence[LTE] = 9;
precedence[GTE] = 9;
precedence[INSTANCEOF] = 9;
precedence[SHIFTL] = 10;
precedence[SHIFTR] = 10;
//precedence[BSR] = 10;
precedence[PLUS] = 11;
precedence[MINUS] = 11;
precedence[DIV] = 12;
precedence[MOD] = 12;
precedence[STAR] = 12;
precedence[INC] = 13;
precedence[DEC] = 13;
precedence[BIN_NOT] = 13;
precedence[LOG_NOT] = 13;
precedence[UNARY_MINUS] = 13;
precedence[UNARY_PLUS] = 13;
precedence[POST_INC_EXPR] = 14;
precedence[POST_DEC_EXPR] = 14;
}
// Compares precedence of op1 and op2.
// Returns -1 if op2 < op1
// 0 if op1 == op2
// 1 if op2 > op1
public static int comparePrecedence(AST op1, AST op2) {
// A gross hack for "instanceof" (no longer necessary with C# front end :-))
// if (op1.getText() == "instanceof")
// precedence[op1.Type] = 9;
// if (op2.getText() == "instanceof")
// precedence[op2.Type] = 9;
return Math.Sign(precedence[op2.Type]-precedence[op1.Type]);
}
}
compilationUnit [TextWriter w, XmlTextWriter enumXmlWriter, TokenStreamHiddenTokenFilter f, Boolean emitDate]
{ filter = f; this.enumXmlWriter = enumXmlWriter; PrintFilePrelude(w, emitDate); }
: #( COMPILATION_UNIT
packageDefinition[w]
useDefinitions[TextWriter.Null] // No output for uses
importDefinitions[w]
(typeDefinition[w])*
)
;
packageDefinition [TextWriter w]
: #( pkg:PACKAGE_DEF ({ Print(w, #pkg, " "); } identifier[w] { Print(w, ";"); PrintNL(w); })? )
;
useDefinitions [TextWriter w]
: #( USING_DIRECTIVES
(useDefinition[w])*
)
;
useDefinition [TextWriter w]
: #( USING_NAMESPACE_DIRECTIVE
identifier[w]
)
| #( USING_ALIAS_DIRECTIVE
alias:identifier[w]
pna:identifier[w]
)
;
importDefinitions [TextWriter w]
: #( IMPORTS
( { PrintNL(w); } (importDefinition[w])+ )?
) { PrintNL(w); }
;
importDefinition [TextWriter w]
: #( imp:IMPORT { Print(w, #imp, " "); }
identifier[w] { Print(w, ";"); PrintNL(w); }
)
;
typeDefinition [TextWriter w]
: #(cl:CLASS {inClassModifiers = true; }
modifiers[w] {inClassModifiers = false; }
id:IDENTIFIER { Print(w, "class "); Print(w, #id, " "); }
extendsClause[w]
implementsClause[w] { PrintNL(w); Print(w, "{"); PrintNL(w); indentLevel++; }
objBlock[w] { indentLevel--; Print(w, "}"); PrintNL(w); }
)
| #(INTERFACE
modifiers[w]
ifid:IDENTIFIER { Print(w, "interface "); Print(w, #ifid, " "); }
implementsClause[w] { PrintNL(w); Print(w, "{"); PrintNL(w); indentLevel++; }
interfaceBlock[w] { indentLevel--; Print(w, "}"); PrintNL(w); }
)
| #(ENUM
modifiers[w]
enmid:IDENTIFIER { Print(w, "enum "); Print(w, #enmid, " "); WriteStartEnum(#enmid); }
implementsClause[w] { PrintNL(w); Print(w, "{"); PrintNL(w); indentLevel++; }
enumBlock[w] { indentLevel--; Print(w, "}"); PrintNL(w); WriteEndEnum(); }
)
| #(ann:ANNOTATION
modifiers[w]
annid:IDENTIFIER { Print(w, "@interface "); Print(w, #annid, " "); PrintNL(w); Print(w, "{"); PrintNL(w); indentLevel++;}
objBlock[w] { indentLevel--; Print(w, "}"); PrintNL(w); }
)
;
typeSpec [TextWriter w]
: #(TYPE
( identifier[w]
| builtInType[w]
)
rankSpecifiers[w]
)
;
rankSpecifiers [TextWriter w]
: #( ARRAY_RANKS
( rankSpecifier[w]
)*
)
;
rankSpecifier [TextWriter w]
: #(ARRAY_RANK
( COMMA // Notice, we ignore dimensions.
)*
) { Print(w, "[]"); }
;
typeSpecArray [TextWriter w]
: #( ARRAY_DECLARATOR
typeSpecArray[w] { Print(w, "[]"); }
)
| type[w]
;
type [TextWriter w]
: identifier[w]
| builtInType[w]
;
builtInType [TextWriter w]
: tvo:VOID { Print(w, #tvo); }
| tbo:BOOL { Print(w, #tbo); }
| tst:STRING { Print(w, #tst); }
| tby:SBYTE { Print(w, #tby); }
| tch:"char" { Print(w, #tch); }
| tsh:"short" { Print(w, #tsh); }
| tin:"int" { Print(w, #tin); }
| tfl:"float" { Print(w, #tfl); }
| tlo:"long" { Print(w, #tlo); }
| tdo:"double" { Print(w, #tdo); }
| tuby: UBYTE { Print(w, #tuby); }
| tudec: DECIMAL { Print(w, #tudec); }
| tuint: UINT { Print(w, #tuint); }
| tulng: ULONG { Print(w, #tulng); }
| tush: USHORT { Print(w, #tush); }
| tb: BYTE { Print(w, #tb); }
;
modifiers [TextWriter w]
: #( MODIFIERS (modifier[w] { Print (w, " "); }
)* )
;
modifier [TextWriter w]
: mpr:"private" { Print(w, #mpr); }
| mpu:"public" { Print(w, #mpu); }
| mpt:"protected" { Print(w, #mpt); }
| mst:"static" { if (!inClassModifiers) {Print(w, #mst);} }
| mtr:"transient" { Print(w, #mtr); }
| mfi:FINAL { Print(w, #mfi); }
| mab:ABSTRACT { Print(w, #mab); }
| mna:"native" { Print(w, #mna); }
| mth:"threadsafe" { Print(w, #mth); }
| msy:"synchronized" { Print(w, #msy); }
| mco:"const" { Print(w, #mco); }
| mvo:"volatile" { Print(w, #mvo); }
| msf:"strictfp" { Print(w, #msf); }
;
extendsClause [TextWriter w]
//OK, OK, really we can only extend 1 class, but the tree stores a list so ....
: #(EXTENDS_CLAUSE
( { Print(w, "extends "); } identifier[w] ({ Print(w, ", "); } identifier[w])* { Print(w, " "); } )?
)
;
implementsClause [TextWriter w]
: #(IMPLEMENTS_CLAUSE
( { Print(w, "implements "); } identifier[w] ({ Print(w, ", "); } identifier[w])* { Print(w, " "); } )?
)
;
interfaceBlock [TextWriter w]
: #( MEMBER_LIST
( methodDecl[w] { Print(w, ";"); PrintNL(w); }
| variableDef[w] { Print(w, ";"); PrintNL(w); }
| typeDefinition[w]
)*
)
;
objBlock [TextWriter w]
: #( MEMBER_LIST
(
( { PrintNL(w); } ctorDef[w]
| { PrintNL(w); } methodDef[w]
| variableDef[w] { Print(w, ";"); }
| { PrintNL(w); } typeDefinition[w]
| { PrintNL(w); } #(STATIC_CTOR_DECL { Print(w, "static"); PrintNL(w); }
slist[w] )
| { PrintNL(w); } #(INSTANCE_INIT
slist[w] )
) { PrintNLIfReq(w); }
)*
)
;
// This enumblock is from Java 1.3, in theory enums can have methods, nested enums, ....
enumBlock [TextWriter w]
{ enumMembers.Clear(); }
: #( MEMBER_LIST ( alt1:IDENTIFIER { Print(w, #alt1); enumMembers.Add(#alt1); } ( alts:IDENTIFIER { Print(w, ", "); Print(w, #alts); enumMembers.Add(#alts); } )* { PrintNL(w); WriteEnumMembers(); } )? )
;
ctorDef [TextWriter w]
: #(CTOR_DECL
modifiers[w]
methodHead[w]
(slist[w])?)
;
methodDecl [TextWriter w]
: #(METHOD_DECL
modifiers[w]
typeSpec[w] { Print(w, " "); }
methodHead[w])
;
methodDef [TextWriter w]
: #(METHOD_DECL
modifiers[w]
typeSpec[w] { Print(w, " "); }
methodHead[w]
(slist[w])?
)
;
variableDef [TextWriter w]
: #(FIELD_DECL
modifiers[w]
typeSpec[w] { Print(w, " "); }
variableDeclarator[w] ( {Print(w, ", "); } variableDeclarator[w])*
//varInitializer[w]
)
;
parameterDef [TextWriter w]
: #(PARAMETER_FIXED
typeSpec[w] { Print(w, " "); }
id:IDENTIFIER { Print(w, #id); }
)
| #(PARAMS typeSpec[w] { Print(w, "... "); } ids:IDENTIFIER { Print(w, #ids); } )
;
objectinitializer [TextWriter w]
: #(INSTANCE_INIT
slist[w] )
;
variableDeclarator [TextWriter w]
: #( VAR_DECLARATOR
id:IDENTIFIER { Print(w, #id); }
(varInitializer[w])?
)
// | LBRACK variableDeclarator[w] { Print(w, "[]"); }
;
varInitializer [TextWriter w]
: #(VAR_INIT { Print(w, " = "); }
initializer[w])
;
initializer [TextWriter w]
: expression[w]
| arrayInitializer[w]
;
arrayInitializer [TextWriter w]
: #(ARRAY_INIT
{ Print(w, "{"); }
( initializer[w] ( { Print(w, ", "); } initializer[w] )* )?
{ Print(w, "}"); }
)
;
methodHead [TextWriter w]
: id:IDENTIFIER { Print(w, #id); }
#( FORMAL_PARAMETER_LIST
{ Print(w, "("); }
( parameterDef[w] ( { Print(w, ", "); } parameterDef[w] )* )?
{ Print(w, ") "); }
)
( throwsClause[w])? { PrintNL(w); }
;
throwsClause [TextWriter w]
: #( th:"throws" { Print(w, #th, " "); }
( identifier[w] ( { Print(w, ", "); } identifier[w] )* )?
)
;
identifier [TextWriter w]
: id:IDENTIFIER { Print(w, #id); }
| #( DOT id1:IDENTIFIER { Print(w, #id1); Print(w, "."); } identifier[w] )
;
identifierStar [TextWriter w]
: id:IDENTIFIER { Print(w, #id); }
| st:STAR { Print(w, "."); Print(w, #st); }
| #( DOT id1:IDENTIFIER { Print(w, #id1); Print(w, "."); } identifier[w] )
;
slist [TextWriter w]
: #( BLOCK { Print(w, "{"); PrintNL(w); indentLevel++; } (stat[w])* { indentLevel--; Print(w, "}"); PrintNL(w); } )
| EMPTY_STMT { Print(w, ";"); PrintNL(w); }
;
// Like a slist[] but we don't indent. Appears in switch alternatives
statementList [TextWriter w]
: #( STMT_LIST (stat[w])* )
;
stat [TextWriter w]
:(
typeDefinition[w]
| variableDef[w] { Print(w, ";"); }
| #(EXPR_STMT expression[w]) { Print(w, ";"); }
| #(LABEL_STMT id:IDENTIFIER { Print(w, #id, ": "); } stat[w])
| #(lif:IF { Print(w, #lif, " ("); }
expression[w] { Print(w, ")"); PrintNL(w); }
stat[w]
( #(ELSE { Print(w, "else"); PrintNL(w); }
stat[w])
)?
)
| #( fo:"for" { Print(w, #fo, " ("); }
#(FOR_INIT (variableDef[w])* (expression[w] ( { Print(w, ", "); } expression[w])* )?) { Print(w, "; "); }
#(FOR_COND (expression[w])?) { Print(w, "; "); }
#(FOR_ITER (expression[w] ( { Print(w, ", "); } expression[w])* )?) { Print(w, ")"); PrintNL(w); }
stat[w]
)
| #(fe:"foreach" { Print(w, "for ("); }
variableDef[w] { Print(w, " : "); }
expression[w] { Print(w, ")"); PrintNL(w); }
stat[w]
)
| #(wh:"while" { Print(w, #wh, " ("); }
expression[w] { Print(w, ")"); PrintNL(w); }
stat[w]
)
| #(dd:"do" { Print(w, #dd); PrintNL(w); }
stat[w] { Print(w, "while ("); }
expression[w] { Print(w, ");"); }
)
| #(gt:"goto" { Print(w, "// TODO: CS2J: goto is not supported by Java."); PrintNL(w); Print(w, "continue "); } gid:IDENTIFIER { Print(w, #gid); Print(w, ";"); } )
| #(br:"break" { Print(w, #br); } ( { Print(w, " "); } bid:IDENTIFIER { Print(w, #bid); } )? { Print(w, ";"); } )
| #(co:"continue" { Print(w, #co); } ( { Print(w, " "); } cid:IDENTIFIER { Print(w, #cid); } )? { Print(w, ";"); } )
| #(re:"return" { Print(w, #re); } ( { Print(w, " "); } expression[w])? { Print(w, ";"); } )
| #(sw:"switch" { Print(w, #sw, " ("); }
expression[w] { Print(w, ")"); PrintNL(w); Print(w, "{"); indentLevel++; PrintNL(w); }
(caseGroup[w])*
) { indentLevel--; Print(w, "}"); }
| #(th:"throw" { Print(w, #th, " "); } expression[w] { Print(w, ";"); } )
| #(sy:"synchronized" { Print(w, #sy, " ("); }
expression[w] { Print(w, ")"); PrintNL(w); }
stat[w]
)
| tryBlock[w]
| slist[w] // nested SLIST (keving: should this be surrounded by braces?)
// uncomment to make assert JDK 1.4 stuff work
// | #("assert" expression[w] (expression[w])?)
| ctorCall[w] { Print(w, ";"); }
) { PrintNLIfReq(w); }
;
caseGroup [TextWriter w]
: #(SWITCH_SECTION (#(ca:"case" { Print(w, #ca, " "); }
expression[w]) { Print(w, ":"); PrintNL(w); indentLevel++; }
| de:"default" { Print(w, #de, ":"); PrintNL(w); indentLevel++; } )+
statementList[w] ) { indentLevel--; }
;
tryBlock [TextWriter w]
: #( tr:"try" { Print(w, #tr); PrintNL(w); }
slist[w]
(handler[w])*
(#(fi:"finally" { Print(w, #fi); PrintNL(w); }
slist[w]
))?
)
;
handler [TextWriter w]
: #( ca:"catch" { Print(w, #ca, " ("); }
( typeSpec[w] | variableDef[w]) { Print(w, ")"); PrintNL(w); }
slist[w]
)
;
elist [TextWriter w]
: #( EXPR_LIST
( expression[w] ( { Print(w, ", "); } expression[w] )* )?
)
;
expression [TextWriter w]
: #(EXPR expr[w])
;
expr [TextWriter w]
// QUESTION is right associative in C# and left-associative in Java, but we always parenthesize :-)
: #(QUESTION { Print(w, "( "); } expr[w] { Print(w, " ? "); } expr[w] { Print(w, " : "); } expr[w] { Print(w, " )"); }) // trinary operator
// binary operators...
| (ASSIGN|PLUS_ASSIGN|MINUS_ASSIGN|STAR_ASSIGN|DIV_ASSIGN
|MOD_ASSIGN|SHIFTR_ASSIGN|BSR_ASSIGN|SHIFTL_ASSIGN|BIN_AND_ASSIGN
|BIN_XOR_ASSIGN|BIN_OR_ASSIGN|LOG_OR|LOG_AND|BIN_OR|BIN_XOR|BIN_AND|NOT_EQUAL
|EQUAL|LTHAN|GTHAN|LTE|GTE|SHIFTL|SHIFTR|BSR|PLUS|MINUS|DIV|MOD|STAR|INSTANCEOF
)
{
AST op = #expr;
AST left = op.getFirstChild();
AST right = left.getNextSibling();
bool lp = false;
bool rp = false;
switch ( comparePrecedence(op,left) )
{
case -1 :
lp = true;
break;
case 0 :
if (op.Type == ASSIGN) lp = true; // ASSIGN/QUESTION is right associative in C#
break;
case 1:
break;
}
switch ( comparePrecedence(op,right) )
{
case -1:
rp = true;
break;
case 0:
if (op.Type != ASSIGN) rp = true; // All operators except ASSIGN/QUESTION are left associative in C#
break;
case 1:
break;
}
if ( lp ) Print(w, "(");
expr(left,w);
if ( lp ) Print(w, ")");
Print(w, " "+#op.getText()+" ");
if ( rp ) Print(w, "(");
expr(right,w); // manually invoke
if ( rp ) Print(w, ")");
}
| (INC|DEC|BIN_NOT|LOG_NOT|UNARY_MINUS|UNARY_PLUS)
{
AST op = #expr;
AST opnd = op.getFirstChild();
bool p = false;
if ( comparePrecedence(op,opnd) == -1) {
p = true;
}
Print(w, op.getText());
if ( p ) Print(w, "(");
expr(opnd, w);
if ( p ) Print(w, ")");
}
| #( POST_INC_EXPR expr[w] {Print(w, "++");} )
| #( POST_DEC_EXPR expr[w] {Print(w, "--");} )
| primaryExpression[w]
;
primaryExpression [TextWriter w]
: id:IDENTIFIER { Print(w, #id); }
| #( MEMBER_ACCESS_EXPR
( expr[w] { Print(w, "."); }
( did:IDENTIFIER { Print(w, #did); }
| arrayIndex[w]
| dth:"this" { Print(w, #dth); }
| dcl:"class" { Print(w, #dcl); }
| #( dne:"new" dni:IDENTIFIER { Print(w, #dne, " "); Print(w, dni, "("); } elist[w] { Print(w, ")"); } )
| dsu:"super" { Print(w, #dsu); }
)
| { Print(w, "."); } #(ARRAY_DECLARATOR typeSpecArray[w] { Print(w, "[]"); } )
| { Print(w, "."); } builtInType[w] (ddcl:"class" { Print(w, #ddcl); } )?
)
)
| arrayIndex[w]
| #(INVOCATION_EXPR primaryExpression[w] { Print(w, "("); } elist[w] { Print(w, ")"); })
| #(CAST_EXPR { Print(w, "(("); } typeSpec[w] { Print(w, ")("); } expr[w] { Print(w, "))"); } )
| newExpression[w]
| constant[w]
| su:"super" { Print(w, #su); }
| tr:"true" { Print(w, #tr); }
| fa:"false" { Print(w, #fa); }
| th:"this" { Print(w, #th); }
| nu:NULL { Print(w, #nu); }
| typeSpec[w] // type name used with instanceof
// javaTxt = text to be printed
// env = map from env-vars to AST
| javaWrapper[w]
;
javaWrapper [TextWriter w]
{ string javaTxt = ""; }
: #( JAVAWRAPPER javaTemplate:IDENTIFIER { javaTxt = javaTemplate.getText(); }
( { StringWriter sw = new StringWriter();
bool saveDoIndent = doIndent;
doIndent = false;
}
v:IDENTIFIER (expression[sw] | expr[sw] | elist[sw] )
{ javaTxt = javaTxt.Replace(#v.getText(), sw.ToString());
sw.Close();
doIndent = saveDoIndent; } )*
)
{ Print(w, javaTxt); }
;
ctorCall [TextWriter w]
: #( THIS { Print(w, "this("); } elist[w] { Print(w, ")"); })
| #( BASE { Print(w, "super("); } elist[w] { Print(w, ")"); })
;
arrayIndex [TextWriter w]
: #(ELEMENT_ACCESS_EXPR expr[w] { Print(w, "["); } elist[w] { Print(w, "]"); } )
;
constant [TextWriter w]
: it:INT_LITERAL { Print(w, #it); }
| ch:CHAR_LITERAL { Print(w, #ch); }
| st:STRING_LITERAL { Print(w, #st); }
| fl:NUM_FLOAT { Print(w, #fl); }
| db:DOUBLE_LITERAL { Print(w, #db); }
| flt:FLOAT_LITERAL { Print(w, #flt); }
| lo:LONG_LITERAL { Print(w, #lo); Print(w, "L"); }
| ul:ULONG_LITERAL { Print(w, #ul); Print(w, "L"); }
| de:DECIMAL_LITERAL { Print(w, #de, "/* Unsupported Decimal Literal */"); }
;
newExpression [TextWriter w]
: #( ne:OBJ_CREATE_EXPR { Print(w, #ne, " "); }
typeSpec[w]
{ Print(w, "("); } elist[w] { Print(w, ")"); }
( { PrintNL(w); indentLevel++; Print(w, "{"); PrintNL(w); indentLevel++; }
objBlock[w]
{ indentLevel--; Print(w, "}"); indentLevel--; PrintNL(w); }
)?
)
| #( na:ARRAY_CREATE_EXPR { Print(w, #na, " "); }
typeSpec[w]
( arrayInitializer[w] //rankSpecifiers[w]!
| { Print(w, "["); } elist[w] {Print(w, "]"); }
rankSpecifiers[w] ( arrayInitializer[w] )?
)
)
;
// newArrayDeclarator [TextWriter w]
// : #( ARRAY_DECLARATOR (newArrayDeclarator[w])? { Print(w, "["); }(expression[w])? { Print(w, "]"); })
// ;