diff --git a/CSharpTranslator/.project b/CSharpTranslator/.project
new file mode 100644
index 0000000..a565c18
--- /dev/null
+++ b/CSharpTranslator/.project
@@ -0,0 +1,11 @@
+
+
+ CSharpTranslator
+
+
+
+
+
+
+
+
diff --git a/CSharpTranslator/CSharpTranslator.sln b/CSharpTranslator/CSharpTranslator.sln
new file mode 100644
index 0000000..bc3f6cd
--- /dev/null
+++ b/CSharpTranslator/CSharpTranslator.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Translator", "Translator\Translator.csproj", "{D33074E4-1525-4F22-A1DB-A7F30989D8FE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8ECA4801-3F48-4FD1-91B4-4DFB567D913B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D33074E4-1525-4F22-A1DB-A7F30989D8FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D33074E4-1525-4F22-A1DB-A7F30989D8FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D33074E4-1525-4F22-A1DB-A7F30989D8FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D33074E4-1525-4F22-A1DB-A7F30989D8FE}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/CSharpTranslator/RusticiLogicTranslator/build.properties b/CSharpTranslator/RusticiLogicTranslator/build.properties
new file mode 100644
index 0000000..d3aeda5
--- /dev/null
+++ b/CSharpTranslator/RusticiLogicTranslator/build.properties
@@ -0,0 +1,51 @@
+build.dir=${basedir}/build
+svntx.build.dir=${build.dir}/svntx
+cs2jtx.build.dir=${build.dir}/cs2jtx
+cs2jtx.bin.dir=${cs2jtx.build.dir}/Translator/bin/Debug
+svntxexe.svnwc.dir=${basedir}/
+
+## WARNING: If these boolean properties are shown through the launch dialog then
+## we must deal with value == false
+is.rebuild.cs2j=true
+is.cs2j.svnwc=true
+is.commit.javacode=false
+
+svn.commit.msg.java=Auto-committed following cs2j translation
+svn.commit.removed.msg.java=Auto-committed removed files following cs2j translation
+
+svn.repo=https://svn.rusticisoftware.com/svn/projects
+csharp.project=Products/ScormEngineNet
+csharp.project.branch=trunk
+csharp.tx.sub.dir=src/app/ScormEngine.Core
+csharp.project.full=${csharp.project}/${csharp.project.branch}
+csharpcode.branch.url=${svn.repo}/${csharp.project.full}/${csharp.tx.sub.dir}
+
+csharptx.dir=ScormEngine.Core
+csharpcode.dir=${svntx.build.dir}/${csharptx.dir}
+
+csharpcode.tx.dir=${svntx.build.dir}/${csharptx.dir}/Logic
+
+java.project=Products/ScormEngineJava
+java.project.branch=${csharp.project.branch}
+java.tx.sub.dir=RusticiSoftware.ScormContentPlayer.Logic/src
+java.project.full=${java.project}/${java.project.branch}
+javacode.branch.url=${svn.repo}/${java.project.full}/${java.tx.sub.dir}
+
+javatx.dir=${java.tx.sub.dir}
+javacode.svnwc.dir=${svntx.build.dir}/${javatx.dir}
+javacode.old.svnwc.dir=${svntx.build.dir}/OldJava/${javatx.dir}
+
+cs2j.project=Products/CS2JLibrary
+#cs2j.project.branch=${csharp.project.branch}
+cs2j.project.branch=trunk
+cs2j.branch.url=${svn.repo}/${cs2j.project}/${cs2j.project.branch}/
+
+cs2j.dir=${svntx.build.dir}/CS2JLibrary
+
+cheats.dir=${svntx.build.dir}/Cheats
+
+svn.exe=svn
+
+
+builder.ant.lib=${basedir}/lib
+builder.ant.dll=${basedir}/dll
diff --git a/CSharpTranslator/RusticiLogicTranslator/build.xml b/CSharpTranslator/RusticiLogicTranslator/build.xml
new file mode 100644
index 0000000..21b83c9
--- /dev/null
+++ b/CSharpTranslator/RusticiLogicTranslator/build.xml
@@ -0,0 +1,209 @@
+
+
+
+
+ This script automates translation of a C# svn branch to a Java branch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CSharpTranslator/Translator/ASTNode.cs b/CSharpTranslator/Translator/ASTNode.cs
new file mode 100644
index 0000000..56b3a7b
--- /dev/null
+++ b/CSharpTranslator/Translator/ASTNode.cs
@@ -0,0 +1,259 @@
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+namespace RusticiSoftware.Translator
+{
+ using System;
+ using FileInfo = System.IO.FileInfo;
+ using StringBuilder = System.Text.StringBuilder;
+ using AST = antlr.collections.AST;
+ using BaseAST = antlr.BaseAST;
+ using ASTFactory = antlr.ASTFactory;
+ using IToken = antlr.IToken;
+ using CommonASTWithHiddenTokens = antlr.CommonASTWithHiddenTokens;
+ using CommonHiddenStreamToken = antlr.CommonHiddenStreamToken;
+
+
+ ///
+ /// Summary description for ASTNode.
+ ///
+ ///
+ [Serializable()]
+ public class ASTNode : CommonASTWithHiddenTokens
+ {
+ new public static readonly ASTNode.ASTNodeCreator Creator = new ASTNodeCreator();
+
+ //---------------------------------------------------------------------
+ // CONSTRUCTORS
+ //---------------------------------------------------------------------
+
+ public ASTNode() : base()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
+ public ASTNode(IToken tok) : base(tok)
+ {
+ }
+
+ //---------------------------------------------------------------------
+ // PUBLIC METHODS
+ //---------------------------------------------------------------------
+
+ override public void initialize(antlr.collections.AST t)
+ {
+ base.initialize(t);
+ ASTNode node = t as ASTNode;
+ if (null != node)
+ {
+ Column = node._column;
+ Line = node._line;
+ DotNetType = node._dotNetType;
+ _fileinfo = node._fileinfo;
+ _previousSibling = node._previousSibling;
+ _parentNode = node._parentNode;
+ }
+ }
+ override public void initialize(IToken tok)
+ {
+ base.initialize(tok);
+ Column = tok.getColumn();
+ Line = tok.getLine();
+
+ CustomHiddenStreamToken ctok = tok as CustomHiddenStreamToken;
+ if (null != ctok)
+ {
+ File = ctok.File;
+ }
+ }
+
+ public virtual ASTNode GetFirstChildOfType(int type)
+ {
+ ASTNode result = null;
+
+ AST sibling = getFirstChild();
+ while (sibling != null)
+ {
+ if (sibling.Type == type)
+ {
+ result = (ASTNode) sibling;
+ break;
+ }
+ sibling = sibling.getNextSibling();
+ }
+
+ return result;
+ }
+
+ public void CopyPositionFrom(ASTNode other)
+ {
+ Line = other.Line;
+ Column = other.Column;
+ }
+
+ //---------------------------------------------------------------------
+ // ACCESSORS & MUTATORS
+ //---------------------------------------------------------------------
+
+ ///
+ /// Gets or sets the contents of the hidden-before token stream.
+ ///
+ ///
+ public CustomHiddenStreamToken HiddenBefore
+ {
+ get { return (CustomHiddenStreamToken) hiddenBefore; }
+ set { hiddenBefore = (CommonHiddenStreamToken) value; }
+ }
+
+ ///
+ /// Gets or sets the contents of the hidden-after token stream.
+ ///
+ ///
+ public CustomHiddenStreamToken HiddenAfter
+ {
+ get { return (CustomHiddenStreamToken) hiddenAfter; }
+ set { hiddenAfter = (CommonHiddenStreamToken) value; }
+ }
+
+ ///
+ /// Gets or Sets the source file line position for this Node
+ ///
+ ///
+ public int Line
+ {
+ get { return _line; }
+ set {_line = value; }
+ }
+ ///
+ /// Gets or Sets the source file column position for this Node
+ ///
+ ///
+ public int Column
+ {
+ get { return _column; }
+ set {_column = value; }
+ }
+ ///
+ /// Gets or Sets the source file for this Node
+ ///
+ ///
+ public FileInfo File
+ {
+ get { return _fileinfo; }
+ set { _fileinfo = value; }
+ }
+
+ public TypeRep DotNetType
+ {
+ get { return _dotNetType; }
+ set { _dotNetType = value; }
+ }
+
+ public ASTNode getParent()
+ {
+ return _parentNode;
+ }
+
+ public ASTNode getPreviousSibling()
+ {
+ return _previousSibling;
+ }
+
+ public void setParent(ASTNode parent)
+ {
+ this._parentNode = parent;
+ }
+
+ public void setPreviousSibling(ASTNode previousSibling)
+ {
+ this._previousSibling = previousSibling;
+ }
+
+ public virtual void addChildEx(ASTNode node)
+ {
+ if (node == null)
+ return ;
+ ASTNode t = (ASTNode) this.down;
+ if (t != null)
+ {
+ while (t.right != null)
+ {
+ t = (ASTNode) t.right;
+ }
+ t.right = (BaseAST) node;
+ node._previousSibling = t;
+ node._parentNode = this;
+ }
+ else
+ {
+ this.down = (BaseAST) node;
+ node._parentNode = this;
+ node._previousSibling = null;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ // PRIVATE DATA MEMBERS
+ //---------------------------------------------------------------------
+ private int _column = -1;
+ private int _line = -1;
+ private FileInfo _fileinfo;
+ private ASTNode _parentNode;
+ private ASTNode _previousSibling;
+ private TypeRep _dotNetType = null;
+
+
+
+ public class ASTNodeCreator : antlr.ASTNodeCreator
+ {
+ public ASTNodeCreator() {}
+
+ ///
+ /// Returns the fully qualified name of the AST type that this
+ /// class creates.
+ ///
+ public override string ASTNodeTypeName
+ {
+ get
+ {
+ return typeof(ASTNode).FullName;;
+ }
+ }
+
+ ///
+ /// Constructs a instance.
+ ///
+ public override AST Create()
+ {
+ return new ASTNode();
+ }
+ }
+ }
+}
diff --git a/CSharpTranslator/Translator/ASTNodeFactory.cs b/CSharpTranslator/Translator/ASTNodeFactory.cs
new file mode 100644
index 0000000..b3756eb
--- /dev/null
+++ b/CSharpTranslator/Translator/ASTNodeFactory.cs
@@ -0,0 +1,254 @@
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+namespace RusticiSoftware.Translator
+{
+ using System;
+ using FileInfo = System.IO.FileInfo;
+ using AST = antlr.collections.AST;
+ using ASTPair = antlr.ASTPair;
+ using ASTFactory = antlr.ASTFactory;
+
+ public class ASTNodeFactory : ASTFactory
+ {
+ //---------------------------------------------------------------------
+ // CONSTRUCTORS
+ //---------------------------------------------------------------------
+
+ ///
+ /// Constructs an ASTNodeFactory with the default AST node type.
+ ///
+ public ASTNodeFactory() :
+ base(typeof(ASTNode).FullName)
+ {
+ setASTNodeCreator(new ASTNode.ASTNodeCreator());
+ }
+
+ ///
+ /// Constructs an ASTNodeFactory with the specified AST node type
+ /// as the default.
+ ///
+ /// Default AST node type name.
+ public ASTNodeFactory(string nodeTypeName) :
+ base(typeof(ASTNode).FullName)
+ {
+ setASTNodeCreator(new ASTNode.ASTNodeCreator());
+ }
+
+ //---------------------------------------------------------------------
+ // DATA MEMBERS
+ //---------------------------------------------------------------------
+ private FileInfo filefinfo_;
+
+
+ //---------------------------------------------------------------------
+ // FUNCTION MEMBERS
+ //---------------------------------------------------------------------
+
+ public FileInfo FileInfo
+ {
+ get { return filefinfo_; }
+ set { filefinfo_ = value; }
+ }
+
+ ///
+ /// Add a child to the current AST
+ ///
+ /// The AST to add a child to
+ /// The child AST to be added
+ public override void addASTChild(ref ASTPair currentAST, AST child)
+ {
+ if (child != null)
+ {
+ if (currentAST.root == null)
+ {
+ // Make new child the current root
+ currentAST.root = child;
+ ((ASTNode) child).setParent(null);
+ }
+ else
+ {
+ ((ASTNode) child).setParent((ASTNode) currentAST.root);
+ if (currentAST.child == null)
+ {
+ // Add new child to current root
+ currentAST.root.setFirstChild(child);
+ ((ASTNode) child).setPreviousSibling(null);
+ }
+ else
+ {
+ currentAST.child.setNextSibling(child);
+ ((ASTNode) child).setPreviousSibling((ASTNode) currentAST.child);
+ }
+ }
+ // Make new child the current child
+ currentAST.child = child;
+ currentAST.advanceChildToEnd();
+ }
+ }
+
+ ///
+ /// Duplicate AST Node tree rooted at specified AST node and all of it's siblings.
+ ///
+ /// Root of AST Node tree.
+ /// Root node of new AST Node tree (or null if t is null).
+ public override AST dupList(AST t)
+ {
+ AST result = dupTree(t); // if t == null, then result==null
+ AST nt = result;
+ while (t != null)
+ {
+ // for each sibling of the root
+ t = t.getNextSibling();
+ AST d = dupTree(t);
+ nt.setNextSibling(d); // dup each subtree, building new tree
+ if (d != null) ((ASTNode) d).setPreviousSibling((ASTNode) nt);
+ nt = nt.getNextSibling();
+ }
+ return result;
+ }
+
+ ///
+ /// Duplicate AST Node tree rooted at specified AST node. Ignore it's siblings.
+ ///
+ /// Root of AST Node tree.
+ /// Root node of new AST Node tree (or null if t is null).
+ public override AST dupTree(AST t)
+ {
+ AST result = dup(t); // make copy of root
+ // copy all children of root.
+ if (t != null)
+ {
+ AST d = dupList(t.getFirstChild());
+ result.setFirstChild(d);
+ if (d != null) ((ASTNode) d).setParent((ASTNode) result);
+ }
+ return result;
+ }
+
+ ///
+ /// Make a tree from a list of nodes. The first element in the
+ /// array is the root. If the root is null, then the tree is
+ /// a simple list not a tree. Handles null children nodes correctly.
+ /// For example, build(a, b, null, c) yields tree (a b c). build(null,a,b)
+ /// yields tree (nil a b).
+ ///
+ /// List of Nodes.
+ /// AST Node tree.
+ public override AST make(params AST[] nodes)
+ {
+ if (nodes == null || nodes.Length == 0)
+ return null;
+ AST root = nodes[0];
+ AST tail = null;
+ if (root != null)
+ {
+ root.setFirstChild(null); // don't leave any old pointers set
+ }
+ // link in children;
+ for (int i = 1; i < nodes.Length; i++)
+ {
+ if (nodes[i] == null)
+ continue;
+ // ignore null nodes
+ if (root == null)
+ {
+ // Set the root and set it up for a flat list
+ root = (tail = nodes[i]);
+ }
+ else if (tail == null)
+ {
+ root.setFirstChild(nodes[i]);
+ ((ASTNode) nodes[i]).setParent((ASTNode) root);
+ tail = root.getFirstChild();
+ }
+ else
+ {
+ ((ASTNode) nodes[i]).setParent((ASTNode) root);
+ tail.setNextSibling(nodes[i]);
+ ((ASTNode) nodes[i]).setPreviousSibling((ASTNode) tail);
+ tail = tail.getNextSibling();
+ }
+ // Chase tail to last sibling
+ while (tail.getNextSibling() != null)
+ {
+ tail = tail.getNextSibling();
+ }
+ }
+ return root;
+ }
+
+ ///
+ /// Make an AST the root of current AST.
+ ///
+ ///
+ ///
+ public override void makeASTRoot(ref ASTPair currentAST, AST root)
+ {
+ if (root != null)
+ {
+ // Add the current root as a child of new root
+ ((ASTNode) root).addChildEx((ASTNode) currentAST.root);
+ // The new current child is the last sibling of the old root
+ currentAST.child = currentAST.root;
+ currentAST.advanceChildToEnd();
+ // Set the new root
+ currentAST.root = root;
+ }
+ }
+
+ public override AST create()
+ {
+ ASTNode newNode = (ASTNode) base.create();
+ newNode.File = filefinfo_;
+ return newNode;
+ }
+
+ public override AST create(int type)
+ {
+ ASTNode newNode = (ASTNode) base.create(type);
+ newNode.File = filefinfo_;
+ return newNode;
+ }
+
+ public override AST create(int type, string txt)
+ {
+ ASTNode newNode = (ASTNode) base.create(type, txt);
+ newNode.File = filefinfo_;
+ return newNode;
+ }
+
+ public override AST create(int type, string txt, string ASTNodeTypeName)
+ {
+ ASTNode newNode = (ASTNode) base.create(type, txt, ASTNodeTypeName);
+ newNode.File = filefinfo_;
+ return newNode;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CSharpTranslator/Translator/CSharpEnvBuilder.g b/CSharpTranslator/Translator/CSharpEnvBuilder.g
new file mode 100644
index 0000000..7430514
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpEnvBuilder.g
@@ -0,0 +1,1414 @@
+header
+{
+ using System.IO;
+ using System.Text;
+ using System.Collections;
+ using ASTFrame = antlr.debug.misc.ASTFrame;
+}
+
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// An AST Printer (or un-parser) that prints the source code that a tree represents.
+///
+///
+///
+///
+/// The default behaviour of this PrettyPrinter is to print out the AST and generate
+/// source code that is as close to the original as is possible.
+///
+///
+/// This behaviour can be overridden by supplying an
+/// object that contains the settings for a custom formatting code style.
+///
+///
+/// The TreeParser defined below is designed for the AST created by CSharpParser.
+/// See the file "CSharpParser.g" for the details of that Parser.
+///
+///
+///
+/// History
+///
+///
+///
+/// 05-Jun-2003 kunle Created file.
+///
+///
+///
+
+
+*/
+
+
+/* keving:
+**
+** Notes
+**
+*/
+class CSharpEnvBuilder extends TreeParser("RusticiSoftware.Translator.JavaTreeParser");
+
+options
+{
+ importVocab = CSharpJava;
+ ASTLabelType = "ASTNode";
+ defaultErrorHandler = true;
+}
+
+//=============================================================================
+// Start of CODE
+//=============================================================================
+
+{
+ private DirectoryHT appEnv = null;
+ private string nameSpace = "";
+
+
+ private bool NotExcluded(CodeMaskEnums codeMask, CodeMaskEnums construct)
+ {
+ return ((codeMask & construct) != 0 );
+ }
+
+
+}
+
+//=============================================================================
+// Start of RULES
+//=============================================================================
+
+
+// A C# compilation unit is a file containing a mixture of namespaces, classes,
+// instances, structs, etc. We do some jiggery pokery here to convert this to a list
+// of Java compilation units, each of which contains appropriate package names, imports,
+// and a single class / instance declaration. Each of these Java compilation units will be
+// written out to a separate java source file by the driver program.
+compilationUnit [SigEnv e, DirectoryHT envIn]
+ { appEnv = envIn;
+ usePath = new Stack();
+ usePath.Push(new ArrayList());
+ }
+ : #( COMPILATION_UNIT
+ justPreprocessorDirectives[e]
+ uses:usingDirectives[e]
+ globalAttributes[e]
+ cus:namespaceMemberDeclarations[e]
+ )
+ ;
+
+usingDirectives [SigEnv e]
+ : #( USING_DIRECTIVES
+ ( preprocessorDirective[e, CodeMaskEnums.UsingDirectives]
+ | usingDirective[e]
+ )*
+ )
+ ;
+
+usingDirective [SigEnv e]
+ : #( USING_NAMESPACE_DIRECTIVE
+ id:qualifiedIdentifier[e] { ((ArrayList)usePath.Peek()).Add(idToString(#id)); }
+ )
+ | #( USING_ALIAS_DIRECTIVE
+ alias:identifier[e]
+ aid:qualifiedIdentifier[e] { ((ArrayList)usePath.Peek()).Add(idToString(#alias) + "=" + idToString(#aid)); }
+ )
+ ;
+
+namespaceMemberDeclarations [SigEnv e]
+ { string saveNameSpace = nameSpace; }
+ : ( namespaceMemberDeclaration[e] { nameSpace = saveNameSpace; }
+ | preprocessorDirective[e, CodeMaskEnums.NamespaceMemberDeclarations] { nameSpace = saveNameSpace; }
+ )*
+ ;
+
+namespaceMemberDeclaration [SigEnv e]
+ : namespaceDeclaration[e]
+ | typeDeclaration[e]
+ ;
+
+typeDeclaration [SigEnv e]
+ : cla:classDeclaration[e]
+ | str:structDeclaration[e]
+ | iface:interfaceDeclaration[e]
+ | enm:enumDeclaration[e]
+ | delegateDeclaration[e]
+ ;
+
+namespaceDeclaration [SigEnv e]
+ : #( NAMESPACE
+ m_ns:qualifiedIdentifier[e] { nameSpace += idToString(#m_ns) + ".";
+ usePath.Push(new ArrayList());
+ ((ArrayList)usePath.Peek()).Add(idToString(#m_ns));
+ }
+ bdy:namespaceBody[e] { usePath.Pop(); }
+ )
+ ;
+
+namespaceBody [SigEnv e]
+ : #( NAMESPACE_BODY usingDirectives[e] namespaceMemberDeclarations[e] CLOSE_CURLY
+ )
+ ;
+
+classModifiers [SigEnv e]
+ : modifiers[e] // indirection for any special processing
+ ;
+
+modifiers [SigEnv e] // TODO: If there are no access modifiers then make it private (check)
+ : #( MODIFIERS ( modifier[e] )* )
+ ;
+
+modifier [SigEnv e]
+ : ( ABSTRACT
+ |/*nw:*/NEW
+ |/*ov:*/OVERRIDE
+ | PUBLIC
+ | PROTECTED
+ | INTERNAL
+ | PRIVATE
+ | SEALED
+ |/*st:*/STATIC
+ |/*vi:*/VIRTUAL
+ |/*ext:*/EXTERN
+ | READONLY
+ |/*un:*/UNSAFE
+ |/*vo:*/VOLATILE
+ )
+ ;
+
+
+typeName [SigEnv e]
+ : predefinedType[e]
+ | qualifiedIdentifier[e]
+ ;
+
+classTypeName [SigEnv e]
+ : qualifiedIdentifier[e]
+ | OBJECT
+ |/*str:*/STRING
+ ;
+
+identifier [SigEnv e]
+ : IDENTIFIER
+ ;
+
+qualifiedIdentifier [SigEnv e]
+ : ( identifier[e]
+ | #(DOT identifier[e] qualifiedIdentifier[e] )
+ )
+ ;
+
+
+//
+// A.2.2 Types
+//
+
+type [SigEnv e] returns [string t]
+ { string rs = ""; t = null; }
+ : #( TYPE
+ ( id:qualifiedIdentifier[e] { t = idToString(#id); }
+ | t = predefinedType[e]
+ | VOID { t = "System.Void"; }
+ )
+ pointerSpecifier[e]
+ rs = rankSpecifiers[e]
+ )
+ { t += rs; }
+ ;
+
+pointerSpecifier [SigEnv e]
+ : #( STARS
+ ( STAR
+ )*
+ )
+ ;
+
+classType [SigEnv e]
+ : qualifiedIdentifier[e]
+ | OBJECT
+ |/*str:*/STRING
+ ;
+
+interfaceType [SigEnv e]
+ : qualifiedIdentifier[e]
+ ;
+
+delegateType [SigEnv e]
+ : qualifiedIdentifier[e] // typeName
+ ;
+
+/*
+pointerType
+ : unmanagedType STAR
+ | VOID STAR
+ ;
+*/
+unmanagedType [SigEnv e]
+ : qualifiedIdentifier[e] // typeName
+ ;
+
+//
+// A.2.3 Variables
+//
+
+variableReference [SigEnv e]
+ : expression[e]
+ ;
+
+//
+// A.2.4 Expressions
+//
+
+argumentList [SigEnv e] // Simplify by making it an EXPR_LIST
+ : #( ARG_LIST ( argument[e] )+
+ )
+ ;
+
+argument [SigEnv e]
+ : expression[e]
+ | #(/*r:*/REF variableReference[e] )
+ | #(/*o:*/OUT variableReference[e] )
+ ;
+
+constantExpression [SigEnv e]
+ : expression[e]
+ ;
+
+booleanExpression [SigEnv e]
+ : expression[e]
+ ;
+
+expressionList [SigEnv e]
+ : #( EXPR_LIST ( expression[e] )+
+ )
+ ;
+
+expression [SigEnv e]
+ : #( EXPR expr[e] )
+ ;
+
+expr [SigEnv e]
+ // assignmentExpression
+ //
+ : #( ASSIGN expr[e] expr[e] )
+ | #( PLUS_ASSIGN expr[e] expr[e] )
+ | #( MINUS_ASSIGN expr[e] expr[e] )
+ | #( STAR_ASSIGN expr[e] expr[e] )
+ | #( DIV_ASSIGN expr[e] expr[e] )
+ | #( MOD_ASSIGN expr[e] expr[e] )
+ | #( BIN_AND_ASSIGN expr[e] expr[e] )
+ | #( BIN_OR_ASSIGN expr[e] expr[e] )
+ | #( BIN_XOR_ASSIGN expr[e] expr[e] )
+ | #( SHIFTL_ASSIGN expr[e] expr[e] )
+ | #( SHIFTR_ASSIGN expr[e] expr[e] )
+ // conditionalExpression
+ //
+ | #( QUESTION expr[e] expr[e] expr[e] )
+
+ // conditional-XXX-Expressions
+ //
+ | #( LOG_OR expr[e] expr[e] )
+ | #( LOG_AND expr[e] expr[e] )
+
+ // bitwise-XXX-Expressions
+ //
+ | #( BIN_OR expr[e] expr[e] )
+ | #( BIN_XOR expr[e] expr[e] )
+ | #( BIN_AND expr[e] expr[e] )
+
+ // equalityExpression
+ //
+ | #( EQUAL expr[e] expr[e] )
+ | #( NOT_EQUAL expr[e] expr[e] )
+
+ // relationalExpression
+ //
+ | #( LTHAN expr[e] expr[e] )
+ | #( GTHAN expr[e] expr[e] )
+ | #( LTE expr[e] expr[e] )
+ | #( GTE expr[e] expr[e] )
+ | #( IS expr[e] type[e] )
+ | #( AS expr[e] type[e] )
+
+ // shiftExpression
+ //
+ | #( SHIFTL expr[e] expr[e] )
+ | #( SHIFTR expr[e] expr[e] )
+
+ // additiveExpression
+ //
+ | #( PLUS expr[e] expr[e] )
+ | #( MINUS expr[e] expr[e] )
+ // multiplicativeExpression
+ //
+ | #( STAR expr[e] expr[e] )
+ | #( DIV expr[e] expr[e] )
+ | #( MOD expr[e] expr[e] )
+ | unaryExpression[e]
+ ;
+
+unaryExpression [SigEnv e]
+ : #( CAST_EXPR type[e] expr[e] )
+ | #( INC expr[e] )
+ | #( DEC expr[e] )
+ | #( UNARY_PLUS expr[e] )
+ | #( UNARY_MINUS expr[e] )
+ | #( LOG_NOT expr[e] )
+ | #( BIN_NOT expr[e] )
+ | #(/*p:*/PTR_INDIRECTION_EXPR expr[e] )
+ | #(/*a:*/ADDRESS_OF_EXPR expr[e] )
+ | primaryExpression[e]
+ ;
+
+primaryExpression [SigEnv e]
+ : #( // invocationExpression ::= primaryExpression OPEN_PAREN ( argumentList )? CLOSE_PAREN
+ INVOCATION_EXPR primaryExpression[e]
+ (a:argumentList[e])?
+ )
+ | #( // elementAccess ::= primaryNoArrayCreationExpression OPEN_BRACK expressionList CLOSE_BRACK
+ /*e:*/ELEMENT_ACCESS_EXPR primaryExpression[e]
+ expressionList[e]
+ )
+ | #( // pointerElementAccess ::= primaryNoArrayCreationExpression OPEN_BRACK expression CLOSE_BRACK
+ /*p:*/PTR_ELEMENT_ACCESS_EXPR primaryExpression[e]
+ expressionList[e]
+ )
+ | #( // memberAccess ::= primaryExpression DOT identifier
+ MEMBER_ACCESS_EXPR
+ ( type[e]
+ | primaryExpression[e]
+ )
+ identifier[e]
+ )
+ | // pointerMemberAccess
+ #(/*d:*/DEREF primaryExpression[e] identifier[e] )
+ | // postIncrementExpression
+ #( POST_INC_EXPR primaryExpression[e] )
+ | // postDecrementExpression
+ #( POST_DEC_EXPR primaryExpression[e] )
+ | basicPrimaryExpression[e]
+ ;
+
+basicPrimaryExpression [SigEnv e]
+ : literal[e]
+ | identifier[e] // simpleName
+ | // parenthesizedExpression
+ //
+ #( PAREN_EXPR expr[e] )
+ | THIS
+ | #( BASE
+ ( i:identifier[e]
+ | expressionList[e] // TODO:access to base class indexer ...
+ )
+ )
+ | newExpression[e]
+ | // typeofExpression
+ //
+ #( TYPEOF type[e] )
+ | #(/*s:*/SIZEOF unmanagedType[e] )
+ | #(/*c:*/CHECKED ce:expression[e] )
+ | #(/*u:*/UNCHECKED ue:expression[e] )
+ ;
+
+newExpression [SigEnv e]
+ // objectCreationExpression
+ //
+ : #(OBJ_CREATE_EXPR type[e] (argumentList[e])? )
+ // delegateCreationExpression
+ //
+ | #(/*dl:*/DLG_CREATE_EXPR type[e] argumentList[e] )
+ // arrayCreationExpression
+ //
+ | #( ARRAY_CREATE_EXPR
+ type[e] // nonArrayType ( rankSpecifiers )?
+ ( arrayInitializer[e]
+ | expressionList[e]
+ rankSpecifiers[e] ( arrayInitializer[e] )?
+ )
+ )
+ ;
+
+literal [SigEnv e]
+ : TRUE
+ | FALSE
+ | INT_LITERAL
+ | UINT_LITERAL
+ | LONG_LITERAL
+ | ULONG_LITERAL
+ | DECIMAL_LITERAL
+ | FLOAT_LITERAL
+ | DOUBLE_LITERAL
+ | CHAR_LITERAL
+ | STRING_LITERAL
+ | NULL
+ ;
+
+predefinedType [SigEnv e] returns [string t]
+ { t = null; }
+ : BOOL { t = "System.Boolean"; }
+ | BYTE { t = "System.Byte"; }
+ | CHAR { t = "System.Char"; }
+ | DECIMAL { t = "System.Decimal"; }
+ | DOUBLE { t = "System.Double"; }
+ | FLOAT { t = "System.Single"; }
+ | INT { t = "System.Int32"; }
+ | LONG { t = "System.Int64"; }
+ | OBJECT { t = "System.Object"; }
+ | SBYTE { t = "System.SByte"; }
+ | SHORT { t = "System.Int16"; }
+ | STRING { t = "System.String"; }
+ | UINT { t = "System.UInt32"; }
+ | ULONG { t = "System.UInt64"; }
+ | USHORT { t = "System.UInt16"; }
+ ;
+
+
+//
+// A.2.5 Statements
+//
+
+statement [SigEnv e]
+ : #(LABEL_STMT identifier[e] statement[e]
+ )
+ | localVariableDeclaration[e]
+ | localConstantDeclaration[e]
+ | embeddedStatement[e]
+ | preprocessorDirective[e, CodeMaskEnums.Statements]
+ ;
+
+embeddedStatement [SigEnv e]
+ : block[e]
+ |/*emp:*/EMPTY_STMT
+ | #(/*sxp:*/EXPR_STMT statementExpression[e] )
+ | #(IF
+ expression[e] embeddedStatement[e]
+ ( #(ELSE
+ embeddedStatement[e]
+ )
+ )?
+ )
+ |
+ #( SWITCH
+ se:expression[e]
+ #( OPEN_CURLY
+ ( ss:switchSection[e] )*
+ CLOSE_CURLY
+ )
+ )
+ | #( FOR
+ #( FOR_INIT ( ( localVariableDeclaration[e] | ( statementExpression[e] )+ ) )? )
+
+ #( FOR_COND ( booleanExpression[e] )? )
+
+ #( FOR_ITER ( ( statementExpression[e] )+ )? )
+
+ embeddedStatement[e]
+ )
+ | #(/*whileStmt:*/WHILE
+ booleanExpression[e] embeddedStatement[e]
+ )
+ | #(/*doStmt:*/DO
+ embeddedStatement[e] booleanExpression[e]
+ )
+ | #(/*foreachStmt:*/FOREACH
+ localVariableDeclaration[e] expression[e]
+
+ embeddedStatement[e]
+ )
+ |/*brk:*/BREAK
+ |/*ctn:*/CONTINUE
+ | #(/*gto:*/GOTO
+ ( identifier[e]
+ |/*cse:*/CASE constantExpression[e]
+ |/*dfl:*/DEFAULT
+ )
+
+ )
+ | #(/*rtn:*/RETURN ( expression[e] )? )
+ | #(/*trw:*/THROW ( expression[e] )? )
+ | tryStatement[e]
+ | #(/*checkedStmt:*/CHECKED block[e]
+ )
+ | #(/**/UNCHECKED block[e]
+ )
+ | #(/*lockStmt:*/LOCK
+ expression[e] embeddedStatement[e]
+ )
+ | #(/*usingStmt:*/USING
+ resourceAcquisition[e] embeddedStatement[e]
+ )
+ | #(/*unsafeStmt:*/UNSAFE
+ block[e]
+ )
+ | // fixedStatement
+ #(/*fixedStmt:*/FIXED
+ type[e]
+ fixedPointerDeclarator[e] ( fixedPointerDeclarator[e] )*
+
+ embeddedStatement[e]
+ )
+ ;
+
+body [SigEnv e]
+ : block[e]
+ | EMPTY_STMT
+ ;
+
+block [SigEnv e]
+ : #(BLOCK
+ ( statement[e] )*
+ CLOSE_CURLY
+ )
+ ;
+
+statementList[SigEnv e]
+ : #( STMT_LIST ( statement[e] )+ )
+ ;
+
+localVariableDeclaration [SigEnv e]
+ : #( LOCVAR_DECLS t:type[e]
+ (d:localVariableDeclarator[e] )+
+ )
+ ;
+
+localVariableDeclarator [SigEnv e]
+ : #( VAR_DECLARATOR identifier[e] (localVariableInit[e])?
+ )
+ ;
+
+localVariableInit [SigEnv e]
+ :
+ #( LOCVAR_INIT
+ ( expression[e]
+ | arrayInitializer[e]
+ )
+ )
+ ;
+
+
+localConstantDeclaration [SigEnv e]
+ : #(LOCAL_CONST t:type[e]
+ ( d:constantDeclarator[e] )+
+ )
+ ;
+
+constantDeclarator [SigEnv e] returns [string i]
+ { i = ""; }
+ : #(CONST_DECLARATOR id:identifier[e] { i = idToString(#id); } constantExpression[e] )
+ ;
+
+statementExpression [SigEnv e]
+ : expr[e]
+ ;
+
+switchSection[SigEnv e]
+ : #( SWITCH_SECTION switchLabels[e] statementList[e] )
+ ;
+
+switchLabels [SigEnv e]
+ : #( SWITCH_LABELS
+ ( ( #(CASE expression[e] )
+ | DEFAULT
+ )
+
+ )+
+ )
+ ;
+
+tryStatement [SigEnv e]
+ : #( TRY
+ block[e]
+ ( finallyClause[e]
+ | catchClauses[e] ( finallyClause[e] )?
+ )
+ )
+ ;
+
+catchClauses [SigEnv e]
+ : (
+ catchClause[e]
+ )+
+ ;
+
+catchClause [SigEnv e]
+ : #( CATCH b:block[e]
+ ( t:type[e]
+ | l:localVariableDeclaration[e]
+ )*
+ )
+ ;
+
+finallyClause [SigEnv e]
+ : #( FINALLY
+ block[e]
+ )
+ ;
+
+resourceAcquisition[SigEnv e]
+ : localVariableDeclaration[e]
+ | expression[e]
+ ;
+
+//
+// A.2.6 Classes
+//
+
+classDeclaration [SigEnv e]
+ { string[] ts = null;
+ ClassRepTemplate cla = null;
+ SigEnv env = new SigEnv();
+ string saveNameSpace = nameSpace;
+ }
+ : #( CLASS
+ attributes[e]
+ mod:classModifiers[e]
+ id:identifier[e]
+ ts = classBase[e]
+ { usePath.Push(new ArrayList());
+ ((ArrayList)usePath.Peek()).Add(nameSpace + idToString(#id));
+ nameSpace += idToString(#id) + "."; }
+ #(TYPE_BODY classMemberDeclarations[env] CLOSE_CURLY )
+ {
+ nameSpace = saveNameSpace;
+ cla = new ClassRepTemplate(nameSpace + #id.getText(), CollectUsePath(), ts,
+ (ConstructorRepTemplate[]) env.Constructors.ToArray(typeof(ConstructorRepTemplate)),
+ (MethodRepTemplate[]) env.Methods.ToArray(typeof(MethodRepTemplate)),
+ (PropRepTemplate[]) env.Properties.ToArray(typeof(PropRepTemplate)),
+ (FieldRepTemplate[]) env.Fields.ToArray(typeof(FieldRepTemplate)),
+ (CastRepTemplate[]) env.Casts.ToArray(typeof(CastRepTemplate)),
+ new string[0], null
+ );
+ appEnv[nameSpace + #id.getText()] = cla;
+ usePath.Pop();
+ }
+ )
+ ;
+
+classBase [SigEnv e] returns [string[] ts]
+ { ArrayList tempBs = new ArrayList();
+ string t = "";
+ ts = null;
+ }
+ : #( CLASS_BASE ( t=type[e] { tempBs.Add(t); } )* )
+ { ts = (string[]) tempBs.ToArray(typeof(string)); }
+ ;
+
+classMemberDeclarations [SigEnv e]
+ : #( MEMBER_LIST
+ ( classMemberDeclaration [e]
+ | preprocessorDirective[e, CodeMaskEnums.ClassMemberDeclarations]
+ )*
+ )
+ ;
+
+classMemberDeclaration [SigEnv e]
+ : ( destructorDeclaration[e]
+ | typeMemberDeclaration[e]
+ )
+ ;
+
+typeMemberDeclaration [SigEnv e]
+ : ( constantDeclaration[e]
+ | eventDeclaration[e]
+ | constructorDeclaration[e]
+ | staticConstructorDeclaration[e]
+ | propertyDeclaration[e]
+ | methodDeclaration[e]
+ | indexerDeclaration[e]
+ | fieldDeclaration[e]
+ | operatorDeclaration[e]
+ | typeDeclaration[e]
+ )
+ ;
+
+constantDeclaration [SigEnv e]
+ { string t; string i; }
+ : #( CONST attributes[e] m:modifiers[e] t = type[e] ( i = constantDeclarator[e] { e.Fields.Add(new FieldRepTemplate(t,i)); } )+ )
+ ;
+
+fieldDeclaration [SigEnv e]
+ { string t; string i; }
+ : #( FIELD_DECL attributes[e] modifiers[e] t = type[e]
+ ( i = variableDeclarator[e] { e.Fields.Add(new FieldRepTemplate(t,i)); } )+
+
+ )
+ ;
+
+variableDeclarator [SigEnv e] returns [string i]
+ { i = ""; }
+ : #( VAR_DECLARATOR id:identifier[e] { i = idToString(#id); }
+ ( variableInitializer[e] )?
+ )
+ ;
+
+variableInitializer [SigEnv e]
+ : #( VAR_INIT
+ ( expression[e]
+ | arrayInitializer[e]
+ | stackallocInitializer[e]
+ )
+ )
+ ;
+
+methodDeclaration [SigEnv e]
+ { string i = "";
+ string rt = "";
+ ParamRepTemplate[] pts = new ParamRepTemplate[0];
+ }
+ : #( METHOD_DECL a:attributes[e] m:modifiers[e] rt = type[e] id:qualifiedIdentifier[e] { i = idToString(#id); }
+ b:methodBody[e]
+ ( pts = formalParameterList[e] )?
+ ) { if (i == "ToString" && pts.Length == 0)
+ i = "toString";
+ e.Methods.Add(new MethodRepTemplate(rt,i,pts)); }
+ ;
+
+memberName [SigEnv e]
+ : qualifiedIdentifier[e] // interfaceType^ DOT identifier
+// | identifier
+ ;
+
+methodBody [SigEnv e]
+ : body[e]
+ ;
+
+formalParameterList [SigEnv e] returns [ParamRepTemplate[] ps]
+ { ArrayList atys = new ArrayList();
+ ArrayList ftys = new ArrayList();
+ ParamRepTemplate pt = null;
+ ps = new ParamRepTemplate[0];
+ }
+ : #( FORMAL_PARAMETER_LIST
+ ( ftys = fixedParameters[e] { atys = ftys; } ( pt = parameterArray[e] { atys.Add(pt); } )?
+ | pt = parameterArray[e] { atys.Add(pt); }
+ ) { ps = (ParamRepTemplate[]) atys.ToArray(typeof(ParamRepTemplate)); }
+ )
+ ;
+
+fixedParameters [SigEnv e] returns [ArrayList ps]
+ { ps = new ArrayList();
+ ParamRepTemplate p = null;
+ }
+ : ( p=fixedParameter[e] { ps.Add(p); } )+
+ ;
+
+fixedParameter [SigEnv e] returns [ParamRepTemplate p]
+ { string t = "";
+ string i = "";
+ p = null;
+ }
+ : #( PARAMETER_FIXED attributes[e]
+ t = type[e] id:identifier[e] { i = idToString(#id); }
+ ( parameterModifier[e] )?
+ ) { p = new ParamRepTemplate(t,i); }
+ ;
+
+parameterModifier [SigEnv e]
+ : REF
+ | OUT
+ ;
+
+parameterArray [SigEnv e] returns [ParamRepTemplate p]
+ { string t = "";
+ string i = "";
+ p = null;
+ }
+ : #(PARAMS attributes[e] t = type[e] id:identifier[e] { i = idToString(#id); }
+ ) { p = new ParamRepTemplate(t + "[]",i); }
+ ;
+
+propertyDeclaration [SigEnv e]
+ { string t; }
+ : #( PROPERTY_DECL attributes[e] m:modifiers[e] t = type[e] id:qualifiedIdentifier[e]
+ a:accessorDeclarations[e] CLOSE_CURLY
+ )
+ { e.Properties.Add(new PropRepTemplate(t, #id.getText())); }
+ ;
+
+accessorDeclarations [SigEnv e]
+ : ( accessorDeclaration[e]
+ )*
+ ;
+
+accessorDeclaration [SigEnv e]
+ : #( "get" attributes[e] accessorBody[e] )
+ | #( "set" attributes[e] accessorBody[e] )
+ ;
+
+
+accessorBody [SigEnv e]
+ : block[e]
+ | EMPTY_STMT
+ ;
+
+eventDeclaration [SigEnv e]
+ : #(/*evt:*/EVENT attributes[e] modifiers[e] type[e]
+ ( qualifiedIdentifier[e]
+ eventAccessorDeclarations[e]/*cly:*/CLOSE_CURLY
+ | variableDeclarator[e] ( variableDeclarator[e] )*
+
+ )
+ )
+ ;
+
+eventAccessorDeclarations [SigEnv e]
+ : addAccessorDeclaration[e] removeAccessorDeclaration[e]
+ | removeAccessorDeclaration[e] addAccessorDeclaration[e]
+ ;
+
+addAccessorDeclaration [SigEnv e]
+ : #( "add" attributes[e] block[e] )
+ ;
+
+removeAccessorDeclaration [SigEnv e]
+ : #( "remove" attributes[e] block[e] )
+ ;
+
+indexerDeclaration [SigEnv e]
+ : #( INDEXER_DECL attributes[e] modifiers[e]
+ type[e] ( interfaceType[e] )?/*t:*/THIS
+ formalParameterList[e] accessorDeclarations[e]
+ /*cly:*/CLOSE_CURLY
+ )
+ ;
+
+operatorDeclaration [SigEnv e]
+ { string t = "";
+ ParamRepTemplate[] ps = null;
+ }
+ : ( #( UNARY_OP_DECL attributes[e] modifiers[e]
+ type[e] overloadableUnaryOperator[e]
+ formalParameterList[e]
+ operatorBody[e]
+ )
+ | #( BINARY_OP_DECL attributes[e] modifiers[e]
+ type[e] overloadableBinaryOperator[e]
+ formalParameterList[e]
+ operatorBody[e]
+ )
+ | #( CONV_OP_DECL attributes[e] modifiers[e]
+ (IMPLICIT | EXPLICIT) t=type[e]
+ ps=formalParameterList[e]
+ operatorBody[e]
+ ) {
+ e.Casts.Add(new CastRepTemplate(ps[0].Type, t));
+ }
+ )
+ ;
+
+overloadableUnaryOperator [SigEnv e]
+ : UNARY_PLUS
+ | UNARY_MINUS
+ | LOG_NOT
+ | BIN_NOT
+ | INC
+ | DEC
+ | TRUE
+ | FALSE
+ ;
+
+overloadableBinaryOperator [SigEnv e]
+ :/*pl:*/PLUS
+ |/*ms:*/MINUS
+ |/*st:*/STAR
+ |/*dv:*/DIV
+ |/*md:*/MOD
+ |/*ba:*/BIN_AND
+ |/*bo:*/BIN_OR
+ |/*bx:*/BIN_XOR
+ |/*sl:*/SHIFTL
+ |/*sr:*/SHIFTR
+ |/*eq:*/EQUAL
+ |/*nq:*/NOT_EQUAL
+ |/*gt:*/GTHAN
+ |/*lt:*/LTHAN
+ |/*ge:*/GTE
+ |/*le:*/LTE
+ ;
+
+operatorBody [SigEnv e]
+ : body[e]
+ ;
+
+constructorDeclaration [SigEnv e]
+ { ParamRepTemplate[] pts = new ParamRepTemplate[0]; }
+ : #( CTOR_DECL attributes[e] modifiers[e] identifier[e]
+ constructorBody[e]
+ ( pts = formalParameterList[e] )?
+ ( c:constructorInitializer[e] )?
+ ) { e.Constructors.Add(new ConstructorRepTemplate(pts)); }
+ ;
+
+constructorInitializer [SigEnv e]
+ : ( #( BASE ( argumentList[e] )? )
+ | #( THIS ( argumentList[e] )? )
+ )
+ ;
+
+constructorBody [SigEnv e]
+ : body[e]
+ ;
+
+staticConstructorDeclaration [SigEnv e]
+ : #( STATIC_CTOR_DECL attributes[e] modifiers[e] identifier[e]
+ staticConstructorBody[e]
+ )
+ ;
+
+staticConstructorBody [SigEnv e]
+ : body[e]
+ ;
+
+destructorDeclaration [SigEnv e]
+ : #( DTOR_DECL attributes[e] modifiers[e] identifier[e]
+ destructorBody[e]
+ )
+ ;
+
+destructorBody [SigEnv e]
+ : body[e]
+ ;
+
+
+//
+// A.2.7 Structs
+//
+
+
+// Convert to a class
+structDeclaration [SigEnv e]
+ { string[] ts = null;
+ StructRepTemplate str = null;
+ SigEnv env = new SigEnv();
+ string saveNameSpace = nameSpace;
+ } : #( STRUCT
+ attributes[e]
+ mod:modifiers[e]
+ id:identifier[e]
+ ts = structImplements[e]
+ { usePath.Push(new ArrayList());
+ ((ArrayList)usePath.Peek()).Add(nameSpace + idToString(#id));
+ nameSpace += idToString(#id) + "."; }
+ #( TYPE_BODY mem:structMemberDeclarations[env] CLOSE_CURLY )
+ {
+ nameSpace = saveNameSpace;
+ str = new StructRepTemplate(nameSpace + #id.getText(), CollectUsePath(), ts,
+ (ConstructorRepTemplate[]) env.Constructors.ToArray(typeof(ConstructorRepTemplate)),
+ (MethodRepTemplate[]) env.Methods.ToArray(typeof(MethodRepTemplate)),
+ (PropRepTemplate[]) env.Properties.ToArray(typeof(PropRepTemplate)),
+ (FieldRepTemplate[]) env.Fields.ToArray(typeof(FieldRepTemplate)),
+ (CastRepTemplate[]) env.Casts.ToArray(typeof(CastRepTemplate)),
+ new string[0], null
+ );
+ appEnv[nameSpace + #id.getText()] = str;
+ usePath.Pop();
+ }
+ )
+ ;
+
+structImplements [SigEnv e] returns [string[] ts]
+ { ArrayList tempIs = new ArrayList();
+ String t;
+ ts = null;
+ }
+ : #( STRUCT_BASE ( t=type[e] { tempIs.Add(t); } )* )
+ { ts = (string[]) tempIs.ToArray(typeof(string)); }
+ ;
+
+structMemberDeclarations [SigEnv e]
+ // Add Default Constructor
+ : #( MEMBER_LIST
+ ( s:structMemberDeclaration[e]
+ | p:preprocessorDirective[e, CodeMaskEnums.StructMemberDeclarations]
+ )*
+ )
+ ;
+
+structMemberDeclaration [SigEnv e]
+ : typeMemberDeclaration[e]
+ ;
+
+
+//
+// A.2.8 Arrays
+//
+
+rankSpecifiers [SigEnv e] returns [string rs]
+ { string r = ""; rs = ""; }
+ : #( ARRAY_RANKS
+ ( r = rankSpecifier[e] { rs += r; }
+ )*
+ )
+ ;
+
+rankSpecifier [SigEnv e] returns [string r]
+ { r = "["; }
+ : #( ARRAY_RANK
+ (COMMA { r += ","; }
+ )*
+ ) { r += "]"; }
+ ;
+
+arrayInitializer [SigEnv e]
+ : #( ARRAY_INIT ( variableInitializerList[e] )? CLOSE_CURLY )
+ ;
+
+variableInitializerList [SigEnv e]
+ : #( VAR_INIT_LIST v:arrayvariableInitializer[e] ( arrayvariableInitializer[e] )* )
+ ;
+
+arrayvariableInitializer [SigEnv e]
+ : v:variableInitializer[e]
+ ;
+
+//
+// A.2.9 Interfaces
+//
+
+interfaceDeclaration [SigEnv e]
+ { string[] ts = null;
+ InterfaceRepTemplate inter = null;
+ SigEnv env = new SigEnv();
+ string saveNameSpace = nameSpace;
+ } : #(INTERFACE attributes[e] mod:modifiers[e] id:identifier[e]
+ ts = interfaceImplements[e]
+ { usePath.Push(new ArrayList());
+ ((ArrayList)usePath.Peek()).Add(nameSpace + idToString(#id));
+ nameSpace += idToString(#id) + "."; }
+ #( TYPE_BODY mem:interfaceMemberDeclarations[env] CLOSE_CURLY )
+ {
+ nameSpace = saveNameSpace;
+ inter = new InterfaceRepTemplate(nameSpace + #id.getText(), CollectUsePath(), ts,
+ (MethodRepTemplate[]) env.Methods.ToArray(typeof(MethodRepTemplate)),
+ (PropRepTemplate[]) env.Properties.ToArray(typeof(PropRepTemplate)),
+ (FieldRepTemplate[]) env.Fields.ToArray(typeof(FieldRepTemplate)),
+ (CastRepTemplate[]) env.Casts.ToArray(typeof(CastRepTemplate)),
+ new string[0], null
+ );
+ appEnv[nameSpace + #id.getText()] = inter;
+ usePath.Pop();
+ }
+
+ )
+ ;
+
+interfaceImplements [SigEnv e] returns [string[] ts]
+ { ArrayList tempBs = new ArrayList();
+ string t = "";
+ ts = null;
+ }
+ : #( INTERFACE_BASE ( t=type[e] { tempBs.Add(t); } )* )
+ { ts = (string[]) tempBs.ToArray(typeof(string)); }
+ ;
+
+interfaceMemberDeclarations [SigEnv e]
+ : #( MEMBER_LIST
+ ( interfaceMemberDeclaration[e]
+ | preprocessorDirective[e, CodeMaskEnums.InterfaceMemberDeclarations]
+ )*
+ )
+ ;
+
+interfaceMemberDeclaration [SigEnv e]
+ : ( methodDeclaration[e]
+ | propertyDeclaration[e]
+ | eventDeclaration[e]
+ | indexerDeclaration[e]
+ )
+ ;
+
+interfaceMethodDeclaration [SigEnv e]
+ : #( METHOD_DECL attributes[e] modifiers[e] type[e] qualifiedIdentifier[e]
+ EMPTY_STMT
+ ( f:formalParameterList[e] )?
+ )
+ ;
+
+interfacePropertyDeclaration [SigEnv e]
+ : #( PROPERTY_DECL attributes[e] modifiers[e] type[e] identifier[e]
+ accessorDeclarations[e]/*cc:*/CLOSE_CURLY
+ )
+ ;
+
+interfaceEventDeclaration [SigEnv e]
+ : #(/*evt:*/EVENT attributes[e] modifiers[e]
+ type[e] variableDeclarator[e]
+ )
+ ;
+
+interfaceIndexerDeclaration [SigEnv e]
+ : #( INDEXER_DECL attributes[e] modifiers[e] type[e]/*t:*/THIS
+ formalParameterList[e]
+ accessorDeclarations[e]/*cc:*/CLOSE_CURLY
+ )
+ ;
+
+
+//
+// A.2.10 Enums
+//
+
+enumDeclaration [SigEnv e]
+ { string t = null;
+ EnumRepTemplate cla = null;
+ SigEnv env = new SigEnv();
+ } : #( ENUM attributes[e] mod:modifiers[e] id:identifier[e]
+ t=enumImplements[e]
+ #( TYPE_BODY
+ mem:enumMemberDeclarations[env, nameSpace + #id.getText()]
+ CLOSE_CURLY
+ )
+ {
+ cla = new EnumRepTemplate(nameSpace + #id.getText(), CollectUsePath(), new string[] {"System.Enum"},
+ (MethodRepTemplate[]) env.Methods.ToArray(typeof(MethodRepTemplate)),
+ (PropRepTemplate[]) env.Properties.ToArray(typeof(PropRepTemplate)),
+ (FieldRepTemplate[]) env.Fields.ToArray(typeof(FieldRepTemplate)),
+ (CastRepTemplate[]) env.Casts.ToArray(typeof(CastRepTemplate)),
+ new string[0],
+ null
+ );
+ appEnv[nameSpace + #id.getText()] = cla;
+ }
+ )
+ ;
+
+enumImplements [SigEnv e] returns [string t]
+ { t = null; }
+ : #( ENUM_BASE ( t=type[e] )? { // By default an enum maps to an int
+ if (t == null) t = "int";
+ }
+ )
+ ;
+
+enumMemberDeclarations [SigEnv e, string t]
+ : #( MEMBER_LIST
+ ( enumMemberDeclaration[e, t] )*
+ )
+ ;
+
+enumMemberDeclaration [SigEnv e, string t]
+ : #( id:IDENTIFIER { e.Fields.Add(new FieldRepTemplate(t, #id.getText())); } attributes[e]
+ ( c:constantExpression[e] )?
+ )
+ ;
+
+
+//
+// A.2.11 Delegates
+//
+
+delegateDeclaration [SigEnv e]
+ : #(/*dlg:*/DELEGATE attributes[e] modifiers[e]
+ type[e] identifier[e] ( f:formalParameterList[e] )?
+ )
+ ;
+
+
+//
+// A.2.12 Attributes
+//
+
+globalAttributes [SigEnv e]
+ : #( GLOBAL_ATTRIBUTE_SECTIONS
+ ( globalAttributeSection[e]
+ | preprocessorDirective[e, CodeMaskEnums.GlobalAttributes]
+ )*
+ )
+ ;
+
+globalAttributeSection [SigEnv e]
+ : #(/*sect:*/GLOBAL_ATTRIBUTE_SECTION
+ ( attribute[e] )+
+ )
+ ;
+
+attributes [SigEnv e]
+ : #( ATTRIBUTE_SECTIONS
+ ( attributeSection[e]
+ | preprocessorDirective[e, CodeMaskEnums.Attributes]
+ )*
+ )
+ ;
+
+attributeSection [SigEnv e]
+ : #(/*sect:*/ATTRIBUTE_SECTION ( attributeTarget[e] )?
+ ( attribute[e] )+
+ )
+ ;
+
+attributeTarget[SigEnv e]
+ : (/*fv:*/"field"
+ |/*ev:*/EVENT
+ |/*mv:*/"method"
+ |/*mo:*/"module"
+ |/*pa:*/"param"
+ |/*pr:*/"property"
+ |/*re:*/RETURN
+ |/*ty:*/"type"
+ )
+ ;
+
+attribute [SigEnv e]
+ : #( ATTRIBUTE typeName[e] attributeArguments[e] )
+ ;
+
+attributeArguments [SigEnv e]
+ : ( positionalArgumentList[e] )? ( namedArgumentList[e] )?
+ ;
+
+positionalArgumentList [SigEnv e]
+ : #( POSITIONAL_ARGLIST positionalArgument[e]
+ ( positionalArgument[e] )*
+ )
+ ;
+
+positionalArgument [SigEnv e]
+ : #( POSITIONAL_ARG attributeArgumentExpression[e] )
+ ;
+
+namedArgumentList [SigEnv e]
+ : #( NAMED_ARGLIST namedArgument[e]
+ ( namedArgument[e] )*
+ )
+ ;
+
+namedArgument [SigEnv e]
+ : #( NAMED_ARG identifier[e] attributeArgumentExpression[e] )
+ ;
+
+attributeArgumentExpression [SigEnv e]
+ : #( ATTRIB_ARGUMENT_EXPR expression[e] )
+ ;
+
+//
+// A.3 Grammar extensions for unsafe code
+//
+
+fixedPointerDeclarator [SigEnv e]
+ : #( PTR_DECLARATOR identifier[e] fixedPointerInitializer[e] )
+ ;
+
+fixedPointerInitializer [SigEnv e]
+ : #( PTR_INIT
+ (/*b:*/BIN_AND variableReference[e]
+ | expression[e]
+ )
+ )
+ ;
+
+stackallocInitializer [SigEnv e]
+ : #(/*s:*/STACKALLOC unmanagedType[e] expression[e] )
+ ;
+
+//======================================
+// Preprocessor Directives
+//======================================
+
+justPreprocessorDirectives [SigEnv e]
+ : #( PP_DIRECTIVES
+ ( preprocessorDirective[e, CodeMaskEnums.PreprocessorDirectivesOnly]
+ )*
+ )
+ ;
+
+preprocessorDirective [SigEnv e, CodeMaskEnums codeMask]
+ : #(PP_DEFINE PP_IDENT )
+ | #(/*u1:*/PP_UNDEFINE /*u2:*/PP_IDENT )
+ | #(/*l1:*/PP_LINE
+ (/*l2:*/DEFAULT
+ |/*l3:*/PP_NUMBER (/*l4:*/PP_FILENAME )?
+ )
+ )
+ | #(/*e1:*/PP_ERROR ppMessage[e] )
+ | #(/*w1:*/PP_WARNING ppMessage[e] )
+ | regionDirective[e, codeMask]
+ | conditionalDirective[e, codeMask]
+ ;
+
+regionDirective [SigEnv e, CodeMaskEnums codeMask]
+ : #(PP_REGION ppMessage[e] b:directiveBlock[e, codeMask]
+ #(PP_ENDREGION ppMessage[e] )
+ )
+ ;
+
+conditionalDirective [SigEnv e, CodeMaskEnums codeMask] // Assume condition is true for now ...
+ : #(PP_COND_IF preprocessExpression[e] th:directiveBlock[e, codeMask]
+ ( #(PP_COND_ELIF preprocessExpression[e] directiveBlock[e, codeMask] ) )*
+ ( #(PP_COND_ELSE directiveBlock[e, codeMask] ) )?
+ PP_COND_ENDIF
+ )
+ ;
+
+directiveBlock [SigEnv e, CodeMaskEnums codeMask]
+ : #( PP_BLOCK
+ ( { NotExcluded(codeMask, CodeMaskEnums.UsingDirectives) }? usingDirective[e]
+ | { NotExcluded(codeMask, CodeMaskEnums.GlobalAttributes) }? globalAttributeSection[e]
+ | { NotExcluded(codeMask, CodeMaskEnums.Attributes) }? attributeSection[e]
+ | { NotExcluded(codeMask, CodeMaskEnums.NamespaceMemberDeclarations) }? namespaceMemberDeclaration[e]
+ | { NotExcluded(codeMask, CodeMaskEnums.ClassMemberDeclarations) }? classMemberDeclaration[e]
+ | { NotExcluded(codeMask, CodeMaskEnums.StructMemberDeclarations) }? structMemberDeclaration[e]
+ | { NotExcluded(codeMask, CodeMaskEnums.InterfaceMemberDeclarations) }? interfaceMemberDeclaration[e]
+ | { NotExcluded(codeMask, CodeMaskEnums.Statements) }? statement[e]
+ | preprocessorDirective[e, codeMask]
+ )*
+ )
+ ;
+
+ppMessage [SigEnv e]
+ : #( PP_MESSAGE
+ (/*m1:*/PP_IDENT
+ |/*m2:*/PP_STRING
+ | /*m3:*/PP_FILENAME
+ | /*m4:*/PP_NUMBER
+ )*
+ )
+ ;
+
+preprocessExpression [SigEnv e]
+ : #( PP_EXPR preprocessExpr[e] )
+ ;
+
+preprocessExpr [SigEnv e]
+ : #(/*o:*/LOG_OR preprocessExpr[e] preprocessExpr[e] )
+ | #(/*a:*/LOG_AND preprocessExpr[e] preprocessExpr[e] )
+ | #(/*e:*/EQUAL preprocessExpr[e] preprocessExpr[e] )
+ | #(/*n:*/NOT_EQUAL preprocessExpr[e] preprocessExpr[e] )
+ | preprocessPrimaryExpression[e]
+ ;
+
+preprocessPrimaryExpression [SigEnv e]
+ :/*i:*/PP_IDENT
+ |/*tr:*/TRUE
+ |/*fa:*/FALSE
+ | #(/*l:*/LOG_NOT preprocessPrimaryExpression[e] )
+ | #(/*p:*/PAREN_EXPR preprocessExpr[e] )
+ ;
diff --git a/CSharpTranslator/Translator/CSharpLexer.g b/CSharpTranslator/Translator/CSharpLexer.g
new file mode 100644
index 0000000..559af7a
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpLexer.g
@@ -0,0 +1,622 @@
+header
+{
+ using System.IO;
+ using System.Globalization;
+
+ using TokenStreamSelector = antlr.TokenStreamSelector;
+}
+
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// A Lexer for the C# language including preprocessors directives.
+///
+///
+///
+///
+/// The Lexer defined below is based on the "C# Language Specification" as
+/// documented in the ECMA-334 standard dated December 2001.
+///
+///
+///
+/// The Lexer depends on the existence of two companion lexers to which it will
+/// delegate the handling of the rest of the contents of a line containing a C#
+/// preprocessor directives after it has tokenized the directive itself. This
+/// companion lexers must be registered with the names "preproLexer" and
+/// "hooverLexer" in the associated with this
+/// Lexer via the Selector property.
+///
+///
+///
+/// History
+///
+///
+///
+/// 31-May-2002 kunle Created first cut from ECMA spec (renamed from Ecma344_CSharp.g)
+/// 08-Feb-2003 kunle Separated Lexer from the original combined Lexer/Parser grammar file
+/// 05-Apr-2004 kunle Post-directive handling is now delegated to one of two companion lexers.
+///
+///
+///
+
+
+*/
+class CSharpLexer extends CSharpLexerBase;
+
+options
+{
+ importVocab = CSharpLexerBase;
+ exportVocab = CSharpLexer;
+ charVocabulary = '\u0000'..'\uFFFE'; // All UNICODE characters except \uFFFF [and \u0000 to \u0002 used by ANTLR]
+ k = 3; // two characters of lookahead
+ testLiterals = false; // don't automatically test for literals
+ //defaultErrorHandler = true;
+ defaultErrorHandler = false;
+ codeGenMakeSwitchThreshold = 5; // Some optimizations
+ codeGenBitsetTestThreshold = 5;
+}
+
+//======================================
+// Section A.1.7 Keywords
+//
+tokens // MUST be kept in sync with "keywordsTable" Hashtable below!!
+{
+ ABSTRACT = "abstract";
+ AS = "as";
+ BASE = "base";
+ BOOL = "bool";
+ BREAK = "break";
+ BYTE = "byte";
+ CASE = "case";
+ CATCH = "catch";
+ CHAR = "char";
+ CHECKED = "checked";
+ CLASS = "class";
+ CONST = "const";
+ CONTINUE = "continue";
+ DECIMAL = "decimal";
+// DEFAULT = "default";
+ DELEGATE = "delegate";
+ DO = "do";
+ DOUBLE = "double";
+ ELSE = "else";
+ ENUM = "enum";
+ EVENT = "event";
+ EXPLICIT = "explicit";
+ EXTERN = "extern";
+// FALSE = "false";
+ FINALLY = "finally";
+ FIXED = "fixed";
+ FLOAT = "float";
+ FOR = "for";
+ FOREACH = "foreach";
+ GOTO = "goto";
+ IF = "if";
+ IMPLICIT = "implicit";
+ IN = "in";
+ INT = "int";
+ INTERFACE = "interface";
+ INTERNAL = "internal";
+ IS = "is";
+ LOCK = "lock";
+ LONG = "long";
+ NAMESPACE = "namespace";
+ NEW = "new";
+ NULL = "null";
+ OBJECT = "object";
+ OPERATOR = "operator";
+ OUT = "out";
+ OVERRIDE = "override";
+ PARAMS = "params";
+ PRIVATE = "private";
+ PROTECTED = "protected";
+ PUBLIC = "public";
+ READONLY = "readonly";
+ REF = "ref";
+ RETURN = "return";
+ SBYTE = "sbyte";
+ SEALED = "sealed";
+ SHORT = "short";
+ SIZEOF = "sizeof";
+ STACKALLOC = "stackalloc";
+ STATIC = "static";
+ STRING = "string";
+ STRUCT = "struct";
+ SWITCH = "switch";
+ THIS = "this";
+ THROW = "throw";
+// TRUE = "true";
+ TRY = "try";
+ TYPEOF = "typeof";
+ UINT = "uint";
+ ULONG = "ulong";
+ UNCHECKED = "unchecked";
+ UNSAFE = "unsafe";
+ USHORT = "ushort";
+ USING = "using";
+ VIRTUAL = "virtual";
+ VOID = "void";
+ VOLATILE = "volatile";
+ WHILE = "while";
+
+ DOT;
+ UINT_LITERAL;
+ LONG_LITERAL;
+ ULONG_LITERAL;
+ DECIMAL_LITERAL;
+ FLOAT_LITERAL;
+ DOUBLE_LITERAL;
+
+ "add";
+ "remove";
+ "get";
+ "set";
+ "assembly";
+ "field";
+ "method";
+ "module";
+ "param";
+ "property";
+ "type";
+}
+
+{
+
+ ///
+ /// A for switching between this Lexer and the Preprocessor Lexer.
+ ///
+ private TokenStreamSelector selector_;
+
+ ///
+ /// A for switching between this Lexer and the Preprocessor Lexer.
+ ///
+ public TokenStreamSelector Selector
+ {
+ get { return selector_; }
+ set { selector_ = value; }
+ }
+
+ private FileInfo _fileinfo = null;
+
+ ///
+ /// Update _fileinfo member whenever filename changes.
+ ///
+ public override void setFilename(string f)
+ {
+ base.setFilename(f);
+ _fileinfo = new FileInfo(f);
+ }
+
+ ///
+ /// Ensures all tokens have access to the source file's details.
+ ///
+ protected override IToken makeToken(int t)
+ {
+ IToken result = base.makeToken(t);
+ CustomHiddenStreamToken customToken = result as CustomHiddenStreamToken;
+ if ( customToken != null )
+ {
+ customToken.File = _fileinfo;
+ }
+ return result;
+ }
+
+ ///
+ /// This table is used to keep a searchable list of keywords only. This is used mainly
+ /// as for section "A.1.6 Identifers" for determining if an identifier is indeed a
+ /// VERBATIM_IDENTIFIER. It's contents MUST be kept in sync with the contents of section
+ /// "A.1.7 Keywords" above.
+ ///
+ ///
+ private static Hashtable keywordsTable = new Hashtable();
+
+ static CSharpLexer()
+ {
+ keywordsTable.Add(ABSTRACT, "abstract");
+ keywordsTable.Add(AS, "as");
+ keywordsTable.Add(BASE, "base");
+ keywordsTable.Add(BOOL, "bool");
+ keywordsTable.Add(BREAK, "break");
+ keywordsTable.Add(BYTE, "byte");
+ keywordsTable.Add(CASE, "case");
+ keywordsTable.Add(CATCH, "catch");
+ keywordsTable.Add(CHAR, "char");
+ keywordsTable.Add(CHECKED, "checked");
+ keywordsTable.Add(CLASS, "class");
+ keywordsTable.Add(CONST, "const");
+ keywordsTable.Add(CONTINUE, "continue");
+ keywordsTable.Add(DECIMAL, "decimal");
+ keywordsTable.Add(DEFAULT, "default");
+ keywordsTable.Add(DELEGATE, "delegate");
+ keywordsTable.Add(DO, "do");
+ keywordsTable.Add(DOUBLE, "double");
+ keywordsTable.Add(ELSE, "else");
+ keywordsTable.Add(ENUM, "enum");
+ keywordsTable.Add(EVENT, "event");
+ keywordsTable.Add(EXPLICIT, "explicit");
+ keywordsTable.Add(EXTERN, "extern");
+ keywordsTable.Add(FALSE, "false");
+ keywordsTable.Add(FINALLY, "finally");
+ keywordsTable.Add(FIXED, "fixed");
+ keywordsTable.Add(FLOAT, "float");
+ keywordsTable.Add(FOR, "for");
+ keywordsTable.Add(FOREACH, "foreach");
+ keywordsTable.Add(GOTO, "goto");
+ keywordsTable.Add(IF, "if");
+ keywordsTable.Add(IMPLICIT, "implicit");
+ keywordsTable.Add(IN, "in");
+ keywordsTable.Add(INT, "int");
+ keywordsTable.Add(INTERFACE, "interface");
+ keywordsTable.Add(INTERNAL, "internal");
+ keywordsTable.Add(IS, "is");
+ keywordsTable.Add(LOCK, "lock");
+ keywordsTable.Add(LONG, "long");
+ keywordsTable.Add(NAMESPACE, "namespace");
+ keywordsTable.Add(NEW, "new");
+ keywordsTable.Add(NULL, "null");
+ keywordsTable.Add(OBJECT, "object");
+ keywordsTable.Add(OPERATOR, "operator");
+ keywordsTable.Add(OUT, "out");
+ keywordsTable.Add(OVERRIDE, "override");
+ keywordsTable.Add(PARAMS, "params");
+ keywordsTable.Add(PRIVATE, "private");
+ keywordsTable.Add(PROTECTED, "protected");
+ keywordsTable.Add(PUBLIC, "public");
+ keywordsTable.Add(READONLY, "readonly");
+ keywordsTable.Add(REF, "ref");
+ keywordsTable.Add(RETURN, "return");
+ keywordsTable.Add(SBYTE, "sbyte");
+ keywordsTable.Add(SEALED, "sealed");
+ keywordsTable.Add(SHORT, "short");
+ keywordsTable.Add(SIZEOF, "sizeof");
+ keywordsTable.Add(STACKALLOC, "stackalloc");
+ keywordsTable.Add(STATIC, "static");
+ keywordsTable.Add(STRING, "string");
+ keywordsTable.Add(STRUCT, "struct");
+ keywordsTable.Add(SWITCH, "switch");
+ keywordsTable.Add(THIS, "this");
+ keywordsTable.Add(THROW, "throw");
+ keywordsTable.Add(TRUE, "true");
+ keywordsTable.Add(TRY, "try");
+ keywordsTable.Add(TYPEOF, "typeof");
+ keywordsTable.Add(UINT, "uint");
+ keywordsTable.Add(ULONG, "ulong");
+ keywordsTable.Add(UNCHECKED, "unchecked");
+ keywordsTable.Add(UNSAFE, "unsafe");
+ keywordsTable.Add(USHORT, "ushort");
+ keywordsTable.Add(USING, "using");
+ keywordsTable.Add(VIRTUAL, "virtual");
+ keywordsTable.Add(VOID, "void");
+ keywordsTable.Add(WHILE, "while");
+ }
+
+ public bool IsLetterCharacter(string s)
+ {
+ return ( (UnicodeCategory.LowercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Ll
+ (UnicodeCategory.ModifierLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lm
+ (UnicodeCategory.OtherLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lo
+ (UnicodeCategory.TitlecaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lt
+ (UnicodeCategory.UppercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lu
+ (UnicodeCategory.LetterNumber == Char.GetUnicodeCategory(s, 1)) //UNICODE class Nl
+ );
+ }
+
+ public bool IsIdentifierCharacter(string s)
+ {
+ return ( (UnicodeCategory.LowercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Ll
+ (UnicodeCategory.ModifierLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lm
+ (UnicodeCategory.OtherLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lo
+ (UnicodeCategory.TitlecaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lt
+ (UnicodeCategory.UppercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lu
+ (UnicodeCategory.LetterNumber == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Nl
+ (UnicodeCategory.NonSpacingMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mn
+ (UnicodeCategory.SpacingCombiningMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mc
+ (UnicodeCategory.DecimalDigitNumber == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Nd
+ (UnicodeCategory.ConnectorPunctuation == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Pc
+ (UnicodeCategory.Format == Char.GetUnicodeCategory(s, 1)) //UNICODE class Cf
+ );
+ }
+
+ public bool IsCombiningCharacter(string s)
+ {
+ return ( (UnicodeCategory.NonSpacingMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mn
+ (UnicodeCategory.SpacingCombiningMark == Char.GetUnicodeCategory(s, 1)) //UNICODE class Mc
+ );
+ }
+
+}
+
+
+//======================================
+// Start of Lexer Rules
+//======================================
+
+
+//======================================
+// Section A.1.1 Line terminators
+//
+NEWLINE
+ : ( '\r' // MacOS-style newline
+ ( options { generateAmbigWarnings=false; }
+ : '\n' // DOS/Windows style newline
+ )?
+ | '\n' // UNIX-style newline
+ | '\u2028' // UNICODE line separator
+ | '\u2029' // UNICODE paragraph separator
+ )
+ { newline();
+ }
+ ;
+
+
+//======================================
+// Section A.1.2 White space
+//
+
+WHITESPACE
+ : pp1:PP_DIRECTIVE
+ { if ( pp1.getColumn() == 1)
+ {
+ $setType(pp1.Type);
+ if ((pp1.Type == PP_REGION) || (pp1.Type == PP_ENDREGION) || (pp1.Type == PP_WARNING) || (pp1.Type == PP_ERROR))
+ selector_.push("hooverLexer");
+ else
+ selector_.push("directivesLexer");
+ }
+ else
+ $setType(PP_STRING);
+ }
+ | nnw:NON_NEWLINE_WHITESPACE (NON_NEWLINE_WHITESPACE)*
+ ( { (nnw.getColumn() == 1) }? pp2:PP_DIRECTIVE
+ {
+ $setType(pp2.Type);
+ if ((pp2.Type == PP_REGION) || (pp2.Type == PP_ENDREGION) || (pp2.Type == PP_WARNING) || (pp2.Type == PP_ERROR))
+ selector_.push("hooverLexer");
+ else
+ selector_.push("directivesLexer");
+ }
+ )?
+ ;
+
+//======================================
+// Section A.1.3 Comments
+//
+ML_COMMENT
+ : "/*"
+ ( options { generateAmbigWarnings=false; } // ignore non-determinism on "*/" between me and block exit
+ : { LA(2) != '/' }? '*'
+ | NEWLINE //{ newline(); }
+ | ~( '*' | '\r' | '\n' | '\u2028' | '\u2029') // ~( NEWLINE | '*' ) -- generated error
+ )*
+ "*/" //{ $setType(Token.SKIP); }
+ ;
+
+
+//======================================
+// A.1.6 Identifiers
+//
+IDENTIFIER
+ options { testLiterals = true; }
+ : '@' '"' { $setType(STRING_LITERAL); }
+ ( ~( '"' )
+ | ('"' '"')
+ )*
+ '"'
+ | ( '@' )?
+ (
+ ( '_'
+ | LETTER_CHARACTER
+ | { IsLetterCharacter(eseq.getText()) }? eseq:UNICODE_ESCAPE_SEQUENCE
+ )
+ ( LETTER_CHARACTER
+ | DECIMAL_DIGIT_CHARACTER
+ | CONNECTING_CHARACTER
+ | COMBINING_CHARACTER
+ | FORMATTING_CHARACTER
+ | { IsIdentifierCharacter(eseq2.getText()) }? eseq2:UNICODE_ESCAPE_SEQUENCE
+ )*
+ )
+ ;
+
+
+//======================================
+// A.1.8 Literals
+//
+//
+INT_LITERAL // BYTE, SHORT, INT, LONG
+ : '0' ('x' | 'X') (HEX_DIGIT)+
+ ( ('l' | 'L') { $setType(LONG_LITERAL); }
+ ( ('u' | 'U') { $setType(ULONG_LITERAL); } )?
+ | ('u' | 'U') { $setType(UINT_LITERAL); }
+ ( ('l' | 'L') { $setType(ULONG_LITERAL); } )?
+ )?
+ | '.' { $setType(DOT); }
+ ( (DECIMAL_DIGIT)+ { $setType(DOUBLE_LITERAL); }
+ ( ('e'|'E') ('+'|'-')? (DECIMAL_DIGIT)+ )?
+ ( ( 'f' | 'F' ) { $setType(FLOAT_LITERAL); }
+ | ( 'd' | 'D' )
+ | ( 'm' | 'M' ) { $setType(DECIMAL_LITERAL); }
+ )?
+ )?
+ | (DECIMAL_DIGIT)+
+ ( '.' (DECIMAL_DIGIT)+ { $setType(DOUBLE_LITERAL); }
+ ( ('e'|'E') ('+'|'-')? (DECIMAL_DIGIT)+ )?
+ ( ( 'f' | 'F' ) { $setType(FLOAT_LITERAL); }
+ | ( 'd' | 'D' )
+ | ( 'm' | 'M' ) { $setType(DECIMAL_LITERAL); }
+ )?
+ | ('e'|'E') ('+'|'-')?
+ (DECIMAL_DIGIT)+ { $setType(DOUBLE_LITERAL); }
+ ( ( 'f' | 'F' ) { $setType(FLOAT_LITERAL); }
+ | ( 'd' | 'D' )
+ | ( 'm' | 'M' ) { $setType(DECIMAL_LITERAL); }
+ )?
+ | ( ( 'f' | 'F' ) { $setType(FLOAT_LITERAL); }
+ | ( 'd' | 'D' ) { $setType(DOUBLE_LITERAL); }
+ | ( 'm' | 'M' ) { $setType(DECIMAL_LITERAL); }
+ )
+ | ( ('l' | 'L') { $setType(LONG_LITERAL); }
+ ( ('u' | 'U') { $setType(ULONG_LITERAL); } )?
+ | ('u' | 'U') { $setType(UINT_LITERAL); }
+ ( ('l' | 'L') { $setType(ULONG_LITERAL); } )?
+ )
+ )?
+ ;
+
+CHAR_LITERAL
+ : '\''
+ ( ~( '\'' | '\\' | '\r' | '\n' | '\u2028' | '\u2029' )
+ | ESCAPED_LITERAL
+ )
+ '\''
+ ;
+
+STRING_LITERAL
+ : '"'
+ ( ~( '"' | '\\' | '\r' | '\n' | '\u2028' | '\u2029' )
+ | ESCAPED_LITERAL
+ )*
+ '"'
+ ;
+
+
+// The ESCAPED_LITERAL rule represents a common subset of the definitons of both STRING_LITERAL
+// and CHAR_LITERAL. It was extracted from both to ensure that multiples copies of the same
+// [semi-complex] sub-recognizer isn't maintained in multiple places.
+//
+protected ESCAPED_LITERAL
+ : '\\'
+ ( '\''
+ | '"'
+ | '\\'
+ | '0'
+ | 'a'
+ | 'b'
+ | 'f'
+ | 'n'
+ | 'r'
+ | 't'
+ | 'v'
+ | 'x' HEX_DIGIT
+ ( options { generateAmbigWarnings=false; }
+ : HEX_DIGIT
+ ( options { generateAmbigWarnings=false; }
+ : HEX_DIGIT
+ ( options { generateAmbigWarnings=false; }
+ : HEX_DIGIT
+ )?
+ )?
+ )?
+ )
+ | UNICODE_ESCAPE_SEQUENCE
+ ;
+
+
+//======================================
+// A.1.9 Operators and punctuators
+//
+OPEN_CURLY : '{' ;
+CLOSE_CURLY : '}' ;
+OPEN_BRACK : '[' ;
+CLOSE_BRACK : ']' ;
+OPEN_PAREN : '(' ;
+CLOSE_PAREN : ')' ;
+//DOT : '.' ; // moved to INTEGER_LITERAL rule to avoid conflict
+COMMA : ',' ;
+COLON : ':' ;
+SEMI : ';' ;
+PLUS : '+' ;
+MINUS : '-' ;
+STAR : '*' ;
+DIV : '/' ;
+MOD : '%' ;
+BIN_AND : '&' ;
+BIN_OR : '|' ;
+BIN_XOR : '^' ;
+LOG_NOT : '!' ;
+BIN_NOT : '~' ;
+ASSIGN : '=' ;
+LTHAN : '<' ;
+GTHAN : '>' ;
+QUESTION : '?' ;
+INC : "++" ;
+DEC : "--" ;
+LOG_AND : "&&" ;
+LOG_OR : "||" ;
+SHIFTL : "<<" ;
+SHIFTR : ">>" ;
+EQUAL : "==" ;
+NOT_EQUAL : "!=" ;
+LTE : "<=" ;
+GTE : ">=" ;
+PLUS_ASSIGN : "+=" ;
+MINUS_ASSIGN : "-=" ;
+STAR_ASSIGN : "*=" ;
+DIV_ASSIGN : "/=" ;
+MOD_ASSIGN : "%=" ;
+BIN_AND_ASSIGN : "&=" ;
+BIN_OR_ASSIGN : "|=" ;
+BIN_XOR_ASSIGN : "^=" ;
+SHIFTL_ASSIGN : "<<=" ;
+SHIFTR_ASSIGN : ">>=" ;
+DEREF : "->" ;
+
+
+//======================================
+// A.1.10 Pre-processing directives
+//
+
+protected PP_DIRECTIVE
+ : '#' (NON_NEWLINE_WHITESPACE)*
+ ( "define" { $setType(PP_DEFINE); }
+ | "undef" { $setType(PP_UNDEFINE); }
+ | "if" { $setType(PP_COND_IF); }
+ | "line" { $setType(PP_LINE); }
+ | "error" { $setType(PP_ERROR); }
+ | "warning" { $setType(PP_WARNING); }
+ | "region" { $setType(PP_REGION); }
+ | 'e'
+ ( 'l'
+ ( "se" { $setType(PP_COND_ELSE); }
+ | "if" { $setType(PP_COND_ELIF); }
+ )
+ | "nd"
+ ( "if" { $setType(PP_COND_ENDIF); }
+ | "region" { $setType(PP_ENDREGION); }
+ )
+ )
+ )
+ ;
+
diff --git a/CSharpTranslator/Translator/CSharpLexerBase.g b/CSharpTranslator/Translator/CSharpLexerBase.g
new file mode 100644
index 0000000..d53c481
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpLexerBase.g
@@ -0,0 +1,201 @@
+header
+{
+ using System.Globalization;
+}
+
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// The basic building block of C# Preprocessors and Lexers.
+///
+///
+///
+///
+/// The Lexer defined below is effectively an abstract base class that collects together a
+/// number of rules that are useful to all Preprocessors and Lexers for the C# language.
+///
+///
+///
+/// History
+///
+///
+///
+/// 26-Jan-2003 kunle Derived this Lexer from the original combined grammar
+///
+///
+///
+
+
+*/
+class CSharpLexerBase extends UnicodeLexerBase;
+
+options
+{
+ importVocab = UnicodeLexerBase;
+ exportVocab = CSharpLexerBase;
+ charVocabulary = '\u0000'..'\uFFFE'; // All UNICODE characters except \uFFFF [and \u0000 to \u0002 used by ANTLR]
+ k = 2;
+ testLiterals = false; // don't automatically test for literals
+ defaultErrorHandler = false;
+}
+
+tokens
+{
+ TRUE = "true";
+ FALSE = "false";
+ DEFAULT = "default";
+
+ PP_DEFINE;
+ PP_UNDEFINE;
+ PP_COND_IF;
+ PP_COND_ELIF;
+ PP_COND_ELSE;
+ PP_COND_ENDIF;
+ PP_LINE;
+ PP_ERROR;
+ PP_WARNING;
+ PP_REGION;
+ PP_ENDREGION;
+
+ PP_FILENAME;
+ PP_IDENT;
+ PP_STRING;
+ PP_NUMBER;
+
+ WHITESPACE;
+}
+
+//======================================
+// Start of Lexer Rules
+//======================================
+
+// The following group of rules are shared by C# Preprocessors and Lexers
+QUOTE : '"' ;
+OPEN_PAREN : '(' ;
+CLOSE_PAREN : ')' ;
+LOG_NOT : '!' ;
+LOG_AND : "&&" ;
+LOG_OR : "||" ;
+EQUAL : "==" ;
+NOT_EQUAL : "!=" ;
+
+
+//======================================
+// Section A.1.3 Comments
+//
+SL_COMMENT
+ : "//" ( NOT_NEWLINE )* (NEWLINE)?
+ ;
+
+//======================================
+// Section A.1.1 Line terminators
+//
+//protected
+NEWLINE
+ : ( '\r' // MacOS-style newline
+ ( options { generateAmbigWarnings=false; }
+ : '\n' // DOS/Windows style newline
+ )?
+ | '\n' // UNIX-style newline
+ | '\u2028' // UNICODE line separator
+ | '\u2029' // UNICODE paragraph separator
+ )
+ { newline(); }
+ ;
+
+protected NOT_NEWLINE
+ : ~( '\r' | '\n' | '\u2028' | '\u2029' )
+ ;
+
+
+//======================================
+// Section A.1.2 White space
+//
+
+protected NON_NEWLINE_WHITESPACE
+ : '\t' // horiz_tab
+// | ' ' // space -- commented out because UNICODE_CLASS_Zs contains space too
+ | '\f' // form_feed
+ | '\u000B' // '\u000B' == '\v' == vert_tab
+ | UNICODE_CLASS_Zs
+ ;
+
+
+//======================================
+// Section A.1.5 Unicode character escape sequences
+//
+protected UNICODE_ESCAPE_SEQUENCE
+ : '\\'
+ ( 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
+ | 'U' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
+ )
+ ;
+
+
+protected DECIMAL_DIGIT
+ : ('0'..'9')
+ ;
+
+protected HEX_DIGIT
+ : ('0'..'9'|'A'..'F'|'a'..'f')
+ ;
+
+
+protected LETTER_CHARACTER
+ : UNICODE_CLASS_Lu
+ | UNICODE_CLASS_Ll
+ | UNICODE_CLASS_Lt
+ | UNICODE_CLASS_Lm
+ | UNICODE_CLASS_Lo
+ | UNICODE_CLASS_Nl
+ ;
+
+protected DECIMAL_DIGIT_CHARACTER
+ : UNICODE_CLASS_Nd
+ ;
+
+protected CONNECTING_CHARACTER
+ : UNICODE_CLASS_Pc
+ ;
+
+protected COMBINING_CHARACTER
+ : UNICODE_CLASS_Mn
+ | UNICODE_CLASS_Mc
+ ;
+
+protected FORMATTING_CHARACTER
+ : UNICODE_CLASS_Cf
+ ;
+
diff --git a/CSharpTranslator/Translator/CSharpParser.g b/CSharpTranslator/Translator/CSharpParser.g
new file mode 100644
index 0000000..5af6b48
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpParser.g
@@ -0,0 +1,1951 @@
+header
+{
+ using StringBuilder = System.Text.StringBuilder;
+ using FileInfo = System.IO.FileInfo;
+}
+
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/**
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// A Parser for the C# language (including preprocessors directives).
+///
+///
+///
+///
+/// The Parser defined below is based on the "C# Language Specification" as documented in
+/// the ECMA-334 standard dated December 2001.
+///
+///
+///
+/// One notable feature of this parser is that it can handle input that includes "normalized"
+/// C# preprocessing directives. In the simplest sense, normalized C# preprocessing directives
+/// are directives that can be safely deleted from a source file without triggering any parsing
+/// errors due to incomplete statements etc.
+///
+///
+///
+/// The Abstract Syntax Tree that this parser constructs has special nodes that represents
+// all the C# preprocessor directives defined in the ECMA-334 standard.
+///
+///
+///
+/// History
+///
+///
+///
+/// 31-May-2002 kunle Started work in earnest
+/// 09-Feb-2003 kunle Separated Parser from the original combined Lexer/Parser grammar file
+/// 20-Oct-2003 kunle Removed STMT_LIST from inside BLOCK nodes. A BLOCK node now directly contains
+/// a list of statements. Finding the AST nodes that correspond to a selection
+/// should now be easier.
+///
+///
+///
+
+*/
+class CSharpParser extends Parser;
+
+options
+{
+ k = 2; // two tokens of lookahead
+ importVocab = CSharpLexer;
+ exportVocab = CSharpJava;
+ buildAST = true;
+ ASTLabelType = "ASTNode";
+ //codeGenMakeSwitchThreshold = 5; // Some optimizations
+ //codeGenBitsetTestThreshold = 50;
+ //defaultErrorHandler = false;
+ defaultErrorHandler = true;
+}
+
+tokens
+{
+ COMPILATION_UNIT;
+ USING_DIRECTIVES;
+ USING_ALIAS_DIRECTIVE;
+ USING_NAMESPACE_DIRECTIVE;
+ GLOBAL_ATTRIBUTE_SECTIONS;
+ GLOBAL_ATTRIBUTE_SECTION;
+ ATTRIBUTE_SECTIONS;
+ ATTRIBUTE_SECTION;
+ ATTRIBUTE;
+ QUALIFIED_IDENTIFIER;
+ POSITIONAL_ARGLIST;
+ POSITIONAL_ARG;
+ NAMED_ARGLIST;
+ NAMED_ARG;
+ ARG_LIST;
+ FORMAL_PARAMETER_LIST;
+ PARAMETER_FIXED;
+ PARAMETER_ARRAY;
+ ATTRIB_ARGUMENT_EXPR;
+ UNARY_MINUS;
+ UNARY_PLUS;
+ CLASS_BASE;
+ STRUCT_BASE;
+ INTERFACE_BASE;
+ ENUM_BASE;
+ TYPE_BODY;
+ MEMBER_LIST;
+ CONST_DECLARATOR;
+ CTOR_DECL;
+ STATIC_CTOR_DECL;
+ DTOR_DECL;
+ FIELD_DECL;
+ METHOD_DECL;
+ PROPERTY_DECL;
+ INDEXER_DECL;
+ UNARY_OP_DECL;
+ BINARY_OP_DECL;
+ CONV_OP_DECL;
+
+ TYPE;
+ STARS;
+ ARRAY_RANK;
+ ARRAY_RANKS;
+ ARRAY_INIT;
+ VAR_INIT;
+ VAR_INIT_LIST;
+ VAR_DECLARATOR;
+ LOCVAR_INIT;
+ LOCVAR_INIT_LIST;
+ LOCVAR_DECLS;
+ LOCAL_CONST;
+
+ EXPR;
+ EXPR_LIST;
+ MEMBER_ACCESS_EXPR;
+ ELEMENT_ACCESS_EXPR;
+ INVOCATION_EXPR;
+ POST_INC_EXPR;
+ POST_DEC_EXPR;
+ PAREN_EXPR;
+ OBJ_CREATE_EXPR;
+ DLG_CREATE_EXPR;
+ ARRAY_CREATE_EXPR;
+ CAST_EXPR;
+
+ PTR_ELEMENT_ACCESS_EXPR;
+ PTR_INDIRECTION_EXPR;
+ PTR_DECLARATOR;
+ PTR_INIT;
+ ADDRESS_OF_EXPR;
+
+ MODIFIERS;
+ NAMESPACE_BODY;
+ BLOCK;
+ STMT_LIST;
+ EMPTY_STMT;
+ LABEL_STMT;
+ EXPR_STMT;
+
+ FOR_INIT;
+ FOR_COND;
+ FOR_ITER;
+
+ SWITCH_SECTION;
+ SWITCH_LABELS;
+ SWITCH_LABEL;
+
+ PP_DIRECTIVES;
+ PP_EXPR;
+ PP_MESSAGE;
+ PP_BLOCK;
+
+ // Java Tokens
+ JAVAWRAPPER; // For strings of Java text that has already been converted
+ FIXME; // Contains C# that we couldn't convert
+ MULTI_COMPILATION_UNITS;
+ IMPORTS;
+ IMPORT="import";
+ PACKAGE_DEF="package";
+ FINAL="final";
+ EXTENDS_CLAUSE;
+ IMPLEMENTS_CLAUSE;
+ INSTANCEOF="instanceof";
+ SUPER="super";
+ THROWS="throws";
+ ANNOTATION="@interface";
+}
+
+{
+ //---------------------------------------------------------------------
+ // PRIVATE DATA MEMBERS
+ //---------------------------------------------------------------------
+ private FileInfo fileinfo_;
+
+ private bool NotExcluded(CodeMaskEnums codeMask, CodeMaskEnums construct)
+ {
+ return ((codeMask & construct) != 0 );
+ }
+
+ public override void setFilename(string filename)
+ {
+ base.setFilename(filename);
+ fileinfo_ = new FileInfo(filename);
+ ((ASTNodeFactory) astFactory).FileInfo = fileinfo_;
+ }
+
+ private bool SingleLinePPDirectiveIsPredictedByLA(int lookAheadDepth)
+ {
+ if ((LA(lookAheadDepth) == PP_WARNING) ||
+ (LA(lookAheadDepth) == PP_ERROR) ||
+ (LA(lookAheadDepth) == PP_LINE) ||
+ (LA(lookAheadDepth) == PP_UNDEFINE) ||
+ (LA(lookAheadDepth) == PP_DEFINE))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private bool PPDirectiveIsPredictedByLA(int lookAheadDepth)
+ {
+ if ((LA(lookAheadDepth) == PP_REGION) ||
+ (LA(lookAheadDepth) == PP_COND_IF) ||
+ (LA(lookAheadDepth) == PP_WARNING) ||
+ (LA(lookAheadDepth) == PP_ERROR) ||
+ (LA(lookAheadDepth) == PP_LINE) ||
+ (LA(lookAheadDepth) == PP_UNDEFINE) ||
+ (LA(lookAheadDepth) == PP_DEFINE))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private bool IdentifierRuleIsPredictedByLA(int lookAheadDepth)
+ {
+ if ((LA(lookAheadDepth) == IDENTIFIER) ||
+ (LA(lookAheadDepth) == LITERAL_add) ||
+ (LA(lookAheadDepth) == LITERAL_remove) ||
+ (LA(lookAheadDepth) == LITERAL_get) ||
+ (LA(lookAheadDepth) == LITERAL_set) ||
+ (LA(lookAheadDepth) == LITERAL_assembly) ||
+ (LA(lookAheadDepth) == LITERAL_field) ||
+ (LA(lookAheadDepth) == LITERAL_method) ||
+ (LA(lookAheadDepth) == LITERAL_module) ||
+ (LA(lookAheadDepth) == LITERAL_param) ||
+ (LA(lookAheadDepth) == LITERAL_property) ||
+ (LA(lookAheadDepth) == LITERAL_type))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private bool TypeRuleIsPredictedByLA(int lookAheadDepth)
+ {
+ if ((LA(lookAheadDepth) == DOT) ||
+ (LA(lookAheadDepth) == VOID) ||
+ (LA(lookAheadDepth) == IDENTIFIER) ||
+ (LA(lookAheadDepth) == INT) ||
+ (LA(lookAheadDepth) == BOOL) ||
+ (LA(lookAheadDepth) == STRING) ||
+ (LA(lookAheadDepth) == OBJECT) ||
+ (LA(lookAheadDepth) == BYTE) ||
+ (LA(lookAheadDepth) == CHAR) ||
+ (LA(lookAheadDepth) == DECIMAL) ||
+ (LA(lookAheadDepth) == DOUBLE) ||
+ (LA(lookAheadDepth) == FLOAT) ||
+ (LA(lookAheadDepth) == LONG) ||
+ (LA(lookAheadDepth) == SBYTE) ||
+ (LA(lookAheadDepth) == SHORT) ||
+ (LA(lookAheadDepth) == UINT) ||
+ (LA(lookAheadDepth) == ULONG) ||
+ (LA(lookAheadDepth) == USHORT))
+ {
+ return true;
+ }
+ return false;
+ }
+}
+
+//=============================================================================
+// Start of RULES
+//=============================================================================
+
+//
+// C# LANGUAGE SPECIFICATION
+//
+// A.2 Syntactic grammar
+//
+// The start rule for this grammar is 'compilationUnit'
+//
+
+//
+// A.2.1 Basic concepts
+//
+
+nonKeywordLiterals
+ : "add"
+ | "remove"
+ | "get"
+ | "set"
+ | "assembly"
+ | "field"
+ | "method"
+ | "module"
+ | "param"
+ | "property"
+ | "type"
+ ;
+
+identifier
+ : IDENTIFIER
+ | n:nonKeywordLiterals { #n.setType(IDENTIFIER); }
+ ;
+
+qualifiedIdentifier
+ : identifier
+ ( options { greedy = true; } :
+ DOT^ qualifiedIdentifier
+ )?
+ ;
+
+/*
+//
+// A.2.2 Types
+//
+*/
+type!
+ {
+ ASTNode typeBase = null;
+ ASTNode starsBase = #[STARS, "STARS"];
+ }
+ : (
+ ( p:predefinedTypeName { typeBase = #p; } | q:qualifiedIdentifier { typeBase = #q; } ) // typeName
+ (
+ s1:STAR // pointerType
+ {
+ #starsBase.addChildEx(#s1);
+ }
+ )*
+
+ | v:VOID s2:STAR
+ {
+ #starsBase.addChildEx(#s2);
+ typeBase = #v;
+ }
+ )
+ r:rankSpecifiers // arrayType := nonArrayType rankSpecifiers
+ { ## = #( [TYPE, "TYPE"], typeBase, starsBase, r ); }
+ ;
+
+integralType
+ : ( SBYTE
+ | BYTE
+ | SHORT
+ | USHORT
+ | INT
+ | UINT
+ | LONG
+ | ULONG
+ | CHAR
+ )
+ { ## = #( [TYPE, "TYPE"], ##, [STARS, "STARS"], [ARRAY_RANKS, "ARRAY_RANKS"] ); }
+ ;
+
+classType
+ : ( qualifiedIdentifier // typeName
+ | OBJECT
+ | STRING
+ )
+ { ## = #( [TYPE, "TYPE"], ##, [STARS, "STARS"], [ARRAY_RANKS, "ARRAY_RANKS"] ); }
+ ;
+
+/*
+//
+// A.2.4 Expressions
+//
+*/
+argumentList
+ : argument ( COMMA! argument )*
+ { ## = #( [ARG_LIST, "ARG_LIST"], #argumentList ); }
+ ;
+
+argument
+ : expression
+ | REF^ expression
+ | OUT^ expression
+ ;
+
+constantExpression
+ : expression
+ ;
+
+booleanExpression
+ : expression
+ ;
+
+expressionList
+ : expression ( COMMA! expression )*
+ { ## = #( [EXPR_LIST, "EXPR_LIST"], #expressionList ); }
+ ;
+
+
+/*
+//======================================
+// 14.2.1 Operator precedence and associativity
+//
+// The following table summarizes all operators in order of precedence from lowest to highest:
+//
+// PRECEDENCE SECTION CATEGORY OPERATORS
+// lowest (14) 14.13 Assignment = *= /= %= += -= <<= >>= &= ^= |=
+// (13) 14.12 Conditional ?:
+// (12) 14.11 Conditional OR ||
+// (11) 14.11 Conditional AND &&
+// (10) 14.10 Logical OR |
+// ( 9) 14.10 Logical XOR ^
+// ( 8) 14.10 Logical AND &
+// ( 7) 14.9 Equality == !=
+// ( 6) 14.9 Relational and type-testing < > <= >= is as
+// ( 5) 14.8 Shift << >>
+// ( 4) 14.7 Additive +{binary} -{binary}
+// ( 3) 14.7 Multiplicative * / %
+// ( 2) 14.6 Unary +{unary} -{unary} ! ~ ++x --x (T)x
+// highest ( 1) 14.5 Primary x.y f(x) a[x] x++ x-- new
+// typeof checked unchecked
+//
+// NOTE: In accordance with lessons gleaned from the "java.g" file supplied with ANTLR,
+// I have applied the following pattern to the rules for expressions:
+//
+// thisLevelExpression :
+// nextHigherPrecedenceExpression (OPERATOR nextHigherPrecedenceExpression)*
+//
+// which is a standard recursive definition for a parsing an expression.
+//
+*/
+expression
+ : assignmentExpression
+ { #expression = #( #[EXPR,"EXPR"], #expression ); }
+ ;
+
+assignmentExpression
+ : conditionalExpression
+ ( ( ASSIGN^
+ | PLUS_ASSIGN^
+ | MINUS_ASSIGN^
+ | STAR_ASSIGN^
+ | DIV_ASSIGN^
+ | MOD_ASSIGN^
+ | BIN_AND_ASSIGN^
+ | BIN_OR_ASSIGN^
+ | BIN_XOR_ASSIGN^
+ | SHIFTL_ASSIGN^
+ | SHIFTR_ASSIGN^
+ )
+ assignmentExpression
+ )?
+ ;
+
+conditionalExpression
+ : conditionalOrExpression ( QUESTION^ assignmentExpression
+ COLON! conditionalExpression
+ )?
+ ;
+
+conditionalOrExpression
+ : conditionalAndExpression ( LOG_OR^ conditionalAndExpression )*
+
+ ;
+
+conditionalAndExpression
+ : inclusiveOrExpression ( LOG_AND^ inclusiveOrExpression )*
+
+ ;
+
+inclusiveOrExpression
+ : exclusiveOrExpression ( BIN_OR^ exclusiveOrExpression )*
+
+ ;
+
+exclusiveOrExpression
+ : andExpression ( BIN_XOR^ andExpression )*
+ ;
+
+andExpression
+ : equalityExpression ( BIN_AND^ equalityExpression )*
+ ;
+
+equalityExpression
+ : relationalExpression ( ( EQUAL^ | NOT_EQUAL^ ) relationalExpression )*
+ ;
+
+relationalExpression
+ : shiftExpression
+ ( ( ( LTHAN^ | GTHAN^ | LTE^ | GTE^ ) shiftExpression )*
+ | ( IS^ | AS^ ) type
+ )
+ ;
+
+shiftExpression
+ : additiveExpression ( ( SHIFTL^ | SHIFTR^ ) additiveExpression )*
+ ;
+
+additiveExpression
+ : multiplicativeExpression ( ( PLUS^ | MINUS^ ) multiplicativeExpression )*
+ ;
+
+multiplicativeExpression
+ : unaryExpression ( ( STAR^ | DIV^ | MOD^ ) unaryExpression )*
+ ;
+
+unaryExpression
+ : // castExpression
+ //
+ ( OPEN_PAREN type CLOSE_PAREN unaryExpression )=>
+ o:OPEN_PAREN^ { #o.setType(CAST_EXPR); } type CLOSE_PAREN! unaryExpression
+ | // preIncrementExpression
+ //
+ INC^ unaryExpression
+ | // preDecrementExpression
+ //
+ DEC^ unaryExpression
+ | p:PLUS^ { #p.setType(UNARY_PLUS ); } unaryExpression
+ | m:MINUS^ { #m.setType(UNARY_MINUS ); } unaryExpression
+ | LOG_NOT^ unaryExpression
+ | BIN_NOT^ unaryExpression
+ | // pointerIndirectionExpression
+ //
+ s:STAR^ { #s.setType(PTR_INDIRECTION_EXPR); } unaryExpression
+ | // addressofExpression
+ //
+ b:BIN_AND^ { #b.setType(ADDRESS_OF_EXPR); } unaryExpression
+ | primaryExpression
+ ;
+
+basicPrimaryExpression
+ // primaryNoArrayCreationExpression
+ //
+ : ( literal
+ | identifier // simpleName
+ | // parenthesizedExpression
+ //
+ o:OPEN_PAREN^ { #o.setType(PAREN_EXPR); } assignmentExpression CLOSE_PAREN!
+ | THIS^ // thisAccess
+ | BASE^
+ ( DOT! identifier // baseAccess
+ | OPEN_BRACK! expressionList CLOSE_BRACK! // baseAccess
+ )
+ | newExpression
+ |! to_t:TYPEOF^ OPEN_PAREN!
+ ( { ((LA(1) == VOID) && (LA(2) == CLOSE_PAREN)) }? to_v:voidAsType CLOSE_PAREN! // typeofExpression
+ { ## = #( #to_t, #to_v ); }
+ | to_typ:type CLOSE_PAREN! // typeofExpression
+ { ## = #( #to_t, #to_typ ); }
+ )
+ | SIZEOF^ OPEN_PAREN! qualifiedIdentifier CLOSE_PAREN! // sizeofExpression
+ | CHECKED^ OPEN_PAREN! expression CLOSE_PAREN! // checkedExpression
+ | UNCHECKED^ OPEN_PAREN! expression CLOSE_PAREN! // uncheckedExpression
+ |! //-- // memberAccess
+ ma_typ:predefinedType dt:DOT ma_id:identifier
+ {
+ #dt.setType(MEMBER_ACCESS_EXPR);
+ ## = #( #dt, #ma_typ, #ma_id );
+ }
+ )
+ ;
+
+primaryExpression!
+ : bexpr:basicPrimaryExpression { ## = #bexpr; }
+ ( options { greedy = true; } :
+ ( // invocationExpression ::= primaryExpression OPEN_PAREN ( argumentList )? CLOSE_PAREN
+ //
+ op:OPEN_PAREN { #a = null; } ( a:argumentList )? CLOSE_PAREN!
+ {
+ #op.setType(INVOCATION_EXPR);
+ ## = #( #op, #bexpr, #a );
+ }
+ | // elementAccess ::= primaryNoArrayCreationExpression OPEN_BRACK expressionList CLOSE_BRACK
+ // pointerElementAccess ::= primaryNoArrayCreationExpression OPEN_BRACK expression CLOSE_BRACK
+ //
+ ob:OPEN_BRACK elist:expressionList CLOSE_BRACK!
+ {
+ #ob.setType(ELEMENT_ACCESS_EXPR);
+ ## = #( #ob, #bexpr, #elist );
+ }
+ | // memberAccess ::= primaryExpression DOT identifier
+ //
+ dt:DOT ma_id:identifier
+ {
+ #dt.setType(MEMBER_ACCESS_EXPR);
+ ## = #( #dt, #bexpr, #ma_id );
+ }
+ | ic:INC // postIncrementExpression
+ {
+ #ic.setType(POST_INC_EXPR);
+ ## = #( #ic, #bexpr );
+ }
+ | dc:DEC // postDecrementExpression
+ {
+ #dc.setType(POST_DEC_EXPR);
+ ## = #( #dc, #bexpr );
+ }
+ | pm_deref:DEREF pm_id:identifier // pointerMemberAccess
+ { ## = #( #pm_deref, #bexpr, #pm_id ); }
+ )
+ { #bexpr = ##; }
+ )*
+ ;
+
+newExpression!
+ : n:NEW typ:type
+ ( // objectCreationExpression ::= NEW type OPEN_PAREN ( argumentList )? CLOSE_PAREN
+ // delegateCreationExpression ::= NEW delegateType OPEN_PAREN expression CLOSE_PAREN
+ // NOTE: Will ALSO match 'delegateCreationExpression'
+ //
+ OPEN_PAREN! ( arglist:argumentList )? CLOSE_PAREN!
+ {
+ #n.setType(OBJ_CREATE_EXPR);
+ ## = #( #n, #typ, #arglist );
+ }
+ | // arrayCreationExpression ::= NEW arrayType arrayInitializer
+ //
+ ar_init:arrayInitializer
+ {
+ #n.setType(ARRAY_CREATE_EXPR);
+ ## = #( #n, #typ, #ar_init );
+ }
+ | // arrayCreationExpression ::= NEW nonArrayType OPEN_BRACK expressionList CLOSE_BRACK ( rankSpecifiers )? ( arrayInitializer )?
+ //
+ OPEN_BRACK! elist:expressionList CLOSE_BRACK!
+ ar_spec2:rankSpecifiers
+ ( ar_init2:arrayInitializer )?
+ {
+ #n.setType(ARRAY_CREATE_EXPR);
+ ## = #( #n, #typ, #elist, #ar_spec2, #ar_init2 );
+ }
+ )
+ ;
+
+literal
+ : TRUE // BOOLEAN_LITERAL
+ | FALSE // BOOLEAN_LITERAL
+ | INT_LITERAL
+ | UINT_LITERAL
+ | LONG_LITERAL
+ | ULONG_LITERAL
+ | DECIMAL_LITERAL
+ | FLOAT_LITERAL
+ | DOUBLE_LITERAL
+ | CHAR_LITERAL
+ | STRING_LITERAL
+ | NULL // NULL_LITERAL
+ ;
+
+predefinedType
+ : ( BOOL
+ | BYTE
+ | CHAR
+ | DECIMAL
+ | DOUBLE
+ | FLOAT
+ | INT
+ | LONG
+ | OBJECT
+ | SBYTE
+ | SHORT
+ | STRING
+ | UINT
+ | ULONG
+ | USHORT
+ )
+ { ## = #( [TYPE, "TYPE"], ##, [STARS, "STARS"], [ARRAY_RANKS, "ARRAY_RANKS"] ); }
+ ;
+
+predefinedTypeName
+ : BOOL
+ | BYTE
+ | CHAR
+ | DECIMAL
+ | DOUBLE
+ | FLOAT
+ | INT
+ | LONG
+ | OBJECT
+ | SBYTE
+ | SHORT
+ | STRING
+ | UINT
+ | ULONG
+ | USHORT
+ ;
+
+
+/*
+//
+// A.2.5 Statements
+//
+*/
+statement
+ : { (IdentifierRuleIsPredictedByLA(1) && (LA(2) == COLON)) }? labeledStatement
+ | { ((LA(1) == CONST) && TypeRuleIsPredictedByLA(2) && IdentifierRuleIsPredictedByLA(3)) ||
+ (TypeRuleIsPredictedByLA(1) && IdentifierRuleIsPredictedByLA(2)) }? declarationStatement
+ | ( ( CONST )? type identifier )=> declarationStatement
+ | embeddedStatement
+ | preprocessorDirective[CodeMaskEnums.Statements]
+ ;
+
+embeddedStatement
+ : block
+ | //emptyStatement
+ //
+ s:SEMI { #s.setType(EMPTY_STMT); }
+ | expressionStatement
+ | selectionStatement
+ | iterationStatement
+ | jumpStatement
+ | tryStatement
+ | checkedStatement
+ | uncheckedStatement
+ | lockStatement
+ | usingStatement
+ | unsafeStatement
+ | fixedStatement
+ ;
+
+
+body
+ : block
+ | s:SEMI { #s.setType(EMPTY_STMT); }
+ ;
+
+block
+ : o:OPEN_CURLY^ { #o.setType(BLOCK); } ( statement )* CLOSE_CURLY
+ ;
+
+statementList
+ : ( statement )+
+ { #statementList = #( [STMT_LIST, "STMT_LIST"], #statementList ); }
+ ;
+
+labeledStatement
+ : id:identifier c:COLON^ { #c.setType(LABEL_STMT); } stmt:statement
+ ;
+
+declarationStatement
+ : localVariableDeclaration SEMI!
+ | localConstantDeclaration SEMI!
+ ;
+
+localVariableDeclaration
+ : type localVariableDeclarators
+ {
+ ## = #( [LOCVAR_DECLS, "LOCVAR_DECLS"], ## );
+ }
+ ;
+
+localVariableDeclarators
+ : localVariableDeclarator
+ (
+ COMMA! localVariableDeclarator
+ )*
+ ;
+
+localVariableDeclarator
+ : identifier ( ASSIGN! localVariableInitializer )?
+ {
+ ## = #( [VAR_DECLARATOR, "VAR_DECLARATOR"], ## );
+ }
+ ;
+
+localVariableInitializer
+ : ( expression
+ | arrayInitializer
+ )
+ { #localVariableInitializer = #( [LOCVAR_INIT, "LOCVAR_INIT"], #localVariableInitializer ); }
+ ;
+
+localConstantDeclaration
+ : c:CONST^ { #c.setType(LOCAL_CONST); } type constantDeclarators
+ ;
+
+constantDeclarators
+ : constantDeclarator
+ (
+ COMMA! constantDeclarator
+ )*
+ ;
+
+constantDeclarator
+ : identifier a:ASSIGN^ { #a.setType(CONST_DECLARATOR); } constantExpression
+ ;
+
+expressionStatement
+ : statementExpression s:SEMI^
+ { #s.setType(EXPR_STMT); }
+ ;
+
+statementExpression!
+ : aexpr:assignmentExpression
+ { ## = #aexpr; }
+/*
+ : invocationExpression
+ | objectCreationExpression
+ | assignmentExpression
+ | postIncrementExpression
+ | postDecrementExpression
+ | preIncrementExpression
+ | preDecrementExpression
+*/
+ ;
+
+selectionStatement
+ : ifStatement
+ | switchStatement
+ ;
+
+ifStatement
+ : IF^ OPEN_PAREN! booleanExpression CLOSE_PAREN! embeddedStatement
+ ( options { greedy = true; } : elseStatement )?
+ ;
+
+elseStatement
+ : ELSE^ embeddedStatement
+ ;
+
+switchStatement
+ : SWITCH^ OPEN_PAREN! expression CLOSE_PAREN! switchBlock
+ ;
+
+switchBlock
+ : OPEN_CURLY^ ( switchSections )? CLOSE_CURLY
+ ;
+
+switchSections
+ : ( switchSection )+
+ ;
+
+switchSection!
+ : lbl:switchLabels stmt:statementList
+ { ## = #( [SWITCH_SECTION, "SWITCH_SECTION"], #lbl, #stmt ); }
+ ;
+
+switchLabels
+ : ( switchLabel )+
+ { #switchLabels = #( [SWITCH_LABELS, "SWITCH_LABELS"], #switchLabels ); }
+ ;
+
+switchLabel
+ : CASE^ constantExpression COLON!
+ | DEFAULT^ COLON!
+ ;
+
+iterationStatement
+ : whileStatement
+ | doStatement
+ | forStatement
+ | foreachStatement
+ ;
+
+whileStatement
+ : WHILE^ OPEN_PAREN! booleanExpression CLOSE_PAREN! embeddedStatement
+ ;
+
+doStatement
+ : DO^ embeddedStatement WHILE! OPEN_PAREN! booleanExpression CLOSE_PAREN! SEMI!
+ ;
+
+forStatement
+ : FOR^ OPEN_PAREN! forInitializer SEMI! forCondition SEMI! forIterator CLOSE_PAREN! embeddedStatement
+ ;
+
+forInitializer
+ : ( { (TypeRuleIsPredictedByLA(1) && IdentifierRuleIsPredictedByLA(2)) }? localVariableDeclaration
+ | ( type identifier )=> localVariableDeclaration
+ | statementExpressionList
+ )?
+ { #forInitializer = #( [FOR_INIT, "FOR_INIT"], #forInitializer ); }
+ ;
+
+forCondition
+ : ( booleanExpression
+ )?
+ { #forCondition = #( [FOR_COND, "FOR_COND"], #forCondition ); }
+ ;
+
+forIterator
+ : ( statementExpressionList
+ )?
+ { #forIterator = #( [FOR_ITER, "FOR_ITER"], #forIterator ); }
+ ;
+
+statementExpressionList
+ : statementExpression ( COMMA! statementExpression )*
+ ;
+
+foreachStatement!
+ : f:FOREACH OPEN_PAREN! t:type id:identifier IN! e:expression CLOSE_PAREN! s:embeddedStatement
+ { ## = #( #f, #( [LOCVAR_DECLS], #t, #( [VAR_DECLARATOR], #id ) ), #e, #s ); }
+ ;
+
+jumpStatement
+ : breakStatement
+ | continueStatement
+ | gotoStatement
+ | returnStatement
+ | throwStatement
+ ;
+
+breakStatement
+ : BREAK^ SEMI!
+ ;
+
+continueStatement
+ : CONTINUE^ SEMI!
+ ;
+
+gotoStatement
+ : GOTO^
+ ( identifier SEMI!
+ | CASE constantExpression SEMI!
+ | DEFAULT SEMI!
+ )
+ ;
+
+returnStatement
+ : RETURN^ ( expression )? SEMI!
+ ;
+
+throwStatement
+ : THROW^ ( expression )? SEMI!
+ ;
+
+tryStatement
+ : TRY^ block
+ ( finallyClause
+ | catchClauses ( finallyClause )?
+ )
+ ;
+
+catchClauses
+ : ( options { greedy = true; } : specificCatchClause )+ ( generalCatchClause )?
+ | generalCatchClause
+ ;
+
+specificCatchClause!
+ : c:CATCH^ OPEN_PAREN! ctype:classType ( id:identifier )? CLOSE_PAREN! b:block
+ {
+ if (#id == null)
+ ## = #( #c, #b, #ctype );
+ else
+ ## = #( #c, #b, #( [LOCVAR_DECLS], #ctype, #( [VAR_DECLARATOR], #id ) ) );
+ }
+ ;
+
+generalCatchClause
+ : CATCH^ block
+ ;
+
+finallyClause
+ : FINALLY^ block
+ ;
+
+checkedStatement
+ : CHECKED^ block
+ ;
+
+uncheckedStatement
+ : UNCHECKED^ block
+ ;
+
+lockStatement
+ : LOCK^ OPEN_PAREN! expression CLOSE_PAREN! embeddedStatement
+ ;
+
+usingStatement
+ : USING^ OPEN_PAREN! resourceAcquisition CLOSE_PAREN! embeddedStatement
+ ;
+
+unsafeStatement
+ : UNSAFE^ block
+ ;
+
+resourceAcquisition
+ : { (TypeRuleIsPredictedByLA(1) && IdentifierRuleIsPredictedByLA(2)) }? localVariableDeclaration
+ | ( type identifier )=> localVariableDeclaration
+ | expression
+ ;
+
+compilationUnit
+ : justPreprocessorDirectives
+ usingDirectives
+ globalAttributes
+ namespaceMemberDeclarations
+ EOF!
+ {
+ ## = #( [COMPILATION_UNIT, "COMPILATION_UNIT"], ## );
+ }
+ ;
+
+usingDirectives
+ : ( options { greedy = true; }
+ : { !PPDirectiveIsPredictedByLA(1) }? usingDirective
+ | ( preprocessorDirective[CodeMaskEnums.UsingDirectives] )=>
+ preprocessorDirective[CodeMaskEnums.UsingDirectives]
+ )*
+ {
+ #usingDirectives = #( [USING_DIRECTIVES, "USING_DIRECTIVES"], ## );
+ }
+ ;
+
+usingDirective
+ : u:USING^
+ ( // UsingAliasDirective
+ { (IdentifierRuleIsPredictedByLA(1) && (LA(2) == ASSIGN)) }? identifier ASSIGN! qualifiedIdentifier SEMI!
+ {
+ #u.setType(USING_ALIAS_DIRECTIVE);
+ }
+ | // UsingNamespaceDirective
+ qualifiedIdentifier SEMI!
+ {
+ #u.setType(USING_NAMESPACE_DIRECTIVE);
+ }
+ )
+ ;
+
+namespaceMemberDeclarations
+ : ( options { greedy = true; }
+ : { PPDirectiveIsPredictedByLA(1) }? preprocessorDirective[CodeMaskEnums.NamespaceMemberDeclarations]
+ | namespaceMemberDeclaration
+ )*
+ ;
+
+namespaceMemberDeclaration
+ : namespaceDeclaration
+ | a:attributes! m:modifiers! typeDeclaration[#a, #m]
+ ;
+
+typeDeclaration [AST attribs, AST modifiers]
+ : classDeclaration[attribs, modifiers]
+ | structDeclaration[attribs, modifiers]
+ | interfaceDeclaration[attribs, modifiers]
+ | enumDeclaration[attribs, modifiers]
+ | delegateDeclaration[attribs, modifiers]
+ ;
+
+namespaceDeclaration
+ : NAMESPACE^ qualifiedIdentifier namespaceBody ( options { greedy = true; } : SEMI! )?
+ ;
+
+namespaceBody
+ : o:OPEN_CURLY^ { #o.setType(NAMESPACE_BODY); }
+ usingDirectives
+ namespaceMemberDeclarations
+ CLOSE_CURLY
+ ;
+
+modifiers
+ : ( modifier )*
+ { #modifiers = #( [MODIFIERS, "MODIFIERS"], #modifiers ); }
+ ;
+
+modifier
+ : ( ABSTRACT
+ | NEW
+ | OVERRIDE
+ | PUBLIC
+ | PROTECTED
+ | INTERNAL
+ | PRIVATE
+ | SEALED
+ | STATIC
+ | VIRTUAL
+ | EXTERN
+ | READONLY
+ | UNSAFE
+ | VOLATILE
+ )
+ ;
+
+
+//
+// A.2.6 Classes
+//
+
+classDeclaration! [AST attribs, AST modifiers]
+ : cl:CLASS id:identifier ba:classBase bo:classBody ( options { greedy = true; } : SEMI! )?
+ { ## = #( #cl, #attribs, #modifiers, #id, #ba, #bo ); }
+ ;
+
+classBase
+ : ( COLON! type ( COMMA! type )*
+ )?
+ { #classBase = #( [CLASS_BASE, "CLASS_BASE"], #classBase ); }
+ ;
+
+classBody
+ : o:OPEN_CURLY^ { #o.setType(TYPE_BODY); } classMemberDeclarations CLOSE_CURLY
+ ;
+
+classMemberDeclarations
+ : ( options { greedy = true; }
+ : { PPDirectiveIsPredictedByLA(1) }? preprocessorDirective[CodeMaskEnums.ClassMemberDeclarations]
+ | classMemberDeclaration
+ )*
+ { ## = #( [MEMBER_LIST, "MEMBER_LIST"], ## ); }
+ ;
+
+classMemberDeclaration
+ : a:attributes! m:modifiers!
+ ( destructorDeclaration[#a, #m]
+ | typeMemberDeclaration[#a, #m]
+ )
+ ;
+
+typeMemberDeclaration [AST attribs, AST modifiers]
+{
+ bool IsBinaryOp = false;
+ AST OpParams = null;
+}
+ :! // constantDeclaration
+ c:CONST t:type cdecl:constantDeclarators SEMI!
+ { ## = #( #c, #attribs, #modifiers, #t, #cdecl ); }
+
+ |! // eventDeclaration
+ ev:EVENT ev_typ:type
+ ( { IdentifierRuleIsPredictedByLA(1) && (LA(2)==ASSIGN || LA(2)==SEMI ||LA(2)==COMMA) }?
+ ev_v:variableDeclarators SEMI!
+ { ## = #( #ev, #attribs, #modifiers, #ev_typ, #ev_v ); }
+ | ev_id:qualifiedIdentifier OPEN_CURLY! ev_e:eventAccessorDeclarations ev_c:CLOSE_CURLY
+ { ## = #( #ev, #attribs, #modifiers, #ev_typ, #ev_id, #ev_e, #ev_c ); }
+ )
+
+ |! // constructorDeclaration
+ cd_id:identifier OPEN_PAREN! ( cd_fp:formalParameterList )? CLOSE_PAREN!
+ ( cd_ci:constructorInitializer )? cd_cb:constructorBody
+ {
+ if ( ((ASTNode) modifiers).GetFirstChildOfType(STATIC) == null )
+ {
+ ## = #( [CTOR_DECL, "CTOR_DECL"], #attribs, #modifiers, #cd_id, #cd_cb, #cd_fp, #cd_ci );
+ ##.CopyPositionFrom( #cd_id );
+ }
+ else
+ {
+ ## = #( [STATIC_CTOR_DECL, "STATIC_CTOR_DECL"], #attribs, #modifiers, #cd_id, #cd_cb );
+ ##.CopyPositionFrom( #cd_id );
+ }
+ }
+
+ |! // methodDeclaration
+ { ((LA(1) == VOID) && (LA(2) != STAR)) }?
+ mdv_rt:voidAsType mdv_mn:qualifiedIdentifier mdv_opn:OPEN_PAREN! ( mdv_fp:formalParameterList )? CLOSE_PAREN!
+ mdv_mb:methodBody
+ {
+ ## = #( [METHOD_DECL, "METHOD_DECL"], #attribs, #modifiers, #mdv_rt, #mdv_mn, #mdv_mb, #mdv_fp );
+ ##.CopyPositionFrom( #mdv_mn );
+ }
+
+ |! typ1:type
+ ( // unaryOperatorDeclarator or binaryOperatorDeclarator
+ OPERATOR! od_op:overloadableOperator OPEN_PAREN!
+ od_f1:fixedOperatorParameter
+ ( COMMA! od_f2:fixedOperatorParameter
+ { IsBinaryOp = true; }
+ )?
+ { OpParams = #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"], #od_f1, #od_f2 ); }
+ CLOSE_PAREN!
+ {
+ if (!IsBinaryOp)
+ {
+ if (#od_op.Type == PLUS)
+ #od_op.Type = UNARY_PLUS;
+ else if (#od_op.Type == MINUS)
+ #od_op.Type = UNARY_MINUS;
+
+ ## = #( [UNARY_OP_DECL, "UNARY_OP_DECL"], #attribs, #modifiers, #typ1, #od_op, OpParams );
+ }
+ else
+ {
+ ## = #( [BINARY_OP_DECL, "BINARY_OP_DECL"], #attribs, #modifiers, #typ1, #od_op, OpParams );
+ }
+ ##.CopyPositionFrom( #od_op );
+ }
+ od_body:operatorBody
+ { ##.addChildEx(#od_body); }
+ |
+ // fieldDeclaration
+ { IdentifierRuleIsPredictedByLA(1) && (LA(2)==ASSIGN || LA(2)==SEMI ||LA(2)==COMMA) }?
+ fd_v:variableDeclarators SEMI!
+ { ## = #( [FIELD_DECL, "FIELD_DECL"], #attribs, #modifiers, #typ1, #fd_v ); }
+ | qid1:qualifiedIdentifier
+
+ ( // propertyDeclaration
+ OPEN_CURLY!
+ pd_a:accessorDeclarations
+ pd_c:CLOSE_CURLY
+ {
+ ## = #( [PROPERTY_DECL, "PROPERTY_DECL"], #attribs, #modifiers, #typ1, #qid1, #pd_a, #pd_c );
+ ##.CopyPositionFrom( #qid1 );
+ }
+
+ | // methodDeclaration
+ OPEN_PAREN! ( md_fp:formalParameterList )? CLOSE_PAREN!
+ md_mb:methodBody
+ {
+ ## = #( [METHOD_DECL, "METHOD_DECL"], #attribs, #modifiers, #typ1, #qid1, #md_mb, #md_fp );
+ ##.CopyPositionFrom( #qid1 );
+ }
+
+ | // indexerDeclaration
+ DOT! ixq_t:THIS OPEN_BRACK! ixq_fp:formalParameterList CLOSE_BRACK!
+ OPEN_CURLY! ixq_adecls:accessorDeclarations ixq_c:CLOSE_CURLY
+ {
+ ## = #( [INDEXER_DECL, "INDEXER_DECL"], #attribs, #modifiers, #typ1, #qid1, #ixq_t, #ixq_fp, #ixq_adecls, #ixq_c );
+ ##.CopyPositionFrom( #ixq_t );
+ }
+ )
+
+ | // indexerDeclaration
+ ix_t:THIS OPEN_BRACK! ix_fp:formalParameterList CLOSE_BRACK!
+ OPEN_CURLY! ix_adecls:accessorDeclarations ix_c:CLOSE_CURLY
+ {
+ ## = #( [INDEXER_DECL, "INDEXER_DECL"], #attribs, #modifiers, #typ1, #qid1, #ix_t, #ix_fp, #ix_adecls, #ix_c );
+ ##.CopyPositionFrom( #ix_t );
+ }
+ )
+
+ |! imp:IMPLICIT OPERATOR! imp_typ1:type OPEN_PAREN! imp_params:oneOperatorParameter CLOSE_PAREN! // conversionOperatorDeclarator
+ {
+ ## = #( [CONV_OP_DECL, "CONV_OP_DECL"], #attribs, #modifiers, #imp, #imp_typ1, #imp_params );
+ ##.CopyPositionFrom( #imp );
+ }
+ imp_body:operatorBody
+ { ##.addChildEx(#imp_body); }
+
+ |! exp:EXPLICIT OPERATOR! exp_typ1:type OPEN_PAREN! exp_params:oneOperatorParameter CLOSE_PAREN! // conversionOperatorDeclarator
+ {
+ ## = #( [CONV_OP_DECL, "CONV_OP_DECL"], #attribs, #modifiers, #exp, #exp_typ1, #exp_params );
+ ##.CopyPositionFrom( #exp );
+ }
+ exp_body:operatorBody
+ { ##.addChildEx(#exp_body); }
+
+ | typeDeclaration[attribs, modifiers]
+ ;
+
+variableDeclarators
+ : variableDeclarator
+ (
+ COMMA! variableDeclarator
+ )*
+ ;
+
+variableDeclarator
+ : identifier ( ASSIGN! variableInitializer )?
+ {
+ ## = #( [VAR_DECLARATOR, "VAR_DECLARATOR"], ## );
+ }
+ ;
+
+variableInitializer
+ : ( expression
+ | arrayInitializer
+ | stackallocInitializer
+ )
+ { #variableInitializer = #( [VAR_INIT, "VAR_INIT"], #variableInitializer ); }
+ ;
+
+returnType
+ : { ((LA(1) == VOID) && (LA(2) != STAR)) }? voidAsType
+ | type
+ ;
+
+methodBody
+ : b:body
+ ;
+
+formalParameterList
+ : fa:attributes!
+ ( fixedParameters[#fa] ( COMMA! pa:attributes! parameterArray[#pa] )?
+ | parameterArray[#fa]
+ )
+ { ## = #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"], ## ); }
+ ;
+
+fixedParameters [AST attribs]
+ : fixedParameter[attribs] ( options { greedy = true; } : COMMA! a:attributes! fixedParameter[#a] )*
+ ;
+
+fixedParameter! [AST attribs]
+ : ( mod:parameterModifier )? typ:type id:identifier
+ {
+ ## = #( [PARAMETER_FIXED, "PARAMETER_FIXED"], #attribs, #typ, #id, #mod );
+ ##.CopyPositionFrom( #id );
+ }
+ ;
+
+parameterModifier
+ : REF
+ | OUT
+ ;
+
+parameterArray! [AST attribs]
+// : PARAMS! arrayType identifier
+ : p:PARAMS t:type id:identifier
+ { ## = #( #p, #attribs, #t, #id ); }
+ ;
+
+accessorDeclarations!
+ : a1:attributes
+ ( g1:getAccessorDeclaration[#a1] { ## = #g1; }
+ ( a2:attributes s1:setAccessorDeclaration[#a2] { #g1.setNextSibling(#s1);
+ #s1.setPreviousSibling(#g1); }
+ )?
+ | s2:setAccessorDeclaration[#a1] { ## = #s2; }
+ ( a3:attributes g2:getAccessorDeclaration[#a3] { #s2.setNextSibling(#g2);
+ #g2.setPreviousSibling(#s2); }
+ )?
+ )
+ ;
+
+getAccessorDeclaration! [AST attribs]
+ : g:"get" abody:accessorBody
+ { ## = #( #g, #attribs, #abody ); }
+ ;
+
+setAccessorDeclaration! [AST attribs]
+ : s:"set" abody:accessorBody
+ { ## = #( #s, #attribs, #abody ); }
+ ;
+
+accessorBody
+ : body
+ ;
+
+eventAccessorDeclarations!
+ : a1:attributes
+ ( add1:addAccessorDeclaration[#a1] a2:attributes rem1:removeAccessorDeclaration[#a2]
+ {
+ ## = #add1;
+ #add1.setNextSibling(#rem1);
+ #rem1.setPreviousSibling(#add1);
+ }
+ | rem2:removeAccessorDeclaration[#a1] a3:attributes add2:addAccessorDeclaration[#a3]
+ {
+ ## = #add2;
+ #add2.setNextSibling(#rem2);
+ #rem2.setPreviousSibling(#add2);
+ }
+ )
+ ;
+
+addAccessorDeclaration! [AST attribs]
+ : a:"add" b:block
+ { ## = #( #a, #attribs, #b ); }
+ ;
+
+removeAccessorDeclaration! [AST attribs]
+ : r:"remove" b:block
+ { ## = #( #r, #attribs, #b ); }
+ ;
+
+overloadableOperator
+ // Unary-or-Binary Operators
+ //
+ : PLUS
+ | MINUS
+
+ // Unary-only Operators
+ //
+ | LOG_NOT
+ | BIN_NOT
+ | INC
+ | DEC
+ | TRUE //"true"
+ | FALSE //"false"
+
+ // Binary-only Operators
+ //
+ | STAR
+ | DIV
+ | MOD
+ | BIN_AND
+ | BIN_OR
+ | BIN_XOR
+ | SHIFTL
+ | SHIFTR
+ | EQUAL
+ | NOT_EQUAL
+ | GTHAN
+ | LTHAN
+ | GTE
+ | LTE
+ ;
+
+oneOperatorParameter
+ : fixedOperatorParameter
+ { ## = #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"], ## ); }
+ ;
+
+fixedOperatorParameter!
+ : typ:type id:identifier
+ {
+ ## = #( [PARAMETER_FIXED, "PARAMETER_FIXED"], [ATTRIBUTE_SECTIONS, "ATTRIBUTE_SECTIONS"], #typ, #id );
+ ##.CopyPositionFrom( #id );
+ }
+ ;
+
+operatorBody
+ : b:body
+ ;
+
+constructorInitializer
+ : c:COLON!
+ ( BASE^ OPEN_PAREN! ( argumentList )? CLOSE_PAREN!
+ | THIS^ OPEN_PAREN! ( argumentList )? CLOSE_PAREN!
+ )
+ ;
+
+constructorBody
+ : b:body
+ ;
+
+destructorDeclaration! [AST attribs, AST modifiers]
+ : b:BIN_NOT! id:identifier OPEN_PAREN! CLOSE_PAREN! dbody:destructorBody
+ {
+ ## = #( [DTOR_DECL, "DTOR_DECL"], #attribs, #modifiers, #id, #dbody );
+ ##.CopyPositionFrom( #id );
+ }
+ ;
+
+destructorBody
+ : b:body
+ ;
+
+
+//
+// A.2.7 Structs
+//
+
+structDeclaration! [AST attribs, AST modifiers]
+ : st:STRUCT^ id:identifier si:structInterfaces sb:structBody ( options { greedy = true; } : SEMI! )?
+ { ## = #( #st, #attribs, #modifiers, #id, #si, #sb ); }
+ ;
+
+structInterfaces
+ : ( COLON! type ( COMMA! type )* )?
+ { ## = #( [STRUCT_BASE, "STRUCT_BASE"], #structInterfaces ); }
+ ;
+
+structBody
+ : o:OPEN_CURLY^ { #o.setType(TYPE_BODY); } structMemberDeclarations CLOSE_CURLY
+;
+
+structMemberDeclarations
+ : ( options { greedy = true; }
+ : { PPDirectiveIsPredictedByLA(1) }? preprocessorDirective[CodeMaskEnums.StructMemberDeclarations]
+ | structMemberDeclaration
+ )*
+ { ## = #( [MEMBER_LIST, "MEMBER_LIST"], ## ); }
+ ;
+
+structMemberDeclaration
+ : a:attributes! m:modifiers! typeMemberDeclaration[#a, #m]
+ ;
+
+
+//
+// A.2.8 Arrays
+//
+
+nonArrayType
+ : type
+ ;
+
+rankSpecifiers
+ : // CONFLICT: ANTLR says this about this line:
+ // ECMA-CSharp.g:1295: warning: nondeterminism upon
+ // ECMA-CSharp.g:1295: k==1:OPEN_BRACK
+ // ECMA-CSharp.g:1295: k==2:COMMA,CLOSE_BRACK
+ // ECMA-CSharp.g:1295: between alt 1 and exit branch of block
+ // !FIXME! -- if possible, can't see the problem right now.
+ ( options { greedy = true; } : rankSpecifier )*
+ //( rankSpecifier )+
+ { #rankSpecifiers = #( [ARRAY_RANKS, "ARRAY_RANKS"], #rankSpecifiers ); }
+ ;
+
+rankSpecifier
+ : o:OPEN_BRACK^ { #o.setType(ARRAY_RANK); } ( options { greedy = true; } : COMMA )* CLOSE_BRACK!
+ ;
+
+arrayInitializer
+ : o:OPEN_CURLY^ { #o.setType(ARRAY_INIT); }
+ ( CLOSE_CURLY
+ | variableInitializerList (COMMA!)? CLOSE_CURLY
+ )
+ ;
+
+variableInitializerList
+ : variableInitializer ( options { greedy = true; } : COMMA! variableInitializer )*
+ { #variableInitializerList = #( [VAR_INIT_LIST, "VAR_INIT_LIST"], #variableInitializerList ); }
+ ;
+
+
+//
+// A.2.9 Interfaces
+//
+
+interfaceDeclaration! [AST attribs, AST modifiers]
+ : iface:INTERFACE id:identifier ibase:interfaceBase ibody:interfaceBody ( options { greedy = true; } : SEMI! )?
+ { ## = #( #iface, #attribs, #modifiers, #id, #ibase, #ibody ); }
+ ;
+
+interfaceBase
+ : ( COLON! type ( COMMA! type )* )?
+ { ## = #( [INTERFACE_BASE, "INTERFACE_BASE"], #interfaceBase ); }
+ ;
+
+interfaceBody
+ : o:OPEN_CURLY^ { #o.setType(TYPE_BODY); } interfaceMemberDeclarations CLOSE_CURLY
+ ;
+
+interfaceMemberDeclarations
+ : ( options { greedy = true; }
+ : { PPDirectiveIsPredictedByLA(1) }? preprocessorDirective[CodeMaskEnums.InterfaceMemberDeclarations]
+ | interfaceMemberDeclaration
+ )*
+ { ## = #( [MEMBER_LIST, "MEMBER_LIST"], ## ); }
+ ;
+
+interfaceMemberDeclaration
+{
+ ASTNode modifiers = #[MODIFIERS, "MODIFIERS"];
+}
+ : attribs:attributes! ( n:NEW! { modifiers.addChildEx(#n); } )?
+ (! // interfaceMethodDeclaration
+ { ((LA(1) == VOID) && (LA(2) != STAR)) }?
+ im1_rt:voidAsType im1_id:identifier OPEN_PAREN! ( im1_fp:formalParameterList )? CLOSE_PAREN!
+ im1_s:SEMI { #im1_s.setType(EMPTY_STMT); }
+ {
+ ## = #( [METHOD_DECL, "METHOD_DECL"], #attribs, #modifiers, #im1_rt, #im1_id, #im1_s, #im1_fp );
+ ##.CopyPositionFrom( #im1_id );
+ }
+
+ |! typ1:type
+ ( // interfaceIndexerDeclaration
+ ix_t:THIS OPEN_BRACK! ix_fp:formalParameterList CLOSE_BRACK!
+ OPEN_CURLY! ix_acc:interfaceAccessors ix_c:CLOSE_CURLY
+ {
+ ## = #( [INDEXER_DECL, "INDEXER_DECL"], #attribs, #modifiers, #typ1, #ix_t, #ix_fp, #ix_acc, #ix_c );
+ ##.CopyPositionFrom( #ix_t );
+ }
+
+ | id1:identifier
+ ( // interfaceMethodDeclaration
+ OPEN_PAREN! ( im2_fp:formalParameterList )? CLOSE_PAREN! im2_s:SEMI { #im2_s.setType(EMPTY_STMT); }
+ {
+ ## = #( [METHOD_DECL, "METHOD_DECL"], #attribs, #modifiers, #typ1, #id1, #im2_s, #im2_fp );
+ ##.CopyPositionFrom( #id1 );
+ }
+
+ | // interfacePropertyDeclaration
+ OPEN_CURLY! ip_acc:interfaceAccessors ip_c:CLOSE_CURLY
+ {
+ ## = #( [PROPERTY_DECL, "PROPERTY_DECL"], #attribs, #modifiers, #typ1, #id1, #ip_acc, #ip_c );
+ ##.CopyPositionFrom( #id1 );
+ }
+ )
+ )
+
+ |! // interfaceEventDeclaration
+ ev:EVENT ev_typ:type ev_id:identifier SEMI!
+ { ## = #( #ev, #attribs, #modifiers, #ev_typ, #( [VAR_DECLARATOR, "VAR_DECLARATOR"], #ev_id ) ); }
+ )
+ ;
+
+
+interfaceAccessors!
+ : a1:attributes
+ ( g1:getAccessorDeclaration[#a1] { ## = #g1; }
+ ( a2:attributes s1:setAccessorDeclaration[#a2] { #g1.setNextSibling(#s1);
+ #s1.setPreviousSibling(#g1); }
+ )?
+ | s2:setAccessorDeclaration[#a1] { ## = #s2; }
+ ( a3:attributes g2:getAccessorDeclaration[#a3] { #s2.setNextSibling(#g2);
+ #g2.setPreviousSibling(#s2); }
+ )?
+ )
+ ;
+
+
+
+//
+// A.2.10 Enums
+//
+
+enumDeclaration! [AST attribs, AST modifiers]
+ : en:ENUM id:identifier ebase:enumBase ebody:enumBody ( options { greedy = true; } : SEMI! )?
+ { ## = #( #en, #attribs, #modifiers, #id, #ebase, #ebody ); }
+ ;
+
+enumBase!
+ {
+ bool empty = true;
+ }
+ : ( c:COLON { #c.setType(ENUM_BASE); empty = false; } t:integralType )?
+ {
+ if (empty)
+ {
+ ## = #[ENUM_BASE, "ENUM_BASE"];
+ }
+ else
+ {
+ ## = #( #c, #t );
+ }
+ }
+ ;
+
+enumBody
+ : o:OPEN_CURLY^ { #o.setType(TYPE_BODY); } ( enumMemberDeclarations ( COMMA! )? )? CLOSE_CURLY
+ ;
+
+enumMemberDeclarations
+ : a1:attributes! enumMemberDeclaration[#a1]
+ ( options { greedy = true; } :
+ COMMA! a2:attributes! enumMemberDeclaration[#a2]
+ )*
+ { ## = #( [MEMBER_LIST, "MEMBER_LIST"], ## ); }
+ ;
+
+enumMemberDeclaration! [AST attribs]
+ : id:identifier ( ASSIGN! cexpr:constantExpression )?
+ { ## = #( #id, #attribs, #cexpr ); }
+ ;
+
+
+//
+// A.2.11 Delegates
+//
+
+delegateDeclaration! [AST attribs, AST modifiers]
+ {
+ AST typ = null;
+ }
+ : dlg:DELEGATE
+ ( { ((LA(1) == VOID) && IdentifierRuleIsPredictedByLA(2)) }?
+ typ1:voidAsType { typ = #typ1; }
+ | typ2:type { typ = #typ2; }
+ )
+ id:identifier OPEN_PAREN! ( fp:formalParameterList )? CLOSE_PAREN! SEMI!
+ { ## = #( #dlg, #attribs, #modifiers, #typ, #id, #fp ); }
+ ;
+
+
+//
+// A.2.12 Attributes
+//
+
+globalAttributes
+ : ( options { greedy = true; }
+ : { !PPDirectiveIsPredictedByLA(1) }? globalAttributeSection
+ | ( preprocessorDirective[CodeMaskEnums.GlobalAttributes] )=>
+ preprocessorDirective[CodeMaskEnums.GlobalAttributes]
+ )*
+ { #globalAttributes = #( [GLOBAL_ATTRIBUTE_SECTIONS, "GLOBAL_ATTRIBUTE_SECTIONS"], #globalAttributes ); }
+ ;
+
+globalAttributeSection
+ : o:OPEN_BRACK^ { #o.setType(GLOBAL_ATTRIBUTE_SECTION); }
+ "assembly"! COLON! attributeList ( COMMA! )?
+ CLOSE_BRACK!
+ ;
+
+attributes
+ : ( options { greedy = true; }
+ : { !PPDirectiveIsPredictedByLA(1) }? attributeSection
+ | ( preprocessorDirective[CodeMaskEnums.Attributes] )=>
+ preprocessorDirective[CodeMaskEnums.Attributes]
+ )*
+ { #attributes = #( [ATTRIBUTE_SECTIONS, "ATTRIBUTE_SECTIONS"], #attributes ); }
+ ;
+
+attributeSection
+ : o:OPEN_BRACK^ { #o.setType(ATTRIBUTE_SECTION); }
+ ( attributeTarget COLON! )? attributeList ( COMMA! )?
+ CLOSE_BRACK!
+ ;
+
+attributeTarget
+ : "field"
+ | EVENT
+ | "method"
+ | "module"
+ | "param"
+ | "property"
+ | RETURN
+ | "type"
+ ;
+
+attributeList
+ : attribute ( options { greedy = true; } : COMMA! attribute )*
+ ;
+
+attribute
+ : ( predefinedTypeName | qualifiedIdentifier ) ( attributeArguments )?
+ { #attribute = #( [ATTRIBUTE, "ATTRIBUTE"], #attribute ); }
+ ;
+
+attributeArguments
+ : OPEN_PAREN!
+ ( CLOSE_PAREN!
+ | { (IdentifierRuleIsPredictedByLA(1) && (LA(2) == ASSIGN)) }? namedArgumentList CLOSE_PAREN!
+ | positionalArgumentList ( COMMA! namedArgumentList )? CLOSE_PAREN!
+ )
+ ;
+
+positionalArgumentList
+ : positionalArgument
+ ( // CONFLICT: ANTLR thinks this is ambiguous, because
+ // in rule 'attributeArguments' a COMMA also
+ // separates positionalArgument & namedArgument.
+ // !FIXME! if possible.
+ options { greedy = true; }
+ : COMMA! positionalArgument
+ )*
+ { #positionalArgumentList = #( [POSITIONAL_ARGLIST, "POSITIONAL_ARGLIST"], #positionalArgumentList ); }
+ ;
+
+positionalArgument
+ : attributeArgumentExpression
+ { #positionalArgument = #( [POSITIONAL_ARG, "POSITIONAL_ARG"], #positionalArgument ); }
+ ;
+
+namedArgumentList
+ : namedArgument ( COMMA! namedArgument )*
+ { #namedArgumentList = #( [NAMED_ARGLIST, "NAMED_ARGLIST"], #namedArgumentList ); }
+ ;
+
+namedArgument
+ : identifier ASSIGN! attributeArgumentExpression
+ { #namedArgument = #( [NAMED_ARG, "NAMED_ARG"], #namedArgument ); }
+ ;
+
+attributeArgumentExpression
+ : expression
+ { #attributeArgumentExpression = #( [ATTRIB_ARGUMENT_EXPR, "ATTRIB_ARGUMENT_EXPR"], #attributeArgumentExpression ); }
+ ;
+
+//
+// A.3 Grammar extensions for unsafe code
+//
+
+fixedStatement
+// : FIXED^ OPEN_PAREN! pointerType fixedPointerDeclarators CLOSE_PAREN! embeddedStatement
+ : FIXED^ OPEN_PAREN! type fixedPointerDeclarators CLOSE_PAREN! embeddedStatement
+ ;
+
+fixedPointerDeclarators
+ : fixedPointerDeclarator ( COMMA! fixedPointerDeclarator )*
+ ;
+
+fixedPointerDeclarator
+ : identifier ASSIGN! fixedPointerInitializer
+ { ## = #( [PTR_DECLARATOR, "PTR_DECLARATOR"], ## ); }
+ ;
+
+fixedPointerInitializer
+ : expression
+ { ## = #( [PTR_INIT, "PTR_INIT"], ## ); }
+ ;
+
+stackallocInitializer
+ : STACKALLOC^ qualifiedIdentifier OPEN_BRACK! expression CLOSE_BRACK!
+ ;
+
+//
+// A.1.10 Pre-processing directives
+//
+
+justPreprocessorDirectives
+ : ( options { greedy = true; }
+ : { SingleLinePPDirectiveIsPredictedByLA(1) }? singleLinePreprocessorDirective
+ | ( preprocessorDirective[CodeMaskEnums.PreprocessorDirectivesOnly] )=>
+ preprocessorDirective[CodeMaskEnums.PreprocessorDirectivesOnly]
+ )*
+ {
+ ## = #( [PP_DIRECTIVES, "PP_DIRECTIVES"], ## );
+ }
+ ;
+
+preprocessorDirective [CodeMaskEnums codeMask]
+ : PP_DEFINE^ PP_IDENT
+ | PP_UNDEFINE^ PP_IDENT
+ | lineDirective
+ | PP_ERROR^ ppMessage
+ | PP_WARNING^ ppMessage
+ | regionDirective[codeMask]
+ | conditionalDirective[codeMask]
+ ;
+
+singleLinePreprocessorDirective
+ : PP_DEFINE^ PP_IDENT
+ | PP_UNDEFINE^ PP_IDENT
+ | lineDirective
+ | PP_ERROR^ ppMessage
+ | PP_WARNING^ ppMessage
+ ;
+
+lineDirective
+ : PP_LINE^
+ ( DEFAULT
+ | PP_NUMBER ( PP_FILENAME )?
+ )
+ ;
+
+regionDirective! [CodeMaskEnums codeMask]
+ : reg:PP_REGION^ msg1:ppMessage { #reg.addChildEx(#msg1); }
+ drtv:directiveBlock[codeMask] { #reg.addChildEx(#drtv); }
+
+ endreg:PP_ENDREGION msg2:ppMessage {
+ #endreg.addChildEx(#msg2);
+ #reg.addChildEx(#endreg);
+ }
+ { ## = #reg; }
+ ;
+
+conditionalDirective! [CodeMaskEnums codeMask]
+ : hashIF:PP_COND_IF^ exprIF:preprocessExpression { #hashIF.addChildEx(#exprIF); }
+ drtvIF:directiveBlock[codeMask] { #hashIF.addChildEx(#drtvIF); }
+
+ ( hashELIF:PP_COND_ELIF exprELIF:preprocessExpression { #hashELIF.addChildEx(#exprELIF); }
+ drtvELIF:directiveBlock[codeMask] { #hashELIF.addChildEx(#drtvELIF); }
+ { #hashIF.addChildEx(#hashELIF); }
+ )*
+
+ ( hashELSE:PP_COND_ELSE
+ drtvELSE:directiveBlock[codeMask] { #hashELSE.addChildEx(#drtvELSE); }
+ { #hashIF.addChildEx(#hashELSE); }
+ )?
+
+ hashENDIF:PP_COND_ENDIF { #hashIF.addChildEx(#hashENDIF); }
+ { ## = #hashIF; }
+ ;
+
+directiveBlock [CodeMaskEnums codeMask]
+ :
+ ( options { greedy = true; }
+ : preprocessorDirective[codeMask]
+ | { NotExcluded(codeMask, CodeMaskEnums.UsingDirectives) }? usingDirective
+ | { NotExcluded(codeMask, CodeMaskEnums.GlobalAttributes) }? globalAttributeSection
+ | { NotExcluded(codeMask, CodeMaskEnums.Attributes) }? attributeSection
+ | { NotExcluded(codeMask, CodeMaskEnums.NamespaceMemberDeclarations) }? namespaceMemberDeclaration
+ | { NotExcluded(codeMask, CodeMaskEnums.ClassMemberDeclarations) }? classMemberDeclaration
+ | { NotExcluded(codeMask, CodeMaskEnums.StructMemberDeclarations) }? structMemberDeclaration
+ | { NotExcluded(codeMask, CodeMaskEnums.InterfaceMemberDeclarations) }? interfaceMemberDeclaration
+ | { NotExcluded(codeMask, CodeMaskEnums.Statements) }? statement
+ )*
+ { ## = #( [PP_BLOCK, "PP_BLOCK"], ## ); }
+ ;
+
+ppMessage
+ : ( PP_IDENT | PP_STRING | PP_FILENAME | PP_NUMBER )*
+ { ## = #( [PP_MESSAGE, "PP_MESSAGE"], ## ); }
+ ;
+
+
+//======================================
+// 14.2.1 Operator precedence and associativity
+//
+// The following table summarizes all PP operators in order of precedence from lowest to highest:
+//
+// PRECEDENCE SECTION CATEGORY OPERATORS
+// lowest ( 4) 14.11 Conditional OR ||
+// ( 3) 14.11 Conditional AND &&
+// ( 2) 14.9 Equality == !=
+// highest ( 1) 14.5 Primary (x) !x
+//
+// NOTE: In accordance with lessons gleaned from the "java.g" file supplied with ANTLR, I have
+// applied the following pattern to the rules for expressions:
+//
+// thisLevelExpression :
+// nextHigherPrecedenceExpression (OPERATOR nextHigherPrecedenceExpression)*
+//
+// which is a standard recursive definition for a parsing an expression.
+//
+preprocessExpression
+ : preprocessOrExpression
+ { #preprocessExpression = #( #[PP_EXPR,"PP_EXPR"], #preprocessExpression ); }
+ ;
+
+preprocessOrExpression
+ : preprocessAndExpression ( LOG_OR^ preprocessAndExpression )*
+ ;
+
+preprocessAndExpression
+ : preprocessEqualityExpression ( LOG_AND^ preprocessEqualityExpression )*
+ ;
+
+preprocessEqualityExpression
+ : preprocessPrimaryExpression ( ( EQUAL^ | NOT_EQUAL^ ) preprocessPrimaryExpression )*
+ ;
+
+preprocessPrimaryExpression
+ : ( id:keywordExceptTrueAndFalse { #id.setType(PP_IDENT); }
+ | PP_IDENT
+ | TRUE
+ | FALSE
+ | LOG_NOT^ preprocessPrimaryExpression
+ | o:OPEN_PAREN^ { #o.setType(PAREN_EXPR); } preprocessOrExpression CLOSE_PAREN!
+ )
+ ;
+
+keywordExceptTrueAndFalse
+ : ABSTRACT
+ | AS
+ | BASE
+ | BOOL
+ | BREAK
+ | BYTE
+ | CASE
+ | CATCH
+ | CHAR
+ | CHECKED | CLASS | CONST | CONTINUE | DECIMAL | DEFAULT | DELEGATE
+ | DO | DOUBLE | ELSE | ENUM | EVENT | EXPLICIT | EXTERN
+ | FINALLY | FIXED | FLOAT | FOR | FOREACH | GOTO | IF
+ | IMPLICIT | IN | INT | INTERFACE| INTERNAL | IS | LOCK
+ | LONG | NAMESPACE| NEW | NULL | OBJECT | OPERATOR | OUT
+ | OVERRIDE | PARAMS | PRIVATE | PROTECTED| PUBLIC | READONLY
+ | REF | RETURN | SBYTE | SEALED | SHORT | SIZEOF | STACKALLOC
+ | STATIC | STRING | STRUCT | SWITCH | THIS | THROW | TRY
+ | TYPEOF | UINT | ULONG | UNCHECKED| UNSAFE | USHORT | USING
+ | VIRTUAL | VOID | VOLATILE| WHILE
+ ;
+
+voidAsType!
+ : v:VOID
+ { ## = #( [TYPE, "TYPE"], #v, [STARS, "STARS"], [ARRAY_RANKS, "ARRAY_RANKS"] ); }
+ ;
diff --git a/CSharpTranslator/Translator/CSharpParser_LICENSE.TXT b/CSharpTranslator/Translator/CSharpParser_LICENSE.TXT
new file mode 100644
index 0000000..637856f
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpParser_LICENSE.TXT
@@ -0,0 +1,26 @@
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code MUST RETAIN the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form MUST REPRODUCE the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior WRITTEN permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/CSharpTranslator/Translator/CSharpParser_README.TXT b/CSharpTranslator/Translator/CSharpParser_README.TXT
new file mode 100644
index 0000000..0a2336f
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpParser_README.TXT
@@ -0,0 +1,139 @@
+kcsparse - a ECMA-334 C# Grammar Sample for ANTLR 2.7.7
+
+1 December, 2005
+
+Kunle Odutola : kunle UNDERSCORE odutola AT hotmail DOT com
+Micheal Jordan
+
+
+1. INTRODUCTION
+
+Congratulations, you have found 'kcsparse' - a nice YAC#GFA[*]!
+
+We hope you find 'kcsparse' delightful and useful even but, as per the
+license under which you may use it, this software is not guaranteed to
+work. See LICENSE.TXT for the full text of the license.
+
+----------------------------------------------------------------------
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+----------------------------------------------------------------------
+
+
+2. WHAT'S A YAC#GFA?
+
+Yet Another C# Grammar For ANTLR.
+
+This particular example is called 'kcsparse' and we hope you like it.
+
+It is probably a more complete and usable YAC#GFA than others. It is
+deliberately packaged in the style of the samples that are included with
+ANTLR itself (and may become one of the standard samples). In any event,
+it should just work out-of-the box for many C# source files.
+
+2.1 WHAT kcsparse CAN DO
+ - Parse C# 1.x source code including some with C# preprocessing directives.
+
+ - Build an AST from the C# source.
+
+ - Display the AST it builts from C# source.
+
+ - Unparse the AST (i.e. pretty prints the AST) back to source code.
+
+2.2 WHAT kcsparse CAN'T DO?
+ - Full parse and resolve of the input C# source code.
+ (kcsparse is NOT a C# front-end but, you can build one based on it)
+
+ - Parse all C# 1.x source code (esp. those with use of preprocessing directives).
+ (kcsparse is NOT a full C# 1.0 parser - it particularly fails on C# source
+ files where simply deleting (or commenting out) all preprocessing directives
+ results in illegal C# source but, you extend it to be)
+
+ - Parse C# source code with C# 2.0 or later features like generics.
+ (kcsparse is NOT a C# 2.0 parser but, you extend it to be)
+
+ - Compile C# source code to MSIL, bytecode or any other lanaguage
+ (kcsparse is NOT a C# translator/compiler but, you can build one based on it)
+
+ - Interpret C# source code
+ (kcsparse is NOT a C# interpreter but, you can build one based on it)
+
+ - Mow your lawns or fetch you a cold beer
+ (But we would like it to be!)
+
+
+3. WHAT'S IN THE PACK?
+
+Along with this with file, you should have received the following:
+
+ README.TXT This file
+ LICENSE.TXT Our license for this software
+ csharp_v1.build NAnt build file
+ CSharpLexer.g Main C# lexer grammar file
+ CSharpPreprocessorLexer.g C# lexer grammar file (used for preprocessor directives)
+ CSharpPreprocessorHooverLexer.g C# lexer grammar file (used for preprocessor directives)
+ CSharpLexerBase.g Common base for all C# lexer grammars
+ UnicodeLexerBase.g Common base for unicode-savvy lexer grammars
+ CSharpParser.g C# parser grammar file
+ CSharpPrettyPrinter.g C# pretty printer grammar file
+ CustomHiddenStreamToken.cs Custom IToken class
+ ASTNode.cs Custom AST node class
+ ASTNodeFactory.cs Custom ASTFactory class
+ CodeMaskEnums.cs Helper class
+ Main.cs Contains sample parsing application
+ csharp.flex Lexer grammar file for use with C# Flex
+ testfiles Directory containing test files to test C# parsing
+ AllCSharpConstructs.cs
+ Empty.cs
+ EmptyNamespace.cs
+ Testing.cs
+ Using.cs
+ UsingGlobalAttributes.cs
+ Tools
+ csflex.exe C# Flex executable
+ runtime.dll [supplied with C# Flex]
+
+
+4. USING kscparse
+
+The easiest way to use kcsparse is to unpack the files into a directory below
+the %ANTLR_HOME%/examples/csharp/ directory. This would "install" it just like
+any of the other ANTLR C# examples. Be sure to maintain the directory
+structure of the archive as shown above.
+
+Then, just type 'nant' (without the single quotes) to build and try kcsparse.
+This assumes that the ANTLR C# runtimes files have been compiled and are in the
+expected location.
+
+Once it is built, you can also run kcsparse directly yourself:
+ kcsparse -- parse the specified
+
+ kcsparse -flex -- parse the specified (uses flex lexer)
+
+ kcsparse -- parse all *.cs files in
+
+ kcsparse -flex -- parse all *.cs files in (uses flex lexer)
+
+ kcsparse -showtree -- parse all *.cs files in and
+ display the AST
+
+ kcsparse -prettyprint -- parse and unparse (pretty-print)
+ the AST to the console
+
+ kcsparse -flex -prettyprint -- parse and unparse (pretty-print)
+ the AST to the console (uses flex lexer)
+
+
+5. kscparse STATUS
+
+kcsparse still has some bugs. kcsparse is mostly complete but expect a few rough edges.
+
diff --git a/CSharpTranslator/Translator/CSharpPreprocessorHooverLexer.g b/CSharpTranslator/Translator/CSharpPreprocessorHooverLexer.g
new file mode 100644
index 0000000..143def1
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpPreprocessorHooverLexer.g
@@ -0,0 +1,243 @@
+header
+{
+ using System.IO;
+ using System.Globalization;
+
+ using TokenStreamSelector = antlr.TokenStreamSelector;
+}
+
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// A Preprocessor Lexer for the C# Language
+///
+///
+///
+///
+/// The Lexer defined below is designed to match and identify only tokens related to the
+/// handling of preprocessing directives for the C# language in the source text. It is
+/// designed to match the tokens that can occur after any of the following directives
+/// (on the same line):
+///
+/// -
+/// #region
+///
+/// -
+/// #endregion
+///
+/// -
+/// #error
+///
+/// -
+/// #warning
+///
+///
+///
+///
+///
+/// This preprocessing lexer is designed to work in tandem with the C# Lexer defined
+/// in the CSharpLexer.g file. In order words, the lexing of all the input not handled
+/// here is assumed to be handled by the other C# Lexer. This other C# Lexer may or may
+/// not be aware of C# preprocessing directives. The co-operation is implemented via
+/// ANTLR's TokenStreamSelector mechanism.
+///
+///
+///
+/// The operation of this C# preprocessing lexer is based on the "C# Language Specification"
+/// as documented in the ECMA-334 standard dated December 2001.
+///
+///
+///
+/// History
+///
+///
+///
+/// 05-Apr-2004 kunle Derived this Lexer from the CSharpPreprocessorLexer
+///
+///
+
+
+*/
+class CSharpPreprocessorHooverLexer extends CSharpLexerBase;
+
+options
+{
+ importVocab = CSharpLexerBase;
+ exportVocab = CSharpHoover;
+ charVocabulary = '\u0000'..'\uFFFE'; // All UNICODE characters except \uFFFF [and \u0000 to \u0002 used by ANTLR]
+ k = 3; // three characters of lookahead
+ testLiterals = false; // don't automatically test for literals
+ //defaultErrorHandler = true;
+ defaultErrorHandler = false;
+ codeGenMakeSwitchThreshold = 5; // Some optimizations
+ codeGenBitsetTestThreshold = 5;
+}
+
+{
+
+ ///
+ /// A for switching between this Lexer and the C#-only Lexer.
+ ///
+ private TokenStreamSelector selector_;
+
+ ///
+ /// A for switching between this Lexer and the C#-only Lexer.
+ ///
+ public TokenStreamSelector Selector
+ {
+ get { return selector_; }
+ set { selector_ = value; }
+ }
+
+ private FileInfo _fileinfo = null;
+
+ ///
+ /// Update _fileinfo member whenever filename changes.
+ ///
+ public override void setFilename(string f)
+ {
+ base.setFilename(f);
+ _fileinfo = new FileInfo(f);
+ }
+
+ ///
+ /// Ensures all tokens have access to the source file's details.
+ ///
+ protected override IToken makeToken(int t)
+ {
+ IToken result = base.makeToken(t);
+ CustomHiddenStreamToken customToken = result as CustomHiddenStreamToken;
+ if ( customToken != null )
+ {
+ customToken.File = _fileinfo;
+ }
+ return result;
+ }
+
+ public bool IsLetterCharacter(string s)
+ {
+ return ( (UnicodeCategory.LowercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Ll
+ (UnicodeCategory.ModifierLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lm
+ (UnicodeCategory.OtherLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lo
+ (UnicodeCategory.TitlecaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lt
+ (UnicodeCategory.UppercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lu
+ (UnicodeCategory.LetterNumber == Char.GetUnicodeCategory(s, 1)) //UNICODE class Nl
+ );
+ }
+
+ public bool IsIdentifierCharacter(string s)
+ {
+ return ( (UnicodeCategory.LowercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Ll
+ (UnicodeCategory.ModifierLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lm
+ (UnicodeCategory.OtherLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lo
+ (UnicodeCategory.TitlecaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lt
+ (UnicodeCategory.UppercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lu
+ (UnicodeCategory.LetterNumber == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Nl
+ (UnicodeCategory.NonSpacingMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mn
+ (UnicodeCategory.SpacingCombiningMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mc
+ (UnicodeCategory.DecimalDigitNumber == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Nd
+ (UnicodeCategory.ConnectorPunctuation == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Pc
+ (UnicodeCategory.Format == Char.GetUnicodeCategory(s, 1)) //UNICODE class Cf
+ );
+ }
+
+ public bool IsCombiningCharacter(string s)
+ {
+ return ( (UnicodeCategory.NonSpacingMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mn
+ (UnicodeCategory.SpacingCombiningMark == Char.GetUnicodeCategory(s, 1)) //UNICODE class Mc
+ );
+ }
+
+}
+
+
+//======================================
+// Start of Lexer Rules
+//======================================
+
+//======================================
+// Section A.1.3 Comments
+//
+SL_COMMENT
+ : '/'
+ ( '/' ( NOT_NEWLINE )*
+ // (NEWLINE)?
+ //
+ ( ('\r' ( options { generateAmbigWarnings=false; } : '\n' )?
+ | '\n'
+ | '\u2028'
+ | '\u2029'
+ )
+ { newline(); }
+ )?
+ { selector_.pop(); }
+ | ~( '/' | '\r' | '\n' | '\u2028' | '\u2029' ) ( NOT_NEWLINE )*
+ { $setType(PP_STRING); }
+ )
+ ;
+
+ //======================================
+// Section A.1.1 Line terminators
+//
+NEWLINE
+ : ( '\r' // MacOS-style newline
+ ( options { generateAmbigWarnings=false; }
+ : '\n' // DOS/Windows style newline
+ )?
+ | '\n' // UNIX-style newline
+ | '\u2028' // UNICODE line separator
+ | '\u2029' // UNICODE paragraph separator
+ )
+ { newline();
+ selector_.pop();
+ }
+ ;
+
+PP_STRING
+ : ~( '/' | '\r' | '\n' | '\u2028' | '\u2029' ) (NOT_NEWLINE)*
+ ;
+
+
+// undefine these inherited rules to remove a non-determinismn conflict with PP_STRING
+//
+protected LOG_NOT : ;
+protected LOG_AND : ;
+protected LOG_OR : ;
+protected EQUAL : ;
+protected NOT_EQUAL : ;
+protected QUOTE : ;
+protected OPEN_PAREN : ;
+protected CLOSE_PAREN : ;
+
diff --git a/CSharpTranslator/Translator/CSharpPreprocessorLexer.g b/CSharpTranslator/Translator/CSharpPreprocessorLexer.g
new file mode 100644
index 0000000..f74729b
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpPreprocessorLexer.g
@@ -0,0 +1,265 @@
+header
+{
+ using System.IO;
+ using System.Globalization;
+
+ using TokenStreamSelector = antlr.TokenStreamSelector;
+}
+
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// A Preprocessor Lexer for the C# Language
+///
+///
+///
+///
+/// The Lexer defined below is designed to match and identify only tokens related to the
+/// handling of preprocessing directives for the C# language in the source text. It is
+/// designed to match the tokens that can occur after any of the following directives
+/// (on the same line):
+///
+/// -
+/// #define
+///
+/// -
+/// #undefine
+///
+/// -
+/// #if
+///
+/// -
+/// #elif
+///
+/// -
+/// #else
+///
+/// -
+/// #endif
+///
+/// -
+/// #line
+///
+///
+///
+///
+///
+/// This preprocessing lexer is designed to work in tandem with the C# Lexer defined
+/// in the CSharpLexer.g file. In order words, the lexing of all the input not handled
+/// here is assumed to be handled by the other C# Lexer. This other C# Lexer may or may
+/// not be aware of C# preprocessing directives. The co-operation is implemented via
+/// ANTLR's TokenStreamSelector mechanism.
+///
+///
+///
+/// The operation of this C# preprocessing lexer is based on the "C# Language Specification"
+/// as documented in the ECMA-334 standard dated December 2001.
+///
+///
+///
+/// History
+///
+///
+///
+/// 26-Jan-2003 kunle Derived this Lexer from the original combined grammar
+/// 28-Jan-2003 kunle Retired this Lexer in favour of single-lexer approach
+/// 25-Feb-2003 kunle Revived this Lexer after issues with single-lexer approach
+///
+///
+
+*/
+class CSharpPreprocessorLexer extends CSharpLexerBase;
+
+options
+{
+ importVocab = CSharpLexerBase;
+ exportVocab = CSharpPreprocess;
+ charVocabulary = '\u0000'..'\uFFFE'; // All UNICODE characters except \uFFFF [and \u0000 to \u0002 used by ANTLR]
+ k = 3; // three characters of lookahead
+ testLiterals = false; // don't automatically test for literals
+ //defaultErrorHandler = true;
+ defaultErrorHandler = false;
+ codeGenMakeSwitchThreshold = 5; // Some optimizations
+ codeGenBitsetTestThreshold = 5;
+}
+
+{
+
+ ///
+ /// A for switching between this Lexer and the C#-only Lexer.
+ ///
+ private TokenStreamSelector selector_;
+
+ ///
+ /// A for switching between this Lexer and the C#-only Lexer.
+ ///
+ public TokenStreamSelector Selector
+ {
+ get { return selector_; }
+ set { selector_ = value; }
+ }
+
+ private FileInfo _fileinfo = null;
+
+ ///
+ /// Update _fileinfo member whenever filename changes.
+ ///
+ public override void setFilename(string f)
+ {
+ base.setFilename(f);
+ _fileinfo = new FileInfo(f);
+ }
+
+ ///
+ /// Ensures all tokens have access to the source file's details.
+ ///
+ protected override IToken makeToken(int t)
+ {
+ IToken result = base.makeToken(t);
+ CustomHiddenStreamToken customToken = result as CustomHiddenStreamToken;
+ if ( customToken != null )
+ {
+ customToken.File = _fileinfo;
+ }
+ return result;
+ }
+
+ public bool IsLetterCharacter(string s)
+ {
+ return ( (UnicodeCategory.LowercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Ll
+ (UnicodeCategory.ModifierLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lm
+ (UnicodeCategory.OtherLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lo
+ (UnicodeCategory.TitlecaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lt
+ (UnicodeCategory.UppercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lu
+ (UnicodeCategory.LetterNumber == Char.GetUnicodeCategory(s, 1)) //UNICODE class Nl
+ );
+ }
+
+ public bool IsIdentifierCharacter(string s)
+ {
+ return ( (UnicodeCategory.LowercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Ll
+ (UnicodeCategory.ModifierLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lm
+ (UnicodeCategory.OtherLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lo
+ (UnicodeCategory.TitlecaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lt
+ (UnicodeCategory.UppercaseLetter == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Lu
+ (UnicodeCategory.LetterNumber == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Nl
+ (UnicodeCategory.NonSpacingMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mn
+ (UnicodeCategory.SpacingCombiningMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mc
+ (UnicodeCategory.DecimalDigitNumber == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Nd
+ (UnicodeCategory.ConnectorPunctuation == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Pc
+ (UnicodeCategory.Format == Char.GetUnicodeCategory(s, 1)) //UNICODE class Cf
+ );
+ }
+
+ public bool IsCombiningCharacter(string s)
+ {
+ return ( (UnicodeCategory.NonSpacingMark == Char.GetUnicodeCategory(s, 1)) || //UNICODE class Mn
+ (UnicodeCategory.SpacingCombiningMark == Char.GetUnicodeCategory(s, 1)) //UNICODE class Mc
+ );
+ }
+
+}
+
+
+//======================================
+// Start of Lexer Rules
+//======================================
+
+PP_IDENT
+ options { testLiterals = true; }
+ : ( '_'
+ | LETTER_CHARACTER
+ | { IsLetterCharacter(eseq.getText()) }? eseq:UNICODE_ESCAPE_SEQUENCE
+ )
+ ( LETTER_CHARACTER
+ | DECIMAL_DIGIT_CHARACTER
+ | CONNECTING_CHARACTER
+ | COMBINING_CHARACTER
+ | FORMATTING_CHARACTER
+ | { IsIdentifierCharacter(eseq2.getText()) }? eseq2:UNICODE_ESCAPE_SEQUENCE
+ )*
+ ;
+
+PP_FILENAME
+ : '"'
+ ( ~( '"' | '\r' | '\n' | '\u2028' | '\u2029' ) )*
+ '"'
+ ;
+
+PP_NUMBER
+ : (DECIMAL_DIGIT)+
+ ;
+
+
+//======================================
+// Section A.1.3 Comments
+//
+SL_COMMENT
+ : "//" ( NOT_NEWLINE )*
+ // (NEWLINE)?
+ //
+ ( ('\r' ( options { generateAmbigWarnings=false; } : '\n' )?
+ | '\n'
+ | '\u2028'
+ | '\u2029'
+ )
+ { newline(); }
+ )?
+ { selector_.pop(); }
+ ;
+
+ //======================================
+// Section A.1.1 Line terminators
+//
+NEWLINE
+ : ( '\r' // MacOS-style newline
+ ( options { generateAmbigWarnings=false; }
+ : '\n' // DOS/Windows style newline
+ )?
+ | '\n' // UNIX-style newline
+ | '\u2028' // UNICODE line separator
+ | '\u2029' // UNICODE paragraph separator
+ )
+ { newline();
+ selector_.pop();
+ }
+ ;
+
+
+WHITESPACE
+ : (NON_NEWLINE_WHITESPACE)+
+ ;
+
+
diff --git a/CSharpTranslator/Translator/CSharpTranslator.g b/CSharpTranslator/Translator/CSharpTranslator.g
new file mode 100644
index 0000000..0d7a6bf
--- /dev/null
+++ b/CSharpTranslator/Translator/CSharpTranslator.g
@@ -0,0 +1,1888 @@
+header
+{
+ using System.IO;
+ using System.Text;
+ using System.Collections;
+ using System.Globalization;
+ using ASTFrame = antlr.debug.misc.ASTFrame;
+}
+
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// An AST Printer (or un-parser) that prints the source code that a tree represents.
+///
+///
+///
+///
+/// The default behaviour of this PrettyPrinter is to print out the AST and generate
+/// source code that is as close to the original as is possible.
+///
+///
+/// This behaviour can be overridden by supplying an
+/// object that contains the settings for a custom formatting code style.
+///
+///
+/// The TreeParser defined below is designed for the AST created by CSharpParser.
+/// See the file "CSharpParser.g" for the details of that Parser.
+///
+///
+///
+/// History
+///
+///
+///
+/// 05-Jun-2003 kunle Created file.
+///
+///
+///
+
+
+*/
+
+
+/* keving:
+**
+** Notes
+**
+** -- It is important that we don't share parts of the AST (e.g., when we copy the namespace
+** into each compilation unit). BE CAREFUL TO CREATE A FRESH COPY INSTEAD OF SHARING.
+**
+** -- We throw out nearly anything embedded in Pre Processing Directives, can we, should we do better?
+**
+*/
+class CSharpTranslator extends TreeParser("RusticiSoftware.Translator.JavaTreeParser");
+
+options
+{
+ importVocab = CSharpJava;
+ buildAST = true;
+ ASTLabelType = "ASTNode";
+ defaultErrorHandler = true;
+}
+
+//=============================================================================
+// Start of CODE
+//=============================================================================
+
+{
+ // counter so that dummy Catchall Vars will be unique
+ private int dummyCatchallCtr = 0;
+
+ // throw 'holes' for the exception being caught in the current context
+ private ArrayList currExHoles = new ArrayList();
+
+ private Hashtable defines = new Hashtable();
+
+ private bool NotExcluded(CodeMaskEnums codeMask, CodeMaskEnums construct)
+ {
+ return ((codeMask & construct) != 0 );
+ }
+
+
+ // If this is the Main method then return a wrapper 'main' method, else return null
+ private AST WrapMainMethod(AST mods, AST typ, AST id, AST ps)
+ {
+ if (id.getText() != "Main")
+ // Quick exit
+ return null;
+ else
+ {
+ // Check return type is int or void
+ // typ == #( TYPE (identifier | predefinedType | VOID) #(ARRAY_RANKS (rankSpecifier)*) )
+ AST rettyp = typ.getFirstChild();
+ if (typ.getFirstChild().getNextSibling().getFirstChild() == null &&
+ (rettyp.Type == VOID || rettyp.Type == INT))
+ {
+ // return type ok, check params is empty or string[], looking for
+ // #( FORMAL_PARAMETER_LIST #( PARAMETER_FIXED type[w] identifier[w]) )
+ if (ps.getNumberOfChildren() < 2)
+ {
+ AST arg = ps.getFirstChild();
+ if (arg == null ||
+ // Arguments type is string
+ (arg.getFirstChild().getFirstChild().Type == STRING &&
+ // and it is a single array
+ arg.getFirstChild().getFirstChild().getNextSibling().getFirstChild().Type == ARRAY_RANK &&
+ arg.getFirstChild().getFirstChild().getNextSibling().getFirstChild().getFirstChild() == null))
+ {
+ // Finally, is it public and static?
+ // keving: According to $3.1 the Main method does not have to be public
+ AST m = mods.getFirstChild();
+ bool stat = false;
+ // mbool pub = false;
+ while (m != null)
+ {
+ if (m.Type == STATIC)
+ stat = true;
+ //if (m.Type == PUBLIC)
+ //pub = true;
+ m = m.getNextSibling();
+ }
+ if (stat)// && pub)
+ {
+ // Found a Main method, construct wrapper
+ // public static void main(String[] args)
+ ASTNode ret = #( [METHOD_DECL],
+ #( [MODIFIERS], [PUBLIC, "public"], [STATIC, "static"] ),
+ #( [TYPE], [VOID, "void"], #( [ARRAY_RANKS] ) ),
+ [IDENTIFIER, "main"],
+ #( [FORMAL_PARAMETER_LIST],
+ #( [PARAMETER_FIXED],
+ #( [TYPE], [STRING, "String"], #( [ARRAY_RANKS] , [ARRAY_RANK] ) ),
+ [IDENTIFIER, "args"]
+ )
+ ), #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ) );
+ // The body varies depending on return type of Main and arguments
+ AST mainArgs = null;
+ string innerMain = this.ClassInProcess + ".Main(${args})";
+ if (arg != null)
+ mainArgs = #( [EXPR], [IDENTIFIER, "args"] );
+ AST mainCall = #( [EXPR],
+ #( [JAVAWRAPPER],
+ #([IDENTIFIER, innerMain]),
+ #([IDENTIFIER, "${args}"]), #([EXPR_LIST], mainArgs)
+ )
+ );
+ AST wrappedMainCall = null;
+ if (rettyp.Type == INT)
+ wrappedMainCall = #( [EXPR],
+ #( [JAVAWRAPPER],
+ #( [IDENTIFIER, "System.exit(${call})"] ),
+ #([IDENTIFIER, "${call}"]), #( [EXPR_LIST], mainCall )
+ ) );
+ else
+ wrappedMainCall = mainCall;
+ ret.addChild( #([BLOCK], #([EXPR_STMT], wrappedMainCall)) );
+ return ret;
+ }
+ else
+ return null;
+ }
+ else
+ return null;
+ }
+ else
+ return null;
+ }
+ else
+ return null;
+ }
+ }
+
+
+ private ASTNode SmotherCheckedExceptions(ASTNode b, String reThrow)
+ {
+
+
+ ASTNode retAST = #( [TRY, "try"],
+ astFactory.dupTree(b),
+ #( [CATCH, "catch"],
+ #( [FIELD_DECL, "FIELD_DECL"],
+ #( [MODIFIERS, "MODIFIERS"] ),
+ #( [TYPE, "type"],
+ #( [JAVAWRAPPER], [IDENTIFIER, "Exception"] ),
+ #( [ARRAY_RANKS] )
+ ),
+ #( [VAR_DECLARATOR, "VAR_DECLARATOR"],
+ #( [IDENTIFIER, "__e"] )
+ ) ),
+ #( [BLOCK],
+ #( [THROW, "throw"],
+ #([EXPR], #( [OBJ_CREATE_EXPR, "new"],
+ #( [TYPE], #([JAVAWRAPPER], [IDENTIFIER, reThrow]), #([ARRAY_RANKS]) ),
+ #( [EXPR_LIST], #([EXPR], #([IDENTIFIER, "__e"]) ) ) ) )
+ ))
+ ) );
+ return retAST;
+
+ }
+
+ // Strip one rank from array type t
+ // t = #( TYPE baseType #( ARRAY_RANKS #( ARRAY_RANK COMMA* )* )
+ // NOTE: Updates t in place
+ private ASTNode StripOneRank(ASTNode t)
+ {
+ ASTNode baseType = (ASTNode) t.getFirstChild();
+ ASTNode arrayRanks = (ASTNode) baseType.getNextSibling();
+ ASTNode rank = (ASTNode) arrayRanks.getFirstChild();
+
+ if (rank == null)
+ {
+ Console.Error.WriteLine("ERROR: Expected array type");
+ }
+ else
+ {
+ if (rank.getNextSibling() == null)
+ {
+ // Only one rank
+ arrayRanks.setFirstChild(null);
+ }
+ else
+ {
+ // Remove final rank (we could just remove the first, but ....)
+ ASTNode prev = rank; // Init to 1st element
+ rank = (ASTNode) rank.getNextSibling(); // Init to 2nd element
+ while (rank.getNextSibling() != null) // Will always succeed first time through
+ {
+ prev = rank;
+ rank = (ASTNode) rank.getNextSibling();
+ }
+ prev.setNextSibling(null);
+ }
+ }
+ return t;
+ }
+}
+
+//=============================================================================
+// Start of RULES
+//=============================================================================
+
+
+// A C# compilation unit is a file containing a mixture of namespaces, classes,
+// instances, structs, etc. We do some jiggery pokery here to convert this to a list
+// of Java compilation units, each of which contains appropriate package names, imports,
+// and a single class / instance declaration. Each of these Java compilation units will be
+// written out to a separate java source file by the driver program.
+compilationUnit! [Object w]
+ : #( COMPILATION_UNIT
+ justPreprocessorDirectives[w]
+ uses:usingDirectives[w]
+ globalAttributes[w]
+ cus:namespaceMemberDeclarations[w, #uses, null /* initial namespace */]
+ )
+ { ## = #( [MULTI_COMPILATION_UNITS], cus) ; }
+ ;
+
+usingDirectives [Object w]
+ : #( USING_DIRECTIVES
+ ( preprocessorDirective[w, CodeMaskEnums.UsingDirectives]
+ | usingDirective[w]
+ )*
+ )
+ ;
+
+usingDirective [Object w]
+ : #( USING_NAMESPACE_DIRECTIVE
+ pn:qualifiedIdentifier[w]
+ )
+ | #( USING_ALIAS_DIRECTIVE
+ alias:identifier[w]
+ pna:qualifiedIdentifier[w]
+ )
+ ;
+
+namespaceMemberDeclarations [Object w, ASTNode uses, ASTNode pns]
+ : ( namespaceMemberDeclaration[w, uses, pns]
+ | preprocessorDirective[w, CodeMaskEnums.NamespaceMemberDeclarations]
+ )*
+ ;
+
+namespaceMemberDeclaration [Object w, ASTNode uses, ASTNode ns]
+ : namespaceDeclaration[w, uses, ns]
+ | typeDeclaration[w, uses, ns, true]
+ ;
+
+typeDeclaration! [Object w, ASTNode uses, ASTNode ns, bool topLevel]
+ { if (topLevel) {
+ // reset java imports for each compilation unit
+ initialize();
+ };
+ }
+ : cla:classDeclaration[w]
+ { if (topLevel) {
+ ## = #( [COMPILATION_UNIT],
+ #( [PACKAGE_DEF, "package"], astFactory.dupTree(ns)),
+ astFactory.dupTree(uses), GetImports(),
+ #cla );
+ }
+ else {
+ ## = #cla ;
+ }; }
+ | str:structDeclaration[w]
+ { if (topLevel) {
+ ## = #( [COMPILATION_UNIT],
+ #( [PACKAGE_DEF, "package"], astFactory.dupTree(ns)),
+ astFactory.dupTree(uses), GetImports(),
+ #str );
+ } else {
+ ## = #str;
+ }; }
+ | iface:interfaceDeclaration[w]
+ { if (topLevel) {
+ ## = #( [COMPILATION_UNIT],
+ #( [PACKAGE_DEF, "package"], astFactory.dupTree(ns)),
+ astFactory.dupTree(uses), GetImports(),
+ #iface );
+ } else {
+ ## = #iface;
+ }; }
+ | enm:enumDeclaration[w]
+ { if (topLevel) {
+ ## = #( [COMPILATION_UNIT],
+ #( [PACKAGE_DEF, "package"], astFactory.dupTree(ns)),
+ astFactory.dupTree(uses), GetImports(),
+ #enm );
+ } else {
+ ## = #enm;
+ }; }
+ | delegateDeclaration[w]
+ ;
+
+namespaceDeclaration! [Object w, ASTNode uses, ASTNode ns]
+ { ASTNode add_ns = null;
+ ASTNode new_ns = null, tmp = null;
+ }
+ : #( NAMESPACE
+ m_ns:qualifiedIdentifier[w] { if (ns == null)
+ // easy, replace with new namespace
+ add_ns = #m_ns;
+ else {
+ if (ns.Type == IDENTIFIER)
+ // A single identifier, just prepend it to existing namespace
+ add_ns = #( [DOT], #( [IDENTIFIER, ns.getText()] ), #m_ns);
+ else {
+ // A dotted identifier list, build new qualified id
+ tmp = (ASTNode) ns.getFirstChild();
+ new_ns = #( [DOT], #( [IDENTIFIER, tmp.getText()] ) );
+ add_ns = new_ns; // remember head of new namespace
+ //new_ns = (ASTNode) add_ns.getFirstChild();
+ tmp = (ASTNode) tmp.getNextSibling();
+ while (tmp.Type == DOT) {
+ tmp = (ASTNode) tmp.getFirstChild();
+ new_ns.addChildEx( #( [DOT], #( [IDENTIFIER, tmp.getText()] ) ) );
+ new_ns = (ASTNode) new_ns.getFirstChild().getNextSibling(); // Newly added child
+ tmp = (ASTNode) tmp.getNextSibling();
+ }
+ new_ns.addChildEx(#( [DOT], #( [IDENTIFIER, tmp.getText()] ), #m_ns));
+ }
+ } ; }
+ bdy:namespaceBody[w, uses, add_ns]
+ ) { ## = #bdy; }
+ ;
+
+namespaceBody! [Object w, ASTNode uses, ASTNode ns]
+ { ASTNode uses_plus = null; }
+ : #( NAMESPACE_BODY m_uses:usingDirectives[w]
+ { uses_plus = (ASTNode) astFactory.dupTree(uses);
+ uses_plus.addChild(#m_uses.getFirstChild());
+ }
+ mem:namespaceMemberDeclarations[w, uses_plus, ns]
+ CLOSE_CURLY
+ ) { ## = #mem; }
+ ;
+
+classModifiers [Object w]
+ : modifiers[w] // indirection for any special processing
+ ;
+
+modifiers [Object w] // TODO: If there are no access modifiers then make it private (check)
+ : #( MODIFIERS ( modifier[w] )* )
+ ;
+
+modifier [Object w]
+ : ( ABSTRACT // tick
+ |/*nw:*/NEW
+ |/*ov:*/OVERRIDE
+ | PUBLIC // tick
+ | PROTECTED // tick
+ |! INTERNAL {## = null;} // equate internal to package level. This is default in Java.
+ | PRIVATE // tick
+ |! SEALED { ## = #( [FINAL, "final"] ); } // tick
+ |/*st:*/STATIC
+ |/*vi:*/VIRTUAL
+ |/*ext:*/EXTERN
+ |! READONLY { ## = #( [FINAL, "final"] ); } // tick
+ |/*un:*/UNSAFE
+ |/*vo:*/VOLATILE
+ )
+ ;
+
+
+typeName [Object w]
+ : predefinedType[w]
+ | qualifiedIdentifier[w]
+ ;
+
+classTypeName [Object w]
+ : qualifiedIdentifier[w]
+ |! OBJECT { ## = #( [DOT, "DOT"], #( [IDENTIFIER, "System"] ), #( [IDENTIFIER, "Object"] ) ); }
+ |/*str:*/STRING
+ ;
+
+identifier [Object w]
+ : id:IDENTIFIER { fixBrokenIds(##); }
+ ;
+
+qualifiedIdentifier [Object w]
+ : ( identifier[w]
+ | #(DOT identifier[w] qualifiedIdentifier[w] )
+ )
+ ;
+
+
+//
+// A.2.2 Types
+//
+
+type [Object w]
+ : #( TYPE
+ ( qualifiedIdentifier[w]
+ | predefinedType[w]
+ | VOID
+ )
+ pointerSpecifier[w]! // TODO: Bleargh. We don't support pointer types
+ rankSpecifiers[w]
+ )
+ ;
+
+pointerSpecifier [Object w]
+ : #( STARS
+ ( STAR
+ )*
+ )
+ ;
+
+classType [Object w]
+ : qualifiedIdentifier[w]
+ |! OBJECT { ## = #( [DOT, "DOT"], #( [IDENTIFIER, "System"] ), #( [IDENTIFIER, "Object"] ) ); }
+ |/*str:*/STRING
+ ;
+
+interfaceType [Object w]
+ : qualifiedIdentifier[w]
+ ;
+
+delegateType [Object w]
+ : qualifiedIdentifier[w] // typeName
+ ;
+
+/*
+pointerType
+ : unmanagedType STAR
+ | VOID STAR
+ ;
+*/
+unmanagedType [Object w]
+ : qualifiedIdentifier[w] // typeName
+ ;
+
+//
+// A.2.3 Variables
+//
+
+variableReference [Object w]
+ : expression[w]
+ ;
+
+//
+// A.2.4 Expressions
+//
+
+argumentList [Object w] // Simplify by making it an EXPR_LIST
+ : #( ARG_LIST { ##.setType(EXPR_LIST); ##.setText("EXPR_LIST"); } argument[w] ( argument[w] )*
+ )
+ ;
+
+argument [Object w]
+ : expression[w]
+ |! #(/*r:*/REF variableReference[w] )
+ |! #(/*o:*/OUT variableReference[w] )
+ ;
+
+constantExpression [Object w]
+ : expression[w]
+ ;
+
+booleanExpression [Object w]
+ : expression[w]
+ ;
+
+expressionList [Object w]
+ : #( EXPR_LIST expression[w] ( expression[w] )*
+ )
+ ;
+
+expression [Object w]
+ : #( EXPR expr[w] )
+ ;
+
+expr [Object w]
+ // assignmentExpression
+ //
+ : #( ASSIGN expr[w] expr[w] )
+ // We expand
+ |! #( PLUS_ASSIGN pal:expr[w] par:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#pal), #( [PLUS, "+"], astFactory.dupTree(#pal), astFactory.dupTree(#par) ) ); } )
+ |! #( MINUS_ASSIGN mal:expr[w] mar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#mal), #( [MINUS, "-"], astFactory.dupTree(#mal), astFactory.dupTree(#mar) ) ); } )
+ |! #( STAR_ASSIGN sal:expr[w] sar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#sal), #( [STAR, "*"], astFactory.dupTree(#sal), astFactory.dupTree(#sar) ) ); } )
+ |! #( DIV_ASSIGN dal:expr[w] dar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#dal), #( [DIV, "/"], astFactory.dupTree(#dal), astFactory.dupTree(#dar) ) ); } )
+ |! #( MOD_ASSIGN moal:expr[w] moar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#moal), #( [MOD, "%"], astFactory.dupTree(#moal), astFactory.dupTree(#moar) ) ); } )
+ |! #( BIN_AND_ASSIGN baal:expr[w] baar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#baal), #( [BIN_AND, "&"], astFactory.dupTree(#baal), astFactory.dupTree(#baar) ) ); } )
+ |! #( BIN_OR_ASSIGN boal:expr[w] boar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#boal), #( [BIN_OR, "|"], astFactory.dupTree(#boal), astFactory.dupTree(#boar) ) ); } )
+ |! #( BIN_XOR_ASSIGN bxal:expr[w] bxar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#bxal), #( [BIN_XOR, "^"], astFactory.dupTree(#bxal), astFactory.dupTree(#bxar) ) ); } )
+ |! #( SHIFTL_ASSIGN slal:expr[w] slar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#slal), #( [SHIFTL, "<<"], astFactory.dupTree(#slal), astFactory.dupTree(#slar) ) ); } )
+ |! #( SHIFTR_ASSIGN sral:expr[w] srar:expr[w] { ## = #( [ASSIGN, "="], astFactory.dupTree(#sral), #( [SHIFTR, ">>"], astFactory.dupTree(#sral), astFactory.dupTree(#srar) ) ); } )
+ // conditionalExpression
+ //
+ | #( QUESTION expr[w] expr[w] expr[w] )
+
+ // conditional-XXX-Expressions
+ //
+ | #( LOG_OR expr[w] expr[w] )
+ | #( LOG_AND expr[w] expr[w] )
+
+ // bitwise-XXX-Expressions
+ //
+ | #( BIN_OR expr[w] expr[w] )
+ | #( BIN_XOR expr[w] expr[w] )
+ | #( BIN_AND expr[w] expr[w] )
+
+ // equalityExpression
+ //
+ | #( EQUAL expr[w] expr[w] )
+ | #( NOT_EQUAL expr[w] expr[w] )
+
+ // relationalExpression
+ //
+ | #( LTHAN expr[w] expr[w] )
+ | #( GTHAN expr[w] expr[w] )
+ | #( LTE expr[w] expr[w] )
+ | #( GTE expr[w] expr[w] )
+ | #( IS expr[w] type[w] ) {##.setType(INSTANCEOF); ##.setText("instanceof"); }
+ |! #( AS e:expr[w] t:type[w] ) { ASTNode e1 = (ASTNode) astFactory.dupTree(#e);
+ ASTNode e2 = (ASTNode) astFactory.dupTree(#e);
+ ASTNode t1 = (ASTNode) astFactory.dupTree(#t);
+ ASTNode t2 = (ASTNode) astFactory.dupTree(#t);
+ ASTNode t3 = (ASTNode) astFactory.dupTree(#t);
+ ## = #( [QUESTION, "?"], #( [INSTANCEOF, "instanceof"], e1, t1),
+ #( [CAST_EXPR], t2, e2),
+ #( [CAST_EXPR], t3, #( [NULL, "null"]))); }
+ // shiftExpression
+ //
+ | #( SHIFTL expr[w] expr[w] )
+ | #( SHIFTR expr[w] expr[w] )
+
+ // additiveExpression
+ //
+ | #( PLUS expr[w] expr[w] )
+ | #( MINUS expr[w] expr[w] )
+ // multiplicativeExpression
+ //
+ | #( STAR expr[w] expr[w] )
+ | #( DIV expr[w] expr[w] )
+ | #( MOD expr[w] expr[w] )
+ | unaryExpression[w]
+ ;
+
+unaryExpression [Object w]
+ : #( CAST_EXPR type[w] expr[w] )
+ | #( INC expr[w] )
+ | #( DEC expr[w] )
+ | #( UNARY_PLUS expr[w] )
+ | #( UNARY_MINUS expr[w] )
+ | #( LOG_NOT expr[w] )
+ | #( BIN_NOT expr[w] )
+ | #(/*p:*/PTR_INDIRECTION_EXPR expr[w] )
+ | #(/*a:*/ADDRESS_OF_EXPR expr[w] )
+ | primaryExpression[w]
+ ;
+
+primaryExpression [Object w]
+ : #( // invocationExpression ::= primaryExpression OPEN_PAREN ( argumentList )? CLOSE_PAREN
+ INVOCATION_EXPR primaryExpression[w]
+ (a:argumentList[w])? { if (a == null) ##.addChild( #( [EXPR_LIST, "EXPR_LIST"] ) ); }
+ )
+ | #( // elementAccess ::= primaryNoArrayCreationExpression OPEN_BRACK expressionList CLOSE_BRACK
+ /*e:*/ELEMENT_ACCESS_EXPR primaryExpression[w]
+ expressionList[w]
+ )
+ | #( // pointerElementAccess ::= primaryNoArrayCreationExpression OPEN_BRACK expression CLOSE_BRACK
+ /*p:*/PTR_ELEMENT_ACCESS_EXPR primaryExpression[w]
+ expressionList[w]
+ )
+ | #( // memberAccess ::= primaryExpression DOT identifier
+ MEMBER_ACCESS_EXPR
+ ( type[w]
+ | primaryExpression[w]
+ )
+ identifier[w]
+ )
+ | // pointerMemberAccess
+ #(/*d:*/DEREF primaryExpression[w] identifier[w] )
+ | // postIncrementExpression
+ #( POST_INC_EXPR primaryExpression[w] )
+ | // postDecrementExpression
+ #( POST_DEC_EXPR primaryExpression[w] )
+ | basicPrimaryExpression[w]
+ ;
+
+basicPrimaryExpression [Object w]
+ : literal[w]
+ | identifier[w] // simpleName
+ |! // parenthesizedExpression
+ //
+ #( PAREN_EXPR e:expr[w] ) { ## = #e; }
+ | THIS
+ |! #( BASE
+ ( i:identifier[w] { ## = #( [MEMBER_ACCESS_EXPR, "MEMBER_ACCESS_EXPR"],
+ [SUPER, "super"], #i); }
+ | expressionList[w] // TODO:access to base class indexer ...
+ )
+ )
+ | newExpression[w]
+ |! // typeofExpression rewrite to call .class
+ //
+ #( TYPEOF t:type[w] )
+ {
+ string classCall = typeToString(#t, false) + ".class"; ## = #( [JAVAWRAPPER], [IDENTIFIER, classCall] );
+ ##.DotNetType = new TypeRep();
+ ##.DotNetType.TypeName = "System.Type"; /* ugly, will fill this type in on the next pass when we have correct type context */
+ }
+// |! // typeofExpression rewrite to call Class.forName("type name");
+// //
+// #( TYPEOF t:type[w] ) {## = #( [INVOCATION_EXPR, "INVOCATION_EXPR"],
+// #( [JAVAWRAPPER],
+// #( [IDENTIFIER, "Class.forName"] )
+// ),
+// #( [EXPR_LIST, "EXPR_LIST"],
+// #( [EXPR, "EXPR"],
+// [STRING_LITERAL, typeToString(#t)] ) )
+// );
+// addImport("RusticiSoftware.JavaSupport.ClassSupport"); // To get a forName that converts checked exception to unchecked
+// }
+ | #(/*s:*/SIZEOF unmanagedType[w] )
+ |! #(/*c:*/CHECKED ce:expression[w] ) { ## = (ASTNode) #ce.getFirstChild(); } // keving: TODO RusticiSoftware.ScormContentPlayer.Logic\Types\ScormTimeSpan.cs uses checked expressions
+ |! #(/*u:*/UNCHECKED ue:expression[w] ) { ## = (ASTNode) #ue.getFirstChild(); }
+ ;
+
+newExpression [Object w]
+ // objectCreationExpression
+ //
+ : #(OBJ_CREATE_EXPR type[w] (al:argumentList[w])? ) { if (#al == null) ##.addChild( #([EXPR_LIST, "EXPR_LIST"]) ); }
+ // delegateCreationExpression
+ //
+ | #(/*dl:*/DLG_CREATE_EXPR type[w] argumentList[w] )
+ // arrayCreationExpression
+ //
+ | #( ARRAY_CREATE_EXPR
+ type[w] // nonArrayType ( rankSpecifiers )?
+ ( arrayInitializer[w]
+ | expressionList[w]
+ rankSpecifiers[w] ( arrayInitializer[w] )?
+ )
+ )
+ ;
+
+literal [Object w]
+ : TRUE
+ | FALSE
+ |! i:INT_LITERAL { long val = 0;
+ if (#i.getText().TrimStart().StartsWith("0x"))
+ val = Int64.Parse(#i.getText().TrimStart().Substring(2), NumberStyles.AllowHexSpecifier);
+ else
+ val = Int64.Parse(#i.getText());
+ if (val > Int32.MaxValue)
+ ## = #( [LONG_LITERAL, #i.getText()] );
+ else
+ ## = (ASTNode) astFactory.dupTree(#i);
+ }
+ |! u:UINT_LITERAL { ulong val = 0;
+ if (#i.getText().TrimStart().StartsWith("0x"))
+ val = UInt64.Parse(#i.getText().TrimStart().Substring(2), NumberStyles.AllowHexSpecifier);
+ else
+ val = UInt64.Parse(#i.getText());
+ if (val > UInt32.MaxValue)
+ ## = #( [ULONG_LITERAL, #u.getText()] );
+ else
+ ## = (ASTNode) astFactory.dupTree(#u);
+ }
+ | LONG_LITERAL
+ | ULONG_LITERAL
+ | DECIMAL_LITERAL
+ | FLOAT_LITERAL
+ | DOUBLE_LITERAL
+ | CHAR_LITERAL
+ | s:STRING_LITERAL { String slit = #s.getText();
+ if (slit.StartsWith("@\"")) {
+ // escape string for Java
+ ##.setText("\"" + escapeJavaString(slit.Substring(2,slit.Length - 2)) + "\"");
+ }
+ // TODO: Check that C# escaped strings are Java escaped
+ ; }
+ | NULL
+ ;
+
+predefinedType [Object w]
+ : BOOL {##.setText("boolean");}
+ | BYTE {##.setText("byte");} // TODO: Not available
+ | CHAR
+ | DECIMAL {##.setText("Decimal");} // TODO: Not available
+ | DOUBLE
+ | FLOAT
+ | INT
+ | LONG
+ | OBJECT { ##.setText("Object"); }
+ | SBYTE { ##.setText("byte"); }
+ | SHORT
+ | STRING {##.setText("String");}
+ | UINT {##.setText("int");} // TODO: Not available
+ | ULONG {##.setText("long");} // TODO: Not available
+ | USHORT {##.setText("short");} // TODO: Not available
+ ;
+
+
+//
+// A.2.5 Statements
+//
+
+statement [Object w]
+ : #(/*l:*/LABEL_STMT identifier[w] statement[w]
+ )
+ | localVariableDeclaration[w]
+ | localConstantDeclaration[w]
+ | embeddedStatement[w]
+ | preprocessorDirective[w, CodeMaskEnums.Statements]
+ ;
+
+embeddedStatement [Object w]
+ : block[w]
+ | EMPTY_STMT
+ | #( EXPR_STMT statementExpression[w] )
+ | #(IF
+ expression[w] embeddedStatement[w]
+ ( #(ELSE
+ embeddedStatement[w]
+ )
+ )?
+ )
+ |! // TODO: If the scrutinee has string type then we must convert to if-then-else :-(
+ { ASTNode ret = #( [SWITCH, "switch"] ); }
+ #( SWITCH
+ se:expression[w] { ret.addChild(#se); }
+ #( OPEN_CURLY
+ ( ss:switchSection[w] { ret.addChild(#ss); } )*
+ CLOSE_CURLY
+ )
+ ) { ## = ret; }
+ | #( FOR
+ #( FOR_INIT ( ( localVariableDeclaration[w] | ( statementExpression[w] )+ ) )? )
+
+ #( FOR_COND ( booleanExpression[w] )? )
+
+ #( FOR_ITER ( ( statementExpression[w] )+ )? )
+
+ embeddedStatement[w]
+ )
+ | #( WHILE booleanExpression[w] embeddedStatement[w] )
+ | #(/*doStmt:*/DO
+ embeddedStatement[w] booleanExpression[w]
+ )
+ | #( FOREACH localVariableDeclaration[w] expression[w] embeddedStatement[w] )
+ | BREAK
+ | CONTINUE
+ | #(/*gto:*/GOTO
+ ( identifier[w]
+ |/*cse:*/CASE constantExpression[w]
+ |/*dfl:*/DEFAULT
+ )
+
+ )
+ | #(/*rtn:*/RETURN ( expression[w] )? )
+ | { bool throwExp = false; } #( THROW ( expression[w] { throwExp = true; } )? )
+ { if (!throwExp)
+ {
+ ASTNode hole = #( [IDENTIFIER, "ThrowHole"] );
+ ##.addChild( #( [EXPR], hole ) );
+ // To be fixed up later in catchClause when we know what the exception var is
+ currExHoles.Add(hole);
+ };
+ }
+ | tryStatement[w]
+ | #(/*checkedStmt:*/CHECKED block[w]
+ )
+ | #(/**/UNCHECKED block[w]
+ )
+ | #(/*lockStmt:*/LOCK
+ expression[w] embeddedStatement[w]
+ )
+ |!
+ // rewrite 'using ( | ) slist' to
+ // ; try finally { if ( != null) .Dispose(); ... .Dispose(); }
+ { ASTNode decsAST = null; }
+ #(USING
+ rs:resourceAcquisition[w]
+ { // Collect all the resources from #rs that need to be Disposed of.
+ ArrayList resources = new ArrayList();
+ if (#rs.Type == EXPR)
+ {
+ // A single resource indicated by an expression (EXPR e)
+ resources.Add(astFactory.dupTree(#rs.getFirstChild()));
+ }
+ else if (#rs.Type == FIELD_DECL)
+ {
+ // Collect all the variable names so that they can be disposed of later
+ ASTNode varsAST = (ASTNode) #rs.getFirstChild().getNextSibling().getNextSibling();
+ while (varsAST != null)
+ {
+ // (VAR_DECLARATOR identifier (init?))
+ resources.Add(astFactory.dupTree(varsAST.getFirstChild()));
+ varsAST = (ASTNode) varsAST.getNextSibling();
+ }
+ // Emit variable declarations
+ decsAST = (ASTNode) astFactory.dupTree(#rs);
+ }
+ else
+ {
+ Console.Error.WriteLine("ERROR -- (using): unexpected resource specification: ");
+ }
+ }
+ slist:embeddedStatement[w]
+ )
+ {
+ // Build up the try .. finally statement
+ ASTNode tryAST = null;
+ ASTNode fBlockAST = #( [BLOCK] );
+ if (slist.Type == BLOCK)
+ tryAST = #( [TRY, "try"], astFactory.dupTree(#slist));
+ else
+ tryAST = #( [TRY, "try"], #( [BLOCK], astFactory.dupTree(#slist) ) );
+ foreach (ASTNode expr in resources)
+ {
+ fBlockAST.addChild( #( [IF, "if"],
+ #( [EXPR], #( [NOT_EQUAL, "!="], astFactory.dupTree(expr), #( [NULL, "null"] ) ) ),
+ #( [BLOCK], #( [EXPR_STMT], #( [EXPR], #( [INVOCATION_EXPR], #( [MEMBER_ACCESS_EXPR], expr, [IDENTIFIER, "Dispose"] ), #( [EXPR_LIST] ) ) ) ) )
+ ) );
+ }
+ tryAST.addChild( #( [FINALLY, "finally"], fBlockAST ) );
+ ## = (decsAST == null ? tryAST : #( null, decsAST, tryAST) );
+ }
+ | #(/*unsafeStmt:*/UNSAFE
+ block[w]
+ )
+ | // fixedStatement
+ #(/*fixedStmt:*/FIXED
+ type[w]
+ fixedPointerDeclarator[w] ( fixedPointerDeclarator[w] )*
+
+ embeddedStatement[w]
+ )
+ ;
+
+body [Object w]
+ : block[w]
+ | EMPTY_STMT
+ ;
+
+block [Object w]
+ : #(BLOCK
+ ( statement[w] )*
+ CLOSE_CURLY!
+ )
+ ;
+
+statementList[Object w]
+ : #( STMT_LIST ( statement[w] )+ )
+ ;
+
+localVariableDeclaration! [Object w]
+ : #( LOCVAR_DECLS t:type[w]
+ { ## = #( [FIELD_DECL, "FIELD_DECL"],
+ #( [MODIFIERS, "MODIFIERS"] ),
+ #t); }
+ (d:localVariableDeclarator[w] { ##.addChild(#d); } )+
+ )
+ ;
+
+localVariableDeclarator [Object w]
+ : #( VAR_DECLARATOR identifier[w] (localVariableInit[w])?
+ )
+ ;
+
+localVariableInit [Object w]
+ :
+ #( LOCVAR_INIT
+ ( expression[w]
+ | arrayInitializer[w]
+ )
+ ) { ##.setType(VAR_INIT); ##.setText("VAR_INIT"); }
+ ;
+
+
+localConstantDeclaration! [Object w] // rewrite to field_decl with final modifier
+ : #(LOCAL_CONST t:type[w]
+ { ## = #( [FIELD_DECL, "FIELD_DECL"],
+ #( [MODIFIERS, "MODIFIERS"],
+ #( [STATIC, "static"] ),
+ #( [FINAL, "final"] )
+ ), #t ); }
+ (
+ d:constantDeclarator[w] { ##.addChild(#d); }
+ )+
+ )
+ ;
+
+constantDeclarator! [Object w]
+ : #(CONST_DECLARATOR i:identifier[w] c:constantExpression[w]
+ ) {## = #( [VAR_DECLARATOR, "VAR_DECLARATOR"], #i, #( [VAR_INIT, "VAR_INIT"], #c) ); }
+ ;
+
+statementExpression! [Object w]
+ : e:expr[w] { ## = #([EXPR], #e); }
+ ;
+
+switchSection[Object w]
+ : #( SWITCH_SECTION switchLabels[w] statementList[w] )
+ ;
+
+switchLabels [Object w]
+ : #( SWITCH_LABELS
+ ( ( #(CASE expression[w] )
+ | DEFAULT
+ )
+
+ )+
+ ) { ## = (ASTNode) ##.getFirstChild(); }
+ ;
+
+tryStatement [Object w]
+ : #( TRY
+ block[w]
+ ( finallyClause[w]
+ | catchClauses[w] ( finallyClause[w] )?
+ )
+ )
+ ;
+
+catchClauses [Object w]
+ : (
+ catchClause[w]
+ )+
+ ;
+
+catchClause [Object w]
+ { bool guards = false;
+ ASTNode ret = #( [CATCH, "catch"] );
+ ArrayList saveExHoles = currExHoles;
+ currExHoles = new ArrayList();
+ string exVarStr = "";
+ }
+ :! #( CATCH b:block[w]
+ ( t:type[w] {
+ exVarStr = "__dummyCatchallEx" + dummyCatchallCtr;
+ dummyCatchallCtr++;
+ ret.addChild( #( [FIELD_DECL, "FIELD_DECL"],
+ #( [MODIFIERS, "MODIFIERS"] ),
+ #( [TYPE, "type"],
+ astFactory.dupTree(#t.getFirstChild()),
+ ( [ARRAY_RANKS] ) ),
+ #( [VAR_DECLARATOR, "VAR_DECLARATOR"],
+ #( [IDENTIFIER, exVarStr] )
+ ) ) );
+ guards = true; }
+ | l:localVariableDeclaration[w] { ret.addChild(#l);
+ exVarStr = #l.getFirstChild().getNextSibling().getNextSibling().getFirstChild().getText();
+ guards = true; }
+ )*
+ ) { if (!guards) {
+ exVarStr = "__dummyCatchallEx" + dummyCatchallCtr;
+ dummyCatchallCtr++;
+ ret.addChild(#( [FIELD_DECL, "FIELD_DECL"],
+ #( [MODIFIERS, "MODIFIERS"] ),
+ #( [TYPE, "type"],
+ #( [JAVAWRAPPER], [IDENTIFIER, "Exception"] ),
+ #( [ARRAY_RANKS] ) ),
+ #( [VAR_DECLARATOR, "VAR_DECLARATOR"],
+ #( [IDENTIFIER, exVarStr] )
+ ) ));
+ }
+ // Fill in any holes
+ foreach (ASTNode idAST in currExHoles)
+ {
+ idAST.setText(exVarStr);
+ }
+ currExHoles = saveExHoles;
+ ret.addChild(#b);
+ ## = ret; }
+ ;
+
+finallyClause [Object w]
+ : #( FINALLY
+ block[w]
+ )
+ ;
+
+resourceAcquisition[Object w]
+ : localVariableDeclaration[w]
+ | expression[w]
+ ;
+
+//
+// A.2.6 Classes
+//
+
+classDeclaration [Object w]
+ {string saveClass = this.ClassInProcess; }
+ :! #( CLASS
+ attributes[w] // todo: attributes
+ mod:classModifiers[w]
+ id:identifier[w] { this.ClassInProcess = #id.getText(); }
+ ext:classBase[w]
+ #(TYPE_BODY mem:classMemberDeclarations[w] CLOSE_CURLY )
+ )
+ {
+ ASTNode firstParent = (ASTNode) #ext.getFirstChild();
+ if ( firstParent != null && firstParent.getNextSibling() == null && idToString(firstParent) == "System.Attribute" ) {
+ // A class that only inherits System.Attribute. Must be a an attribute definition.
+ // TODO: We don't handle annotations with parameters yet.
+ ## = #( [ANNOTATION], #mod, #id, #( [MEMBER_LIST]) );
+ }
+ else {
+ ## = #( [CLASS], #mod, #id, #ext, #mem );
+ }
+ this.ClassInProcess = saveClass;
+ }
+ ;
+
+classBase [Object w]
+ :! { ## = #( [CLASS_BASE] ); }
+ #( CLASS_BASE
+ (
+ t:type[w]! { ##.addChild( astFactory.dupTree(#t.getFirstChild()) ); } // Extract identifier from type info
+ )*
+ )
+ ;
+
+classMemberDeclarations [Object w]
+ : #( MEMBER_LIST
+ ( classMemberDeclaration [w]
+ | preprocessorDirective[w, CodeMaskEnums.ClassMemberDeclarations]
+ )*
+ )
+ ;
+
+classMemberDeclaration [Object w]
+ : ( destructorDeclaration[w]
+ | typeMemberDeclaration[w]
+ )
+ ;
+
+typeMemberDeclaration [Object w]
+ : ( constantDeclaration[w]
+ | eventDeclaration[w]
+ | constructorDeclaration[w]
+ | staticConstructorDeclaration[w]
+ | propertyDeclaration[w]
+ | methodDeclaration[w]
+ | indexerDeclaration[w]
+ | fieldDeclaration[w]
+ | operatorDeclaration[w]
+ | typeDeclaration[w, null, null, false]
+ )
+ ;
+
+constantDeclaration! [Object w]
+ : #(CONST attributes[w]! m:modifiers[w] t:type[w]
+ { #m.addChild( #( null, [STATIC, "static"], [FINAL, "final"] ));
+ ## = #( [FIELD_DECL, "FIELD_DECL"], #m, #t );
+ }
+ ( c:constantDeclarator[w] { ##.addChild(#c); } )+
+ )
+ ;
+
+fieldDeclaration [Object w]
+ : #( FIELD_DECL attributes[w]! modifiers[w] type[w]
+ ( variableDeclarator[w] )+
+
+ )
+ ;
+
+variableDeclarator [Object w]
+ : #( VAR_DECLARATOR identifier[w]
+ ( variableInitializer[w] )?
+ )
+ ;
+
+variableInitializer [Object w]
+ : #( VAR_INIT
+ ( expression[w]
+ | arrayInitializer[w]
+ | stackallocInitializer[w]
+ )
+ )
+ ;
+
+methodDeclaration! [Object w]
+ : #( METHOD_DECL a:attributes[w] m:modifiers[w] t:type[w] i:qualifiedIdentifier[w]
+ b:methodBody[w]
+ ( p:formalParameterList[w] )?
+ ) {
+ if (#p == null) #p = #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"] );
+
+ if (#i.getText() == "ToString" && #p.getFirstChild() == null)
+ {
+ //TODO: keving: Note: Should generalize this, we also should trap equals, clone etc.
+ ## = #( [METHOD_DECL], #m, astFactory.dupTree(#t), #( [IDENTIFIER, "toString"] ), #p, #( [BLOCK], SmotherCheckedExceptions(#b, "RuntimeException") ));
+ }
+ else
+ {
+ ## = #( [METHOD_DECL], #m, #t, #i, #p, #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ), #b);
+ ##.setNextSibling(WrapMainMethod(#m, #t, #i, #p)); // Adds wrapper if this is Main
+ }
+ }
+ ;
+
+memberName [Object w]
+ : qualifiedIdentifier[w] // interfaceType^ DOT! identifier
+// | identifier
+ ;
+
+methodBody [Object w]
+ : body[w]
+ ;
+
+formalParameterList [Object w]
+ : #( FORMAL_PARAMETER_LIST
+ ( fixedParameters[w] ( parameterArray[w] )?
+ | parameterArray[w]
+ )
+ )
+ ;
+
+fixedParameters [Object w]
+ : fixedParameter[w] ( fixedParameter[w] )*
+ ;
+
+fixedParameter [Object w]
+ : #( PARAMETER_FIXED attributes[w]!
+ type[w] identifier[w]
+ ( parameterModifier[w] )?
+ )
+ ;
+
+parameterModifier [Object w]
+ : REF
+ | OUT
+ ;
+
+// In C# public void fred(int[]... arg)
+//
+// In Java public void fred(int... arg)
+//
+// So we strip the rank off here and the netTranslator has to
+// make sure arg is an array.
+parameterArray! [Object w]
+ : #(PARAMS attributes[w]! t:type[w] i:identifier[w] { ## = #( [PARAMS], StripOneRank(#t), #i); }
+ )
+ ;
+
+propertyDeclaration! [Object w]
+ : #( PROPERTY_DECL attributes[w] m:modifiers[w] t:type[w] id:qualifiedIdentifier[w]
+ a:accessorDeclarations[w] CLOSE_CURLY
+ ) { ## = #( [IDENTIFIER, "dummy"] );
+ // Take each getter/setter
+ ASTNode gs = #a;
+
+ while ( gs != null ) {
+ if (gs.getText() == "get") {
+ AST new_id = astFactory.dupTree(#id);
+ prependStringToId(new_id, "get");
+ ASTNode myGetter = #( [METHOD_DECL, "METHOD_DECL"],
+ astFactory.dupTree(#m),
+ astFactory.dupTree(#t),
+ new_id,
+ #( [FORMAL_PARAMETER_LIST] ), #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ),
+ astFactory.dupTree(gs.getFirstChild()) );
+ if (## == null)
+ ## = myGetter;
+ else
+ ##.addChild(myGetter);
+ } else {
+ if (gs.getText() == "set") {
+ AST new_id = astFactory.dupTree(#id);
+ prependStringToId(new_id, "set");
+ ASTNode mySetter = #( [METHOD_DECL, "METHOD_DECL"],
+ astFactory.dupTree(#m),
+ #( [TYPE, "TYPE"],
+ #( [VOID, "void"] ),
+ #( [ARRAY_RANKS] ) ),
+ new_id,
+ #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"],
+ #( [PARAMETER_FIXED, "PARAMETER_FIXED"],
+ astFactory.dupTree(#t),
+ [IDENTIFIER, "value"] )), #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ),
+ astFactory.dupTree(gs.getFirstChild()) );
+ if (## == null)
+ ## = mySetter;
+ else
+ ##.addChild(mySetter);
+ }
+ }
+ gs = (ASTNode) gs.getNextSibling();
+ }
+ ## = (ASTNode) ##.getFirstChild();
+ }
+ ;
+
+accessorDeclarations [Object w]
+ : ( accessorDeclaration[w]
+ )*
+ ;
+
+accessorDeclaration [Object w]
+ : #( "get" attributes[w]! accessorBody[w] )
+ | #( "set" attributes[w]! accessorBody[w] )
+ ;
+
+
+accessorBody [Object w]
+ : block[w]
+ | EMPTY_STMT
+ ;
+
+eventDeclaration [Object w]
+ : #(/*evt:*/EVENT attributes[w] modifiers[w] type[w]
+ ( qualifiedIdentifier[w]
+ eventAccessorDeclarations[w]/*cly:*/CLOSE_CURLY
+ | variableDeclarator[w] ( variableDeclarator[w] )*
+
+ )
+ )
+ ;
+
+eventAccessorDeclarations [Object w]
+ : addAccessorDeclaration[w] removeAccessorDeclaration[w]
+ | removeAccessorDeclaration[w] addAccessorDeclaration[w]
+ ;
+
+addAccessorDeclaration [Object w]
+ : #( "add" attributes[w] block[w] )
+ ;
+
+removeAccessorDeclaration [Object w]
+ : #( "remove" attributes[w] block[w] )
+ ;
+
+
+// for an index getter create get___idx()
+// for the setter set___idx()
+// I am trying to avoid clashes with possible property names (__idx would clash)
+indexerDeclaration! [Object w]
+ : #( INDEXER_DECL attributes[w] m:modifiers[w]
+ t:type[w] ( interfaceType[w] )? THIS
+ f:formalParameterList[w] a:accessorDeclarations[w]
+ /*cly:*/CLOSE_CURLY
+ ) { ## = #( [IDENTIFIER, "dummy"] );
+ // Take each getter/setter
+ ASTNode gs = #a;
+
+ while ( gs != null ) {
+ if (gs.getText() == "get") {
+ ASTNode myGetter = #( [METHOD_DECL, "METHOD_DECL"],
+ astFactory.dupTree(#m),
+ astFactory.dupTree(#t),
+ #( [IDENTIFIER, "get___idx"]),
+ astFactory.dupTree(#f), #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ),
+ astFactory.dupTree(gs.getFirstChild()) );
+ ##.addChild(myGetter);
+ } else {
+ if (gs.getText() == "set") {
+ ASTNode mySetter = #( [METHOD_DECL, "METHOD_DECL"],
+ astFactory.dupTree(#m),
+ #( [TYPE, "TYPE"],
+ #( [VOID, "void"] ),
+ #( [ARRAY_RANKS] ) ),
+ #( [IDENTIFIER, "set___idx"]),
+ astFactory.dupTree(#f), #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ),
+ astFactory.dupTree(gs.getFirstChild()) );
+ ##.addChild(mySetter);
+ }
+ }
+ gs = (ASTNode) gs.getNextSibling();
+ }
+ ## = (ASTNode) ##.getFirstChild();
+ }
+ ;
+
+operatorDeclaration [Object w]
+ : ( #( UNARY_OP_DECL attributes[w]! modifiers[w]
+ type[w] overloadableUnaryOperator[w]
+ formalParameterList[w]
+ operatorBody[w]
+ )
+ | #( BINARY_OP_DECL attributes[w]! modifiers[w]
+ type[w] overloadableBinaryOperator[w]
+ formalParameterList[w]
+ operatorBody[w]
+ )
+ | #( CONV_OP_DECL attributes[w]! modifiers[w]
+ ( IMPLICIT | EXPLICIT ) type[w]
+ formalParameterList[w] operatorBody[w]
+ )
+ )
+ ;
+
+overloadableUnaryOperator [Object w]
+ : UNARY_PLUS
+ | UNARY_MINUS
+ | LOG_NOT
+ | BIN_NOT
+ | INC
+ | DEC
+ | TRUE
+ | FALSE
+ ;
+
+overloadableBinaryOperator [Object w]
+ :/*pl:*/PLUS
+ |/*ms:*/MINUS
+ |/*st:*/STAR
+ |/*dv:*/DIV
+ |/*md:*/MOD
+ |/*ba:*/BIN_AND
+ |/*bo:*/BIN_OR
+ |/*bx:*/BIN_XOR
+ |/*sl:*/SHIFTL
+ |/*sr:*/SHIFTR
+ |/*eq:*/EQUAL
+ |/*nq:*/NOT_EQUAL
+ |/*gt:*/GTHAN
+ |/*lt:*/LTHAN
+ |/*ge:*/GTE
+ |/*le:*/LTE
+ ;
+
+operatorBody [Object w]
+ : body[w]
+ ;
+
+constructorDeclaration [Object w]
+ :! #( CTOR_DECL attributes[w]! m:modifiers[w] i:identifier[w]
+ b:constructorBody[w]
+ ( p:formalParameterList[w] )?
+ ( c:constructorInitializer[w] )?
+ )
+ {
+ AST nbody = #( [BLOCK] );
+ nbody.addChild(#c);
+ nbody.addChild(#b.getFirstChild());
+ if (#p == null)
+ #p = #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"] );
+ ## = #( CTOR_DECL, #m, #i, #p, #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ), nbody);
+ }
+ ;
+
+constructorInitializer [Object w]
+ : ( #( BASE ( es1:argumentList[w] )? ) { ##.setText("super"); if (#es1 == null) ##.addChild( #( [EXPR_LIST] ) ); }
+ | #( THIS ( es2:argumentList[w] )? ) { ##.setText("this"); if (#es2 == null) ##.addChild( #( [EXPR_LIST] ) ); }
+ )
+ ;
+
+constructorBody [Object w]
+ : body[w]
+ ;
+
+staticConstructorDeclaration! [Object w]
+ : #( STATIC_CTOR_DECL attributes[w] modifiers[w] identifier[w]
+ b:staticConstructorBody[w]
+ ) { ## = #( [STATIC_CTOR_DECL], #( [BLOCK], SmotherCheckedExceptions(#b, "ExceptionInInitializerError") ) ); }
+ ;
+
+staticConstructorBody [Object w]
+ : body[w]
+ ;
+
+destructorDeclaration [Object w]
+ : #( DTOR_DECL attributes[w] modifiers[w] identifier[w]
+ destructorBody[w]
+ )
+ ;
+
+destructorBody [Object w]
+ : body[w]
+ ;
+
+
+//
+// A.2.7 Structs
+//
+
+
+// Convert to a class
+// A struct instance is an object without identity
+// We add a default constructor that does nothing. In C# a default
+// constructor is not allowed. If a struct is declared without
+// an explicit constructor call then struct fields will be initialized
+// to defalt values, but anyway program must assign to them before
+// they can be used.
+// [TODO]: What problems can happen when passed as parameter due to
+// value vs ref semantics.
+structDeclaration [Object w]
+ { string saveClass = this.ClassInProcess; }
+ :! #( STRUCT attributes[w] mod:modifiers[w] id:identifier[w] { this.ClassInProcess = #id.getText(); }
+ imps:structImplements[w]
+ #( TYPE_BODY mem:structMemberDeclarations[w, #id] CLOSE_CURLY )
+ ) { ## = #( [CLASS, "class"], #mod, #id, #imps, #mem );
+ this.ClassInProcess = saveClass; }
+ ;
+
+structImplements [Object w]
+ : #( STRUCT_BASE ( type[w] )* )
+ { ##.setType(CLASS_BASE); }
+ ;
+
+structMemberDeclarations [Object w, ASTNode id]
+ // Add Default Constructor
+ :! { ASTNode ret = #( [MEMBER_LIST],
+ #( [CTOR_DECL],
+ #( [MODIFIERS], [PUBLIC, "public"] ),
+ astFactory.dupTree(id),
+ #( [FORMAL_PARAMETER_LIST] ),
+ #( [BLOCK] ) )
+ ); }
+ #( MEMBER_LIST
+ ( s:structMemberDeclaration[w] { ret.addChild(#s); }
+ | p:preprocessorDirective[w, CodeMaskEnums.StructMemberDeclarations] { ret.addChild(#p); }
+ )*
+ ) { ## = ret; }
+ ;
+
+structMemberDeclaration [Object w]
+ : typeMemberDeclaration[w]
+ ;
+
+
+//
+// A.2.8 Arrays
+//
+
+rankSpecifiers [Object w]
+ : #( ARRAY_RANKS
+ ( rankSpecifier[w]
+ )*
+ )
+ ;
+
+rankSpecifier [Object w]
+ : #( ARRAY_RANK
+ (COMMA
+ )*
+ )
+ ;
+
+arrayInitializer [Object w]
+ : #( ARRAY_INIT ( variableInitializerList[w] )? CLOSE_CURLY! )
+ ;
+
+variableInitializerList [Object w]
+ : #( VAR_INIT_LIST v:arrayvariableInitializer[w] ( arrayvariableInitializer[w] )* ) {## = #v; }
+ ;
+
+arrayvariableInitializer! [Object w]
+ : v:variableInitializer[w] {## = (ASTNode) #v.getFirstChild(); }
+ ;
+
+//
+// A.2.9 Interfaces
+//
+
+interfaceDeclaration [Object w]
+ { string saveClass = this.ClassInProcess; }
+ :! #(INTERFACE attributes[w] mod:modifiers[w] id:identifier[w] { this.ClassInProcess = #id.getText(); }
+ imps:interfaceImplements[w]
+ #( TYPE_BODY mem:interfaceMemberDeclarations[w] CLOSE_CURLY )
+ ) { ## = #( [INTERFACE], #mod, #id, #imps, #mem );
+ this.ClassInProcess = saveClass; }
+ ;
+
+interfaceImplements [Object w]
+ : #( INTERFACE_BASE ( type[w] )* )
+ { ##.setType(IMPLEMENTS_CLAUSE); ##.setText("implements"); }
+ ;
+
+interfaceMemberDeclarations [Object w]
+ : #( MEMBER_LIST
+ ( interfaceMemberDeclaration[w]
+ | preprocessorDirective[w, CodeMaskEnums.InterfaceMemberDeclarations]
+ )*
+ )
+ ;
+
+interfaceMemberDeclaration [Object w]
+ : ( methodDeclaration[w]
+ | propertyDeclaration[w]
+ | eventDeclaration[w]
+ | indexerDeclaration[w]
+ )
+ ;
+
+interfaceMethodDeclaration [Object w]
+ : #( METHOD_DECL attributes[w]! modifiers[w] type[w] qualifiedIdentifier[w]
+ EMPTY_STMT
+ ( f:formalParameterList[w] )?
+ ) { if (#f == null) ##.addChild( #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"] )); }
+ ;
+
+interfacePropertyDeclaration [Object w]
+ : #( PROPERTY_DECL attributes[w] modifiers[w] type[w] identifier[w]
+ accessorDeclarations[w]/*cc:*/CLOSE_CURLY
+ )
+ ;
+
+interfaceEventDeclaration [Object w]
+ : #(/*evt:*/EVENT attributes[w] modifiers[w]
+ type[w] variableDeclarator[w]
+ )
+ ;
+
+interfaceIndexerDeclaration [Object w]
+ : #( INDEXER_DECL attributes[w] modifiers[w] type[w]/*t:*/THIS
+ formalParameterList[w]
+ accessorDeclarations[w]/*cc:*/CLOSE_CURLY
+ )
+ ;
+
+
+//
+// A.2.10 Enums
+//
+
+enumDeclaration [Object w]
+ { string saveClass = this.ClassInProcess; }
+ :! #( ENUM attributes[w] mod:modifiers[w] id:identifier[w] { this.ClassInProcess = #id.getText(); }
+ basetype:enumImplements[w]
+ #( TYPE_BODY
+ mem:enumMemberDeclarations[w]
+ CLOSE_CURLY
+ )
+ ) { ## = #( [ENUM], #mod, #id, #( [IMPLEMENTS_CLAUSE] ), #mem);
+ this.ClassInProcess = saveClass; }
+ ;
+
+// keving: ignored in enumDeclaration
+enumImplements [Object w]
+ { ASTNode t = null; }
+ :! #( ENUM_BASE ( gt:type[w] { t = #gt; } )? )
+ { if (t == null)
+ ## = #( [TYPE], [INT, "int"], #( [ARRAY_RANKS] ) );
+ else
+ ## = #gt; }
+ ;
+
+// Convert the declarations to a simple list, match their intended value to their ordinal position by adding in
+// dummy enums
+enumMemberDeclarations! [Object w]
+ { SortedList ExplicitEnums = new SortedList();
+ ArrayList ImplicitEnums = new ArrayList();
+ int dummyCounter = 0;
+ }
+ : #( MEMBER_LIST ( enumMemberDeclaration[w, ExplicitEnums, ImplicitEnums] )* )
+ {
+ ## = #(MEMBER_LIST);
+ int ord = 0;
+ foreach (DictionaryEntry de in ExplicitEnums)
+ {
+ // entries are sorted by enum value
+ int enumValue = (int) de.Key;
+ ASTNode enumAST = (ASTNode) de.Value;
+ while (ord < enumValue)
+ {
+ // We need some padding here
+ if (ImplicitEnums.Count > 0)
+ {
+ ##.addChild((ASTNode) ImplicitEnums[0]);
+ ImplicitEnums.RemoveAt(0);
+ }
+ else
+ {
+ string dummyEnum = "__dummyEnum" + dummyCounter;
+ dummyCounter++;
+ ##.addChild(#([IDENTIFIER, dummyEnum]));
+ }
+ ord++;
+ }
+ ##.addChild(enumAST);
+ ord++;
+ }
+ // Add implicit enums that haven't yet been accounted for
+ foreach (ASTNode id in ImplicitEnums)
+ ##.addChild((ASTNode) #id);
+
+ }
+ ;
+
+enumMemberDeclaration! [Object w, SortedList e, ArrayList i]
+ { bool init = false; }
+ : #( id:IDENTIFIER { fixBrokenIds(#id); } attributes[w]
+ ( c:constantExpression[w]
+ { // If constantExpression is #(EXPR #( [INT_LITERAL, xxx] ) )
+ // then we maintain its value, otherwise print a warning and
+ // give it next available slot
+ bool hasValue = false;
+ int intValue = 0;
+ if (#c.Type == EXPR)
+ {
+ if (#c.getFirstChild().Type == INT_LITERAL)
+ {
+ // Assigned value
+ String strValue = #c.getFirstChild().getText();
+ if ( strValue.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) {
+ intValue = Int32.Parse(strValue.Substring(2), NumberStyles.HexNumber);
+ }
+ else {
+ intValue = Int32.Parse(strValue);
+ }
+ if (!e.Contains(intValue))
+ hasValue = true;
+ else
+ Console.Error.WriteLine("ERROR -- (enumMemberDeclaration): repeated enum value: " + intValue);
+ }
+ }
+ if (hasValue)
+ {
+ init = true;
+ e[intValue] = #id;
+ }
+ else
+ Console.Out.WriteLine("WARNING -- (enumMemberDeclaration): Ignoring assigned value of " + #id.getText());
+ }
+ )?
+ { if (!init)
+ i.Add(#id);
+ }
+ )
+ ;
+
+
+//
+// A.2.11 Delegates
+//
+
+delegateDeclaration [Object w]
+ : #(/*dlg:*/DELEGATE attributes[w] modifiers[w]
+ type[w] identifier[w] ( f:formalParameterList[w] )?
+ ) { if (#f == null) ##.addChild( #( [FORMAL_PARAMETER_LIST, "FORMAL_PARAMETER_LIST"] )); }
+ ;
+
+
+//
+// A.2.12 Attributes
+//
+
+globalAttributes [Object w]
+ : #( GLOBAL_ATTRIBUTE_SECTIONS
+ ( globalAttributeSection[w]
+ | preprocessorDirective[w, CodeMaskEnums.GlobalAttributes]
+ )*
+ )
+ ;
+
+globalAttributeSection [Object w]
+ : #(/*sect:*/GLOBAL_ATTRIBUTE_SECTION
+ ( attribute[w] )+
+ )
+ ;
+
+attributes [Object w]
+ : #( ATTRIBUTE_SECTIONS
+ ( attributeSection[w]
+ | preprocessorDirective[w, CodeMaskEnums.Attributes]
+ )*
+ )
+ ;
+
+attributeSection [Object w]
+ : #(/*sect:*/ATTRIBUTE_SECTION ( attributeTarget[w] )?
+ ( attribute[w] )+
+ )
+ ;
+
+attributeTarget[Object w]
+ : (/*fv:*/"field"
+ |/*ev:*/EVENT
+ |/*mv:*/"method"
+ |/*mo:*/"module"
+ |/*pa:*/"param"
+ |/*pr:*/"property"
+ |/*re:*/RETURN
+ |/*ty:*/"type"
+ )
+ ;
+
+attribute [Object w]
+ : #( ATTRIBUTE typeName[w] attributeArguments[w] )
+ ;
+
+attributeArguments [Object w]
+ : ( positionalArgumentList[w] )? ( namedArgumentList[w] )?
+ ;
+
+positionalArgumentList [Object w]
+ : #( POSITIONAL_ARGLIST positionalArgument[w]
+ ( positionalArgument[w] )*
+ )
+ ;
+
+positionalArgument [Object w]
+ : #( POSITIONAL_ARG attributeArgumentExpression[w] )
+ ;
+
+namedArgumentList [Object w]
+ : #( NAMED_ARGLIST namedArgument[w]
+ ( namedArgument[w] )*
+ )
+ ;
+
+namedArgument [Object w]
+ : #( NAMED_ARG identifier[w] attributeArgumentExpression[w] )
+ ;
+
+attributeArgumentExpression [Object w]
+ : #( ATTRIB_ARGUMENT_EXPR expression[w] )
+ ;
+
+//
+// A.3 Grammar extensions for unsafe code
+//
+
+fixedPointerDeclarator [Object w]
+ : #( PTR_DECLARATOR identifier[w] fixedPointerInitializer[w] )
+ ;
+
+fixedPointerInitializer [Object w]
+ : #( PTR_INIT
+ (/*b:*/BIN_AND variableReference[w]
+ | expression[w]
+ )
+ )
+ ;
+
+stackallocInitializer [Object w]
+ : #(/*s:*/STACKALLOC unmanagedType[w] expression[w] )
+ ;
+
+//======================================
+// Preprocessor Directives
+//======================================
+
+justPreprocessorDirectives [Object w]
+ : #( PP_DIRECTIVES
+ ( preprocessorDirective[w, CodeMaskEnums.PreprocessorDirectivesOnly]
+ )*
+ )
+ ;
+
+preprocessorDirective [Object w, CodeMaskEnums codeMask]
+ :! #(PP_DEFINE i:PP_IDENT {defines[#i.getText()] = true;} )
+ |! #(/*u1:*/PP_UNDEFINE i2:PP_IDENT {defines.Remove(#i2.getText()); } )
+ |! #(/*l1:*/PP_LINE
+ (/*l2:*/DEFAULT
+ |/*l3:*/PP_NUMBER (/*l4:*/PP_FILENAME )?
+ )
+ )
+ |! #(/*e1:*/PP_ERROR ppMessage[w] )
+ |! #(/*w1:*/PP_WARNING ppMessage[w] )
+ | regionDirective[w, codeMask]
+ | conditionalDirective[w, codeMask]
+ ;
+
+regionDirective! [Object w, CodeMaskEnums codeMask]
+ : #(PP_REGION ppMessage[w] b:directiveBlock[w, codeMask]
+ #(PP_ENDREGION ppMessage[w] )
+ ) { ## = #b; }
+ ;
+
+conditionalDirective! [Object w, CodeMaskEnums codeMask]
+ { ASTNode ret = null;
+ bool c = false; }
+ : #(PP_COND_IF c = preprocessExpression[w] th:directiveBlock[w, codeMask] { if (c) ret = #th; }
+ ( #(PP_COND_ELIF c = preprocessExpression[w] ce:directiveBlock[w, codeMask] ) { if (c && ret == null) ret = #ce; } )*
+ ( #(PP_COND_ELSE el:directiveBlock[w, codeMask] ) { if (ret == null) ret = #el; } )?
+ PP_COND_ENDIF
+ ) { ## = ret; }
+ ;
+
+directiveBlock [Object w, CodeMaskEnums codeMask]
+ : #( PP_BLOCK
+ ( { NotExcluded(codeMask, CodeMaskEnums.UsingDirectives) }? usingDirective[w]
+ | { NotExcluded(codeMask, CodeMaskEnums.GlobalAttributes) }? globalAttributeSection[w]
+ | { NotExcluded(codeMask, CodeMaskEnums.Attributes) }? attributeSection[w]
+ | { NotExcluded(codeMask, CodeMaskEnums.NamespaceMemberDeclarations) }? namespaceMemberDeclaration[w, null, null]
+ | { NotExcluded(codeMask, CodeMaskEnums.ClassMemberDeclarations) }? classMemberDeclaration[w]
+ | { NotExcluded(codeMask, CodeMaskEnums.StructMemberDeclarations) }? structMemberDeclaration[w]
+ | { NotExcluded(codeMask, CodeMaskEnums.InterfaceMemberDeclarations) }? interfaceMemberDeclaration[w]
+ | { NotExcluded(codeMask, CodeMaskEnums.Statements) }? statement[w]
+ | preprocessorDirective[w, codeMask]
+ )*
+ ) {## = (ASTNode) ##.getFirstChild(); }
+ ;
+
+ppMessage [Object w]
+ : #( PP_MESSAGE
+ (/*m1:*/PP_IDENT
+ |/*m2:*/PP_STRING
+ | /*m3:*/PP_FILENAME
+ | /*m4:*/PP_NUMBER
+ )*
+ )
+ ;
+
+preprocessExpression [Object w] returns [bool v]
+ { v = false; }
+ : #( PP_EXPR v = preprocessExpr[w] )
+ ;
+
+preprocessExpr [Object w] returns [bool v]
+ { bool v1, v2;
+ v = false;
+ }
+ : #( LOG_OR v1 = preprocessExpr[w] v2 = preprocessExpr[w] ) { v = v1 | v2; }
+ | #( LOG_AND v1 = preprocessExpr[w] v2 = preprocessExpr[w] ) { v = v1 & v2; }
+ | #( EQUAL v1 = preprocessExpr[w] v2 = preprocessExpr[w] ) { v = v1 == v2; }
+ | #( NOT_EQUAL v1 = preprocessExpr[w] v2 = preprocessExpr[w] ) { v = v1 != v2; }
+ | v = preprocessPrimaryExpression[w]
+ ;
+
+preprocessPrimaryExpression [Object w] returns [bool v]
+ { bool r;
+ v = false;
+ }
+ : i:PP_IDENT { v = (defines[#i.getText()] == null?false:(bool)defines[#i.getText()]); // Should look up in symbol table!
+ }
+ | TRUE { v = true; }
+ | FALSE { v = false; }
+ | #( LOG_NOT r = preprocessPrimaryExpression[w] ) { v = !r; }
+ | #( PAREN_EXPR v = preprocessExpr[w] )
+ ;
diff --git a/CSharpTranslator/Translator/CodeMaskEnums.cs b/CSharpTranslator/Translator/CodeMaskEnums.cs
new file mode 100644
index 0000000..e9f4e1a
--- /dev/null
+++ b/CSharpTranslator/Translator/CodeMaskEnums.cs
@@ -0,0 +1,50 @@
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+namespace RusticiSoftware.Translator
+{
+ using System;
+
+ ///
+ /// Bit masks for specifying valid CSharp syntax constructs in Parser productions.
+ ///
+ public enum CodeMaskEnums
+ {
+ PreprocessorDirectivesOnly = 0x0000,
+
+ UsingDirectives = 0x0001,
+ GlobalAttributes = 0x0002,
+ Attributes = 0x0004,
+ ClassMemberDeclarations = 0x0008,
+ StructMemberDeclarations = 0x0010,
+ InterfaceMemberDeclarations = 0x0020,
+ NamespaceMemberDeclarations = 0x0040,
+ Statements = 0x0080,
+ }
+}
diff --git a/CSharpTranslator/Translator/CustomHiddenStreamToken.cs b/CSharpTranslator/Translator/CustomHiddenStreamToken.cs
new file mode 100644
index 0000000..5b74637
--- /dev/null
+++ b/CSharpTranslator/Translator/CustomHiddenStreamToken.cs
@@ -0,0 +1,146 @@
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+namespace RusticiSoftware.Translator
+{
+ using System;
+ using FileInfo = System.IO.FileInfo;
+ using IToken = antlr.IToken;
+ using TokenCreator = antlr.TokenCreator;
+ using CommonHiddenStreamToken = antlr.CommonHiddenStreamToken;
+
+ ///
+ /// A sub-class of antlr.CommonHiddenStreamToken that can be used to track the
+ /// file from which a token was created.
+ ///
+ /// Has an ugly but convenient dependency on the CSharpParser class. See
+ /// ToString() below.
+ ///
+ ///
+ public class CustomHiddenStreamToken : CommonHiddenStreamToken
+ {
+ private string filename_;
+ private FileInfo fileinfo_;
+
+ protected CustomHiddenStreamToken() : base()
+ {
+ }
+
+ public CustomHiddenStreamToken(int t, string txt) : base(t, txt)
+ {
+ }
+
+ public CustomHiddenStreamToken(int t, string txt, FileInfo fileinfo) : base(t, txt)
+ {
+ fileinfo_ = fileinfo;
+ }
+
+ public CustomHiddenStreamToken(int t, string txt, FileInfo fileinfo, int line, int col) : base(t, txt)
+ {
+ this.fileinfo_ = fileinfo;
+ this.line = line;
+ this.col = col;
+ }
+
+ public override string getFilename()
+ {
+ if (fileinfo_ != null)
+ return fileinfo_.FullName;
+ else
+ return null;
+ }
+
+ override public string ToString()
+ {
+ return "[\"" + getText() + "\",<" + CSharpParser.tokenNames_[type_] + ">,line=" + line + ",col=" + col + "]";
+ }
+
+ ///
+ /// Sets the source file of the token
+ ///
+ ///
+ public FileInfo File
+ {
+ [System.Diagnostics.DebuggerStepThrough]
+ get { return fileinfo_; }
+ [System.Diagnostics.DebuggerStepThrough]
+ set { fileinfo_ = value; }
+ }
+
+ ///
+ /// Gets or sets the contents of the hidden-before token stream.
+ ///
+ ///
+ public CustomHiddenStreamToken HiddenBefore
+ {
+ [System.Diagnostics.DebuggerStepThrough]
+ get { return (CustomHiddenStreamToken) hiddenBefore; }
+ [System.Diagnostics.DebuggerStepThrough]
+ set { hiddenBefore = (CommonHiddenStreamToken) value; }
+ }
+
+ ///
+ /// Gets or sets the contents of the hidden-after token stream.
+ ///
+ ///
+ public CustomHiddenStreamToken HiddenAfter
+ {
+ [System.Diagnostics.DebuggerStepThrough]
+ get { return (CustomHiddenStreamToken) hiddenAfter; }
+ [System.Diagnostics.DebuggerStepThrough]
+ set { hiddenAfter = (CommonHiddenStreamToken) value; }
+ }
+
+ public class CustomHiddenStreamTokenCreator : TokenCreator
+ {
+ public CustomHiddenStreamTokenCreator() {}
+
+ ///
+ /// Returns the fully qualified name of the Token type that this
+ /// class creates.
+ ///
+ public override string TokenTypeName
+ {
+ [System.Diagnostics.DebuggerStepThrough]
+ get
+ {
+ return typeof(CustomHiddenStreamToken).FullName;;
+ }
+ }
+
+ ///
+ /// Constructs a instance.
+ ///
+ public override IToken Create()
+ {
+ return new CustomHiddenStreamToken();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CSharpTranslator/Translator/DirectoryHT.cs b/CSharpTranslator/Translator/DirectoryHT.cs
new file mode 100644
index 0000000..c5f7885
--- /dev/null
+++ b/CSharpTranslator/Translator/DirectoryHT.cs
@@ -0,0 +1,291 @@
+using System;
+using System.Collections;
+using System.Text;
+
+namespace RusticiSoftware.Translator
+{
+
+ // Implements a hierarchy of directories.
+ public class DirectoryHT : IDictionary
+ {
+
+ private DirectoryHT _parent = null;
+
+ private Hashtable leaves = new Hashtable();
+
+ private Hashtable children = new Hashtable();
+
+ public DirectoryHT(DirectoryHT p)
+ {
+ _parent = p;
+ }
+
+ public DirectoryHT()
+ : this(null)
+ { }
+
+
+ public Hashtable Leaves
+ {
+ get { return leaves; }
+ }
+
+ // p is key to a sub directory
+ public DirectoryHT subDir(string p)
+ {
+ string[] components = p.Split(new char[] { '.' }, 2);
+ if (components.Length == 1)
+ {
+ return (DirectoryHT) children[components[0]];
+ }
+ else
+ {
+ DirectoryHT child = (DirectoryHT)children[components[0]];
+ return (child == null ? null : child.subDir(components[1]));
+ }
+ }
+
+ #region IDictionary Members
+
+ public void Add(object key, object value)
+ {
+ if (!(key is string))
+ throw new Exception("The method or operation is not implemented.");
+
+ string[] components = ((string)key).Split(new char[] { '.' }, 2);
+ if (components.Length == 1)
+ {
+ leaves[components[0]] = value;
+ }
+ else
+ {
+ if (children[components[0]] == null)
+ children[components[0]] = new DirectoryHT(this);
+ ((DirectoryHT)children[components[0]]).Add(components[1], value);
+ }
+ }
+
+ public void Clear()
+ {
+ leaves.Clear();
+ children.Clear();
+ }
+
+ public bool Contains(object key)
+ {
+ if (!(key is string))
+ throw new Exception("The method or operation is not implemented.");
+ string[] components = ((String)key).Split(new char[] { '.' }, 2);
+ if (components.Length == 1)
+ {
+ return leaves.Contains(components[0]);
+ }
+ else
+ {
+ return ((DirectoryHT)children[components[0]]).Contains(components[1]);
+ }
+ }
+
+ public IDictionaryEnumerator GetEnumerator()
+ {
+ IDictionaryEnumerator[] des = new IDictionaryEnumerator[1 + children.Count];
+ string[] pres = new string[1 + children.Count];
+ int i = 1;
+
+ pres[0] = "";
+ des[0] = leaves.GetEnumerator();
+ foreach (DictionaryEntry de in children)
+ {
+ pres[i] = ((string)de.Key) + ".";
+ des[i] = ((DirectoryHT)de.Value).GetEnumerator();
+ i++;
+ }
+
+ return new DirectoryHTEnumerator(pres,des);
+ }
+
+ public bool IsFixedSize
+ {
+ get { return false; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return false; }
+ }
+
+ public ICollection Keys
+ {
+ get {
+ ArrayList keys = new ArrayList();
+ foreach (object k in leaves.Keys)
+ keys.Add(k);
+ foreach (DictionaryEntry de in children)
+ foreach (string k in ((DirectoryHT)de.Value).Keys)
+ keys.Add(de.Key + "." + k);
+ return keys;
+ }
+ }
+
+ public void Remove(object key)
+ {
+ if (!(key is string))
+ throw new Exception("The method or operation is not implemented.");
+ string[] components = ((string)key).Split(new char[] { '.' }, 2);
+ if (components.Length == 1)
+ {
+ leaves.Remove(components[0]);
+ }
+ else
+ {
+ ((DirectoryHT)children[components[0]]).Remove(components[1]);
+ }
+ }
+
+ public ICollection Values
+ {
+
+ get {
+ ArrayList vals = new ArrayList();
+ foreach (object v in leaves.Values)
+ vals.Add(v);
+ foreach (DictionaryEntry de in children)
+ foreach (object v in ((DirectoryHT)de.Value).Values)
+ vals.Add(v);
+ return vals;
+ }
+ }
+
+ public object this[object key]
+ {
+ get
+ {
+ if (!(key is string))
+ throw new Exception("The method or operation is not implemented.");
+ string[] components = ((string)key).Split(new char[] { '.' }, 2);
+ if (components.Length == 1)
+ {
+ object val = leaves[components[0]];
+ return (val != null ? val : children[components[0]]);
+ }
+ else
+ {
+ DirectoryHT child = (DirectoryHT)children[components[0]];
+ return (child == null ? null : child[components[1]]);
+ }
+ }
+ set
+ {
+ Add(key, value);
+ }
+ }
+
+ #endregion
+
+ #region ICollection Members
+
+ public void CopyTo(Array array, int index)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public int Count
+ {
+ get
+ {
+ int count = leaves.Count;
+ foreach (DirectoryHT c in children.Values)
+ count += c.Count;
+ return count;
+ }
+ }
+
+ public bool IsSynchronized
+ {
+ get { throw new Exception("The method or operation is not implemented."); }
+ }
+
+ public object SyncRoot
+ {
+ get { throw new Exception("The method or operation is not implemented."); }
+ }
+
+ #endregion
+
+ #region IEnumerable Members
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion
+ }
+
+ public class DirectoryHTEnumerator : IDictionaryEnumerator
+ {
+ private int _pos = 0;
+ private string[] _prefixes;
+ private IDictionaryEnumerator[] _enums;
+
+ public DirectoryHTEnumerator(string[] pres, IDictionaryEnumerator[] des)
+ {
+ _prefixes = pres;
+ _enums = des;
+ }
+
+ #region IDictionaryEnumerator Members
+
+ public DictionaryEntry Entry
+ {
+ get { return (DictionaryEntry)Current; }
+ }
+
+ public object Key
+ {
+ get { return Entry.Key; }
+ }
+
+ public object Value
+ {
+ get { return Entry.Value; }
+ }
+
+ #endregion
+
+ #region IEnumerator Members
+
+ public object Current
+ {
+ get { ValidateIndex();
+ return new DictionaryEntry(_prefixes[_pos] + (string)((DictionaryEntry)_enums[_pos].Current).Key,
+ ((DictionaryEntry)_enums[_pos].Current).Value);
+ }
+ }
+
+ public bool MoveNext()
+ {
+ if (_pos >= _enums.Length)
+ return false;
+
+ while (_pos < _enums.Length && !_enums[_pos].MoveNext())
+ _pos++;
+
+ return _pos != _enums.Length;
+ }
+
+ public void Reset()
+ {
+ _pos = 0;
+ }
+
+ // Validate the enumeration index and throw an exception if the index is out of range.
+ private void ValidateIndex()
+ {
+ if (_pos < 0 || _pos >= _enums.Length)
+ throw new InvalidOperationException("Enumerator is before or after the collection.");
+ }
+
+ #endregion
+ }
+}
diff --git a/CSharpTranslator/Translator/Exception.cs b/CSharpTranslator/Translator/Exception.cs
new file mode 100644
index 0000000..cfecafa
--- /dev/null
+++ b/CSharpTranslator/Translator/Exception.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RusticiSoftware.Translator
+{
+ class CorruptCompilationUnit : Exception
+ {
+ ASTNode ast = null;
+
+ public CorruptCompilationUnit(ASTNode astIn)
+ {
+ ast = astIn;
+ }
+ }
+
+ class UnexpectedAST : Exception
+ {
+ ASTNode ast = null;
+
+ public UnexpectedAST(ASTNode astIn)
+ {
+ ast = astIn;
+ }
+ }
+}
diff --git a/CSharpTranslator/Translator/JavaPrettyPrinter.g b/CSharpTranslator/Translator/JavaPrettyPrinter.g
new file mode 100644
index 0000000..5884ddc
--- /dev/null
+++ b/CSharpTranslator/Translator/JavaPrettyPrinter.g
@@ -0,0 +1,778 @@
+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
+ *
+ * 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();
+
+ /** 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());
+ }
+ }
+
+ ///
+ /// Prints the text of the specified AST node
+ ///
+ /// The output destination.
+ /// The AST node to print.
+ private void Print(TextWriter w, AST node)
+ {
+ Print(w, node, null);
+ }
+
+ ///
+ /// Prints the text
+ ///
+ /// The output destination.
+ /// The AST node to print.
+ private void Print(TextWriter w, string text)
+ {
+ Print(w, null, text);
+ }
+
+
+ ///
+ /// Prints the text of the AST node if it exists, then the text if it exists
+ ///
+ /// The output destination.
+ /// The AST node to print.
+ 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 take newline from environment?
+ 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++;
+ }
+ }
+ }
+
+ // 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 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]
+ { filter = f; this.enumXmlWriter = enumXmlWriter; }
+ : #( 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
+ modifiers[w]
+ 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" { 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, ";"); }
+ | #(LABELED_STAT 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, ");"); }
+ )
+ | #(br:"break" { Print(w, #br); } ( { Print(w, " "); } IDENTIFIER)? { Print(w, ";"); } )
+ | #(co:"continue" { Print(w, #co); } ( { Print(w, " "); } IDENTIFIER)? { 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); }
+ | flr:FLOAT_LITERAL { Print(w, #flr); }
+ | 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, "]"); })
+// ;
diff --git a/CSharpTranslator/Translator/JavaTreeParser.cs b/CSharpTranslator/Translator/JavaTreeParser.cs
new file mode 100644
index 0000000..a6f0d45
--- /dev/null
+++ b/CSharpTranslator/Translator/JavaTreeParser.cs
@@ -0,0 +1,349 @@
+
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using T = RusticiSoftware.Translator.CSharpJavaTokenTypes; // We want easy access to the Token mappings
+
+namespace RusticiSoftware.Translator
+{
+ // Generate header specific to the tree-parser CSharp file
+ using System;
+
+ using TreeParser = antlr.TreeParser;
+ using Token = antlr.Token;
+ using IToken = antlr.IToken;
+ using AST = antlr.collections.AST;
+ using RecognitionException = antlr.RecognitionException;
+ using ANTLRException = antlr.ANTLRException;
+ using NoViableAltException = antlr.NoViableAltException;
+ using MismatchedTokenException = antlr.MismatchedTokenException;
+ using SemanticException = antlr.SemanticException;
+ using BitSet = antlr.collections.impl.BitSet;
+ using ASTPair = antlr.ASTPair;
+ using ASTFactory = antlr.ASTFactory;
+ using ASTArray = antlr.collections.impl.ASTArray;
+
+
+ /** Java 1.3 AST Tree Parser Base Class
+ *
+ * Author: Kevin Glynn
+ *
+ * This contains utility routines for the java parser passes
+ *
+ */
+ public class JavaTreeParser : antlr.TreeParser
+ {
+
+ protected string ClassInProcess; // Name of Class being processed
+ ///
+ /// Provides the storage for elements in the Set, stored as the key-set
+ /// of the IDictionary object. Set this object in the constructor
+ /// if you create your own Set class.
+ ///
+ protected Set imports = null;
+
+ private static readonly string[] ScruTypeStrs = new string[] { "System.Int32",
+ "System.Int64",
+ "System.Char",
+ "System.Enum", };
+
+ protected void initialize()
+ {
+ // Here we can add imports that should always be present
+ imports = new Set();
+ }
+
+ protected void addImport(string imp)
+ {
+ imports.Add(imp);
+ }
+
+ protected void addImport(string[] imps)
+ {
+ foreach (string imp in imps)
+ imports.Add(imp);
+ }
+
+ protected ASTNode GetImports()
+ {
+ ASTNode ret = (ASTNode)astFactory.make((AST)(ASTNode)astFactory.create(T.IMPORTS, "IMPORTS"));
+ String[] sortedImports = imports.AsArray();
+ Array.Sort(sortedImports);
+ foreach (string imp in sortedImports)
+ {
+ ret.addChild((ASTNode)astFactory.make((AST)(ASTNode)astFactory.create(T.IMPORT, "import"),
+ (AST)(ASTNode)astFactory.make((AST)(ASTNode)astFactory.create(T.IDENTIFIER, imp))));
+ }
+ return ret;
+ }
+
+ protected bool isValidScrutinee(ASTNode e)
+ {
+ bool ret = false;
+ TypeRep stype = e.DotNetType;
+
+ foreach (string t in ScruTypeStrs)
+ {
+ if (mkType(t).IsA(stype))
+ {
+ ret = true;
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+
+ // getClassName, getPackageName assume a compilation unit looks like this:
+ // #( COMPILATION_UNIT,
+ // #(PACKAGE_DEF, ),
+ // #(USING_DIRECTIVES, ()*),
+ // #(class, MODIFIERS, , ....)
+ // )
+ public static String getClassName(ASTNode cuAST)
+ {
+ if (cuAST.Type == T.COMPILATION_UNIT)
+ {
+ AST cla = cuAST.getFirstChild().getNextSibling().getNextSibling().getNextSibling(); ;
+ return cla.getFirstChild().getNextSibling().getText();
+ }
+ else
+ {
+ throw new CorruptCompilationUnit(cuAST);
+ }
+ }
+
+ public static ArrayList getPackageName(ASTNode cuAST)
+ {
+
+ if (cuAST.Type == T.COMPILATION_UNIT)
+ {
+ ArrayList nsComps = new ArrayList();
+ AST ns = cuAST.getFirstChild().getFirstChild();
+ while (ns != null)
+ {
+ if (ns.Type == T.IDENTIFIER)
+ {
+ nsComps.Add(ns.getText());
+ break;
+ }
+ else
+ { // Its a DOT node
+ ns = ns.getFirstChild();
+ nsComps.Add(ns.getText());
+ ns = ns.getNextSibling();
+ }
+ }
+ return nsComps;
+ }
+ else
+ {
+ throw new CorruptCompilationUnit(cuAST);
+ }
+ }
+
+ // Keep track of current use Path
+ protected Stack usePath = null;
+
+ protected string[] CollectUsePath()
+ {
+ int count = 0;
+ foreach (ArrayList l in usePath)
+ {
+ count += l.Count;
+ }
+
+ string[] ret = new string[count];
+ int i = 0;
+
+ foreach (ArrayList l in usePath)
+ {
+ foreach (string s in l)
+ {
+ ret[i] = s;
+ i++;
+ }
+ }
+
+ return ret;
+ }
+
+ public String idToString(AST idAST, string sep)
+ {
+
+ String res = "";
+
+ while (idAST != null)
+ {
+ if (idAST.Type == T.IDENTIFIER)
+ {
+ res += idAST.getText();
+ break;
+ }
+ else if (idAST.Type == T.DOT)
+ {
+ idAST = (ASTNode)idAST.getFirstChild();
+ res += idAST.getText() + sep;
+ idAST = (ASTNode)idAST.getNextSibling();
+ }
+ else
+ {
+ throw new UnexpectedAST((ASTNode)idAST);
+ }
+ }
+
+ return res;
+ }
+
+ public String idToString(AST idAST, char sep)
+ {
+ return idToString(idAST, sep.ToString());
+ }
+
+ public String idToString(AST idAST)
+ {
+ return idToString(idAST, ".");
+ }
+
+ // typeSpec [TextWriter w]
+ // : #(TYPE
+ // ( identifier[w]
+ // | builtInType[w]
+ // )
+ // rankSpecifiers[w]
+ // )
+ public String typeToString(AST tyAST, bool withQuotes)
+ {
+ String res = "";
+
+ if (withQuotes)
+ res = "\"";
+
+ if (tyAST != null && tyAST.Type == T.TYPE)
+ {
+
+ tyAST = tyAST.getFirstChild();
+ if (tyAST.Type == T.DOT)
+ res += idToString(tyAST);
+ else
+ res += tyAST.getText();
+
+ // Move to rankspecifiers
+ tyAST = tyAST.getNextSibling();
+ for (int i = 0; i < tyAST.getNumberOfChildren(); i++)
+ res += "[]";
+
+ }
+ else
+ {
+ throw new UnexpectedAST((ASTNode)tyAST);
+ }
+
+ if (withQuotes)
+ res += "\"";
+
+ return res;
+ }
+
+ public String typeToString(AST tyAST)
+ {
+ return typeToString(tyAST, true);
+ }
+
+ // Remove/Replace troublesome characters
+ protected String typeNameToId(String tName)
+ {
+ return tName.Replace(".", "").Replace("[","_").Replace("]","");
+ }
+
+ protected void prependStringToId(AST idAST, String str)
+ {
+ while (idAST.Type == T.DOT)
+ {
+ idAST = idAST.getFirstChild().getNextSibling();
+ }
+ idAST.setText(str + idAST.getText());
+ }
+
+ private readonly static string[] javaReserved = new string[] { "int", "protected", "package" };
+
+ protected void fixBrokenIds(ASTNode id)
+ {
+ if (id.Type == T.IDENTIFIER)
+ {
+ foreach (string k in javaReserved)
+ {
+ if (k == id.getText())
+ {
+ id.setText("__" + id.getText());
+ break;
+ }
+ }
+ }
+ }
+
+ protected string escapeJavaString(string rawStr)
+ {
+ StringBuilder buf = new StringBuilder(rawStr.Length * 2);
+ bool seenDQ = false;
+ foreach (char ch in rawStr)
+ {
+ switch (ch)
+ {
+ case '\\':
+ buf.Append("\\\\");
+ break;
+ case '"':
+ if (seenDQ)
+ buf.Append("\\\"");
+ seenDQ = !seenDQ;
+ break;
+ case '\'':
+ buf.Append("\\'");
+ break;
+ case '\b':
+ buf.Append("\\b");
+ break;
+ case '\t':
+ buf.Append("\\t");
+ break;
+ case '\n':
+ buf.Append("\\n");
+ break;
+ case '\f':
+ buf.Append("\\f");
+ break;
+ case '\r':
+ buf.Append("\\r");
+ break;
+ default:
+ buf.Append(ch);
+ break;
+ }
+ if (ch != '"')
+ seenDQ = false;
+ }
+ return buf.ToString();
+ }
+
+ protected Stack uPath = new Stack();
+
+ protected TypeRep mkType(string type)
+ {
+ return TypeRep.newInstance(type, uPath);
+ }
+
+ public ASTNode stripQualifier(ASTNode eAST)
+ {
+ if (eAST.Type == T.IDENTIFIER)
+ return (ASTNode) astFactory.dupTree(eAST);
+ else
+ return stripQualifier((ASTNode)eAST.getFirstChild().getNextSibling());
+ }
+
+ }
+
+
+}
diff --git a/CSharpTranslator/Translator/Main.cs b/CSharpTranslator/Translator/Main.cs
new file mode 100644
index 0000000..3f07b02
--- /dev/null
+++ b/CSharpTranslator/Translator/Main.cs
@@ -0,0 +1,590 @@
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+// bug(?) in DotGNU 0.6 - "using antlr" will workaround the problem.
+#if __CSCC__
+using antlr;
+#endif
+
+namespace RusticiSoftware.Translator
+{
+ using System;
+ using System.Collections;
+ using System.Xml;
+ using System.Xml.Serialization;
+
+ using FileInfo = System.IO.FileInfo;
+ using Directory = System.IO.Directory;
+ using FileStream = System.IO.FileStream;
+ using FileMode = System.IO.FileMode;
+ using FileAccess = System.IO.FileAccess;
+ using Stream = System.IO.Stream;
+ using StreamReader = System.IO.StreamReader;
+ using StringWriter = System.IO.StringWriter;
+ using StreamWriter = System.IO.StreamWriter;
+ using Path = System.IO.Path;
+ using DirectoryInfo = System.IO.DirectoryInfo;
+ using TextWriter = System.IO.TextWriter;
+ using File = System.IO.File;
+ using XmlTextWriter = System.Xml.XmlTextWriter;
+
+ using BaseAST = antlr.BaseAST;
+ using CommonAST = antlr.CommonAST;
+ using ASTFactory = antlr.ASTFactory;
+ using RecognitionException = antlr.RecognitionException;
+ using AST = antlr.collections.AST;
+ using ASTFrame = antlr.debug.misc.ASTFrame;
+ using IToken = antlr.IToken;
+ using TokenStream = antlr.TokenStream;
+ using TokenStreamSelector = antlr.TokenStreamSelector;
+ using TokenStreamHiddenTokenFilter = antlr.TokenStreamHiddenTokenFilter;
+
+ using IEnumerator = System.Collections.IEnumerator;
+ using System.Reflection;
+
+ class AppMain
+ {
+ private const string VERSION = "2008.1.0.6617";
+
+ public delegate void FileProcessor(string fName, Stream s);
+
+ internal static bool showTree = false;
+ internal static bool showCSharp = false;
+ internal static bool showJavaSyntax = false;
+ internal static bool showJava = false;
+ // keving: We don't use the flex scanner (at least for now) and we don't pretty print CSharp
+// internal static bool printTree = false;
+// internal static bool useFlexLexer = false;
+ internal static bool displayTokens = false;
+ internal static bool dumpXMLs = false;
+ internal static string outDir = ".";
+ internal static string cheatDir = "";
+ internal static ArrayList netRoot = new ArrayList();
+ internal static ArrayList exNetRoot = new ArrayList();
+ internal static ArrayList appRoot = new ArrayList();
+ internal static ArrayList exAppRoot = new ArrayList();
+ internal static ArrayList exclude = new ArrayList();
+ internal static DirectoryHT appEnv = new DirectoryHT(null);
+ internal static XmlTextWriter enumXmlWriter;
+ internal static string xmldumpDir = Path.Combine(".", "tmpXMLs");
+ internal static int verbosity = 0;
+
+ internal static TokenStreamHiddenTokenFilter filter;
+
+
+ internal static int numFilesSuccessfullyProcessed = 0;
+ internal static int numFilesProcessed = 0;
+
+ private static void showVersion()
+ {
+ Console.Out.WriteLine(Path.GetFileNameWithoutExtension(System.Environment.GetCommandLineArgs()[0]) + ": " + VERSION);
+ }
+
+ private static void showUsage()
+ {
+ Console.Out.WriteLine("Usage: " + Path.GetFileNameWithoutExtension(System.Environment.GetCommandLineArgs()[0]));
+ Console.Out.WriteLine(" [-help] (this usage message)");
+ Console.Out.WriteLine(" [-v] (be [somewhat more] verbose, repeat for more verbosity)");
+ Console.Out.WriteLine(" [-showtokens] (the lexer prints the tokenized input to the console)");
+ Console.Out.WriteLine(" [-showtree][-showcsharp] [-showjavasyntax] [-showjava] (show parse tree at various stages of the translation)");
+ Console.Out.WriteLine(" [-dumpxml] [-xmldir ] (dump the translation repository as xml files)");
+ Console.Out.WriteLine(" [-dumpenums ] (create an xml file documenting enums)");
+ Console.Out.WriteLine(" [-odir ]");
+ Console.Out.WriteLine(" [-cheatdir ]");
+ Console.Out.WriteLine(" [-netdir +] (can be multiple directories, separated by semi-colons)");
+ Console.Out.WriteLine(" [-exnetdir +] (can be multiple directories/files, separated by semi-colons)");
+ Console.Out.WriteLine(" [-appdir ]");
+ Console.Out.WriteLine(" [-exappdir +] (can be multiple directories/files, separated by semi-colons)");
+ Console.Out.WriteLine(" [-exclude +] (can be multiple directories/files, separated by semi-colons)");
+ Console.Out.WriteLine(" ");
+ Environment.Exit(0);
+ }
+
+ public static void Main(string[] args)
+ {
+ long startTime = DateTime.Now.Ticks;
+ // Use a try/catch block for parser exceptions
+ try
+ {
+ // if we have at least one command-line argument
+ if (args.Length > 0)
+ {
+ if (verbosity >= 2) Console.Error.WriteLine("Parsing...");
+ // for each directory/file specified on the command line
+ for (int i = 0; i < args.Length; i++)
+ {
+ if (args[i].ToLower().Equals("-showtree"))
+ {
+ showTree = true;
+ }
+ else if (args[i].ToLower().Equals("-showcsharp"))
+ {
+ showCSharp = true;
+ }
+ else if (args[i].ToLower().Equals("-showjava"))
+ {
+ showJava = true;
+ }
+ else if (args[i].ToLower().Equals("-showjavasyntax"))
+ {
+ showJavaSyntax = true;
+ }
+ else if (args[i].ToLower().Equals("-tokens"))
+ {
+ displayTokens = true;
+ }
+ else if (args[i].ToLower().Equals("-dumpxml"))
+ {
+ dumpXMLs = true;
+ }
+ else if (args[i].ToLower().Equals("-v"))
+ {
+ verbosity++;
+
+ // in verbose mode, echo back the command line (so if command line is generated by another tool that does not
+ // echo it, it can still be seen in the logs.
+ Console.Write(Assembly.GetExecutingAssembly().Location + " ");
+ foreach (string arg in args)
+ {
+ Console.Write(arg + " ");
+ }
+ Console.WriteLine(System.Environment.NewLine);
+
+ }
+ else if (args[i].ToLower().Equals("-help"))
+ {
+ showUsage();
+ }
+ else if (args[i].ToLower().Equals("-version"))
+ {
+ showVersion();
+ }
+ else if (args[i].ToLower().Equals("-odir") && i < (args.Length - 1))
+ {
+ i++;
+ outDir = args[i];
+ }
+ else if (args[i].ToLower().Equals("-dumpenums") && i < (args.Length - 1))
+ {
+ i++;
+ enumXmlWriter = new XmlTextWriter(args[i], System.Text.Encoding.UTF8);
+ enumXmlWriter.WriteStartElement("enums");
+ }
+ else if (args[i].ToLower().Equals("-cheatdir") && i < (args.Length - 1))
+ {
+ i++;
+ cheatDir = args[i];
+ }
+ else if (args[i].ToLower().Equals("-netdir") && i < (args.Length - 1))
+ {
+ i++;
+ string[] argDirs = args[i].Split(';');
+ for (int j = 0; j < argDirs.Length; j++)
+ argDirs[j] = Path.GetFullPath(argDirs[j]).ToLower();
+ netRoot.AddRange(argDirs);
+ }
+ else if (args[i].ToLower().Equals("-exnetdir") && i < (args.Length - 1))
+ {
+ i++;
+ string[] argDirs = args[i].Split(';');
+ for (int j = 0; j < argDirs.Length; j++)
+ argDirs[j] = Path.GetFullPath(argDirs[j]).ToLower();
+ exNetRoot.AddRange(argDirs);
+ }
+ else if (args[i].ToLower().Equals("-appdir") && i < (args.Length - 1))
+ {
+ i++;
+ string[] argDirs = args[i].Split(';');
+ for (int j = 0; j < argDirs.Length; j++)
+ argDirs[j] = Path.GetFullPath(argDirs[j]).ToLower();
+ appRoot.AddRange(argDirs);
+ }
+ else if (args[i].ToLower().Equals("-exappdir") && i < (args.Length - 1))
+ {
+ i++;
+ string[] argDirs = args[i].Split(';');
+ for (int j = 0; j < argDirs.Length; j++)
+ argDirs[j] = Path.GetFullPath(argDirs[j]).ToLower();
+ exAppRoot.AddRange(argDirs);
+ }
+ else if (args[i].ToLower().Equals("-exclude") && i < (args.Length - 1))
+ {
+ i++;
+ string[] argDirs = args[i].Split(';');
+ for (int j = 0; j < argDirs.Length; j++)
+ argDirs[j] = Path.GetFullPath(argDirs[j]).ToLower();
+ exclude.AddRange(argDirs);
+ }
+ else if (args[i].ToLower().Equals("-xmldir") && i < (args.Length - 1))
+ {
+ i++;
+ xmldumpDir = args[i];
+ }
+ else
+ {
+ // Final argument is translation target
+
+ // Load .Net templates
+ numFilesSuccessfullyProcessed = 0;
+ numFilesProcessed = 0;
+
+ foreach (string r in netRoot)
+ doFile(new FileInfo(r), ".xml", addNetTranslation, exNetRoot);
+
+ Console.Out.WriteLine(String.Format("\nFound {0} .Net template files ({1} processed successfully)\n", numFilesProcessed, numFilesSuccessfullyProcessed));
+
+ // Load Application Class Signatures (i.e. generate templates)
+ if (appRoot.Count == 0)
+ // By default translation target is application root
+ appRoot.Add(args[i]);
+
+ numFilesSuccessfullyProcessed = 0;
+ numFilesProcessed = 0;
+
+ foreach (string r in appRoot)
+ doFile(new FileInfo(r), ".cs", addAppSigTranslation, exAppRoot); // parse it
+
+ Console.Out.WriteLine(String.Format("\nFound {0} cs files in the application ({1} processed successfully)\n", numFilesProcessed, numFilesSuccessfullyProcessed));
+
+ if (dumpXMLs)
+ {
+ // Get package name and convert to directory name
+ foreach (DictionaryEntry de in appEnv)
+ {
+ String xmlFName = Path.Combine(xmldumpDir,
+ ((string)de.Key).Replace('.', Path.DirectorySeparatorChar) + ".xml");
+ String xmlFDir = Path.GetDirectoryName(xmlFName);
+ if (!Directory.Exists(xmlFDir))
+ {
+ Directory.CreateDirectory(xmlFDir);
+ }
+ XmlSerializer s = new XmlSerializer(de.Value.GetType());
+ TextWriter w = new StreamWriter(xmlFName);
+ s.Serialize(w, de.Value);
+ w.Close();
+ }
+ }
+ numFilesSuccessfullyProcessed = 0;
+ numFilesProcessed = 0;
+
+ doFile(new FileInfo(args[i]), ".cs", translateFile, exclude); // parse it
+
+ if (numFilesProcessed == 0) {
+ Console.Out.WriteLine("\nWARNING: Did not find any cs files to translate\n");
+ }
+ else {
+ Console.Out.WriteLine(String.Format("\nTranslated {0} cs files ({1} processed somewhat successfully)\n", numFilesProcessed, numFilesSuccessfullyProcessed));
+ }
+ if (enumXmlWriter != null)
+ {
+ enumXmlWriter.WriteEndElement();
+ enumXmlWriter.Close();
+ }
+ }
+ }
+ }
+ else
+ {
+ showUsage();
+ }
+ }
+ catch (System.Exception e)
+ {
+ Console.Error.WriteLine("exception: " + e);
+ Console.Error.WriteLine(e.StackTrace); // so we can get stack trace
+ }
+ double elapsedTime = ((DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond) / 1000.0;
+ if (verbosity >= 1)
+ {
+ System.Console.Out.WriteLine("");
+ System.Console.Out.WriteLine("");
+ System.Console.Out.WriteLine("Total run time was {0} seconds.", elapsedTime);
+ }
+ }
+
+
+ // Call processFile on all files below f that have the given extension
+ public static void doFile(FileInfo f, string ext, FileProcessor processFile, ArrayList excludes)
+ {
+ // If this is a directory, walk each file/dir in that directory
+ if (!excludes.Contains(Path.GetFullPath(f.FullName).ToLower()))
+ {
+ if (Directory.Exists(f.FullName))
+ {
+ string[] files = Directory.GetFileSystemEntries(f.FullName);
+ for (int i = 0; i < files.Length; i++)
+ doFile(new FileInfo(Path.Combine(f.FullName, files[i])), ext, processFile, excludes);
+ }
+ else if ((f.Name.Length > ext.Length) && f.Name.Substring(f.Name.Length - ext.Length).Equals(ext))
+ {
+ FileStream fs = null;
+ if (verbosity >= 2) Console.WriteLine(" " + f.FullName);
+ try
+ {
+ fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read);
+ processFile(f.FullName, fs);
+ numFilesSuccessfullyProcessed++;
+ }
+ catch (Exception e)
+ {
+ Console.Error.WriteLine("\nCannot process file: " + f.FullName);
+ Console.Error.WriteLine("exception: " + e);
+ }
+ finally
+ {
+ if (fs != null) fs.Close();
+ numFilesProcessed++;
+ }
+ }
+ }
+ }
+
+ public static ASTNode parseFile(string f, Stream s)
+ {
+ ASTNode ret = null;
+ try
+ {
+ // Define a selector that can switch from the C# codelexer to the C# preprocessor lexer
+ TokenStreamSelector selector = new TokenStreamSelector();
+
+ TokenStream lexer;
+ CSharpLexer antlrLexer = new CSharpLexer(new StreamReader(s));
+
+ antlrLexer.Selector = selector;
+ antlrLexer.setFilename(f);
+ CSharpPreprocessorLexer preproLexer = new CSharpPreprocessorLexer(antlrLexer.getInputState());
+ preproLexer.Selector = selector;
+ CSharpPreprocessorHooverLexer hooverLexer = new CSharpPreprocessorHooverLexer(antlrLexer.getInputState());
+ hooverLexer.Selector = selector;
+
+ // use the special token object class
+ antlrLexer.setTokenCreator(new CustomHiddenStreamToken.CustomHiddenStreamTokenCreator());
+ antlrLexer.setTabSize(1);
+ preproLexer.setTokenCreator(new CustomHiddenStreamToken.CustomHiddenStreamTokenCreator());
+ preproLexer.setTabSize(1);
+ hooverLexer.setTokenCreator(new CustomHiddenStreamToken.CustomHiddenStreamTokenCreator());
+ hooverLexer.setTabSize(1);
+
+ // notify selector about various lexers; name them for convenient reference later
+ selector.addInputStream(antlrLexer, "codeLexer");
+ selector.addInputStream(preproLexer, "directivesLexer");
+ selector.addInputStream(hooverLexer, "hooverLexer");
+ selector.select("codeLexer"); // start with main the CSharp code lexer
+ lexer = selector;
+
+ // create the stream filter; hide WS and SL_COMMENT
+ if (displayTokens)
+ filter = new TokenStreamHiddenTokenFilter(new LoggingTokenStream(lexer));
+ else
+ filter = new TokenStreamHiddenTokenFilter(lexer);
+
+ filter.hide(CSharpJavaTokenTypes.WHITESPACE);
+ filter.hide(CSharpJavaTokenTypes.NEWLINE);
+ filter.hide(CSharpJavaTokenTypes.ML_COMMENT);
+ filter.hide(CSharpJavaTokenTypes.SL_COMMENT);
+
+ // Create a parser that reads from the scanner
+ CSharpParser parser = new CSharpParser(filter);
+
+ // create trees that copy hidden tokens into tree also
+ parser.setASTNodeClass(typeof(ASTNode).FullName);
+ parser.setASTFactory(new ASTNodeFactory());
+ CSharpParser.initializeASTFactory(parser.getASTFactory());
+ parser.setFilename(f);
+ //parser.getASTFactory().setASTNodeCreator(new ASTNode.ASTNodeCreator());
+
+ // start parsing at the compilationUnit rule
+ long startTime = DateTime.Now.Ticks;
+ parser.compilationUnit();
+ double elapsedTime = ((DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond) / 1000.0;
+ if (verbosity >= 2) System.Console.Out.WriteLine("Parsed {0} in: {1} seconds.", f, elapsedTime);
+
+ BaseAST.setVerboseStringConversion(true, parser.getTokenNames());
+ ret = (ASTNode)parser.getAST();
+ }
+ catch (System.Exception e)
+ {
+ Console.Error.WriteLine("parser exception: " + e);
+ Console.Error.WriteLine(e.StackTrace); // so we can get stack trace
+ }
+ return ret;
+ }
+
+ // Here's where we do the real work...
+ public static void addNetTranslation(string fullName, Stream s)
+ {
+ TypeRepTemplate t = TypeRepTemplate.newInstance(s);
+ appEnv[t.TypeName] = t;
+ }
+
+ // Here's where we do the real work...
+ public static void addAppSigTranslation(string fullName, Stream s)
+ {
+ string f = Path.GetFileName(fullName);
+
+ ASTNode t = parseFile(f, s);
+ if (t != null)
+ {
+ // A prescan of all files to build an environment mapping qualified name to typereptemplate
+ CSharpEnvBuilder envBuilder = new CSharpEnvBuilder();
+ envBuilder.compilationUnit(t, null, appEnv);
+ }
+ }
+
+ // Here's where we do the real work...
+ public static void translateFile(string fullName, Stream s)
+ {
+ string f = Path.GetFileName(fullName);
+
+ ASTNode t = parseFile(f, s);
+ if (t != null)
+ {
+ if (showTree)
+ {
+ ASTNode r = (ASTNode)new ASTNodeFactory().create(0, "AST ROOT");
+ r.setFirstChild(t);
+ ASTFrame frame = new ASTFrame("C# AST for file [" + f + "]", r);
+ frame.ShowDialog();
+ //frame.Visible = true;
+ // System.out.println(t.toStringList());
+ }
+ ASTNode r1 = (ASTNode)new ASTNodeFactory().create(0, "AST ROOT");
+ r1.setFirstChild(t);
+ ASTFrame frame1 = new ASTFrame("C# AST for file [" + f + "]", r1);
+ if (showCSharp)
+ frame1.ShowDialog();
+
+ CSharpTranslator transformer = new CSharpTranslator();
+ transformer.setASTNodeClass(typeof(ASTNode).FullName);
+ transformer.setASTFactory(new ASTNodeFactory());
+ CSharpTranslator.initializeASTFactory(transformer.getASTFactory());
+
+ long startTime = DateTime.Now.Ticks;
+ transformer.compilationUnit(t, null);
+
+ //BaseAST.setVerboseStringConversion(true, tokenNames);
+ ASTNode r2 = (ASTNode)new ASTNodeFactory().create(0, "AST ROOT");
+ r2.setFirstChild(transformer.getAST());
+ ASTFrame frame2 = new ASTFrame("Java syntax AST for file [" + f + "]", r2);
+ if (showJavaSyntax)
+ frame2.ShowDialog();
+
+ // Take each java compilation unit (each class defn) and write it to the appropriate file
+ IEnumerator enumCU = transformer.getAST().findAllPartial((ASTNode)transformer.getASTFactory().create(CSharpParser.COMPILATION_UNIT));
+ while (enumCU.MoveNext())
+ {
+ ASTNode javaCU = (ASTNode)enumCU.Current;
+
+ // Extract class/interface name
+ String claName = JavaTreeParser.getClassName(javaCU);
+
+ // Get package name and convert to directory name
+ String nsDir = "";
+ foreach (String nsc in JavaTreeParser.getPackageName(javaCU))
+ {
+ nsDir = Path.Combine(nsDir, nsc);
+ }
+
+ // Build destination filename for this class
+ String fName = Path.Combine(Path.Combine(outDir, nsDir), claName + ".java");
+
+ if (cheatDir != "")
+ {
+ String cheatFile = Path.Combine(cheatDir, Path.Combine(nsDir, claName + ".java"));
+ if (File.Exists(cheatFile))
+ {
+ // the old switcheroo
+ File.Copy(cheatFile, fName,true);
+ continue;
+ }
+
+ String ignoreMarker = Path.Combine(cheatDir, Path.Combine(nsDir, claName + ".none"));
+ if (File.Exists(ignoreMarker))
+ {
+ // Don't generate this class
+ continue;
+ }
+ }
+
+ NetTranslator netTx = new NetTranslator();
+ netTx.setASTNodeClass(typeof(ASTNode).FullName);
+ netTx.setASTFactory(new ASTNodeFactory());
+ NetTranslator.initializeASTFactory(netTx.getASTFactory());
+ netTx.compilationUnit(javaCU, null, appEnv);
+
+ //BaseAST.setVerboseStringConversion(true, tokenNames);
+ ASTNode r3 = (ASTNode)new ASTNodeFactory().create(0, "AST ROOT");
+ r3.setFirstChild(netTx.getAST());
+ ASTFrame frame3 = new ASTFrame("Java AST for file [" + f + "]", r3);
+ if (showJava)
+ frame3.ShowDialog();
+
+ Console.WriteLine(fName);
+
+ String fDir = Path.GetDirectoryName(fName);
+ if (!Directory.Exists(fDir))
+ {
+ Directory.CreateDirectory(fDir);
+ }
+ FileInfo outF = new FileInfo(fName);
+ StreamWriter w = new StreamWriter(outF.Create());
+ JavaPrettyPrinter writer = new JavaPrettyPrinter();
+ writer.compilationUnit(netTx.getAST(), w, enumXmlWriter, filter);
+ w.Close();
+
+ }
+
+ double elapsedTime = ((DateTime.Now.Ticks - startTime) / TimeSpan.TicksPerMillisecond) / 1000.0;
+ //System.Console.Out.WriteLine(writer.ToString());
+ System.Console.Out.WriteLine("");
+ System.Console.Out.WriteLine("");
+ System.Console.Out.WriteLine("Pretty-printed {0} in: {1} seconds.", f, elapsedTime);
+ }
+ }
+ }
+
+ class LoggingTokenStream : TokenStream
+ {
+ TokenStream source;
+
+ public LoggingTokenStream(TokenStream source)
+ {
+ this.source = source;
+ }
+
+ public IToken nextToken()
+ {
+ IToken tok = source.nextToken();
+ if (tok != null)
+ Console.Out.WriteLine(tok.ToString());
+
+ return tok;
+ }
+ }
+}
diff --git a/CSharpTranslator/Translator/NetTranslator.g b/CSharpTranslator/Translator/NetTranslator.g
new file mode 100644
index 0000000..fcd45e2
--- /dev/null
+++ b/CSharpTranslator/Translator/NetTranslator.g
@@ -0,0 +1,1422 @@
+header {
+ using System.IO;
+ using System.Collections;
+ using Directory = System.IO.Directory;
+ using System.Xml.Serialization;
+ using Path = System.IO.Path;
+}
+
+options {
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/** NetTranslator: Converts .Net calls to Java API calls
+ *
+ * Author: Kevin Glynn
+ *
+ * This grammar is based on the java tree walker included in ANTLR examples
+ *
+ */
+
+class NetTranslator extends TreeParser("RusticiSoftware.Translator.NetTranslatorBase");
+
+options {
+ importVocab = CSharpJava;
+ buildAST = true;
+ ASTLabelType = "ASTNode";
+ defaultErrorHandler = true;
+}
+{
+ // track current namespace
+ private string nameSpace = "";
+
+ // track current level of switch statement so that we generate unique scrutinee variables
+ private int scrutineeCounter = 0;
+
+ // track current level of foreach statement so that we generate unique temp variables
+ private int foreachCounter = 0;
+
+ // expr.
+ // accessAST:#( MEMBER_ACCESS_EXPR thisAST:expr fieldNm:IDENTIFIER )
+ private ASTNode ResolveGetter(ASTNode accessAST)
+ {
+ ASTNode retAST = null;
+ ASTNode thisAST = (ASTNode) accessAST.getFirstChild();
+ string fieldNm = thisAST.getNextSibling().getText();
+ FieldRep fldProp = thisAST.DotNetType.Resolve(fieldNm);
+ if (fldProp != null)
+ {
+ string getter = fldProp.Get;
+ this.addImport(fldProp.Imports);
+ bool thisIsDummyThis = thisAST.Type == THIS && thisAST.getText() == "DUMMYTHIS";
+ if (getter == null)
+ {
+ string newFieldNm = fieldNm;
+ if (fldProp is PropRep)
+ newFieldNm = "get" + newFieldNm + "()";
+
+ ASTNode newFieldAST = #( [IDENTIFIER, newFieldNm] );
+
+ if (thisIsDummyThis)
+ retAST = newFieldAST;
+ else
+ retAST = #( [MEMBER_ACCESS_EXPR], astFactory.dupTree(thisAST), newFieldAST );
+ }
+ else
+ retAST = (ASTNode) #( [JAVAWRAPPER], [IDENTIFIER, getter],
+ [IDENTIFIER, "${this}"],
+ astFactory.dupTree(thisAST) );
+ retAST.DotNetType = fldProp.Type;
+ }
+ return retAST;
+ }
+
+ // expr. = value
+ // accessAST: #( ASSIGN targetAST:#( MEMBER_ACCESS_EXPR thisAST:expr fieldNm:IDENTIFIER ) valueAST:expr[w] )
+ private ASTNode ResolveSetter(ASTNode assignAST)
+ {
+ ASTNode retAST = null;
+ ASTNode targetAST = (ASTNode) assignAST.getFirstChild();
+ ASTNode valueAST = (ASTNode) targetAST.getNextSibling();
+ ASTNode thisAST = (ASTNode) targetAST.getFirstChild();
+ string fieldNm = thisAST.getNextSibling().getText();
+ FieldRep fldProp = thisAST.DotNetType.Resolve(fieldNm);
+ if (fldProp != null)
+ {
+ string setter = fldProp.Set;
+ this.addImport(fldProp.Imports);
+ bool thisIsDummyThis = thisAST.Type == THIS && thisAST.getText() == "DUMMYTHIS";
+ if (thisIsDummyThis)
+ thisAST.setText("this");
+ if (setter == null)
+ {
+ // assignment of an application property or field
+ if (fldProp is PropRep)
+ setter = (thisIsDummyThis ? "" : "${this}.") + "set" + fieldNm + "(${value})";
+ else
+ setter = (thisIsDummyThis ? "" : "${this}.") + fieldNm + " = ${value}";
+ }
+ retAST = (ASTNode) #( [JAVAWRAPPER], [IDENTIFIER, setter],
+ [IDENTIFIER, "${this}"],
+ astFactory.dupTree(thisAST),
+ [IDENTIFIER, "${value}"],
+ astFactory.dupTree(valueAST) );
+ retAST.DotNetType = mkType("System.Void");
+ }
+ return retAST;
+ }
+
+ // new T()
+ // newAST:#( OBJ_CREATE_EXPR #( TYPE type #( ARRAY_RANKS ) ) #( [ELIST] args ) )
+ private ASTNode ResolveNewObj(ASTNode newAST)
+ {
+ ASTNode retAST = null;
+ ASTNode typeAST = (ASTNode) newAST.getFirstChild().getFirstChild();
+
+ ArrayList argVs = new ArrayList();
+ ASTNode argAST = (ASTNode) newAST.getFirstChild().getNextSibling().getFirstChild();
+ while (argAST != null)
+ {
+ argVs.Add(astFactory.dupTree(argAST));
+ argAST = (ASTNode) argAST.getNextSibling();
+ }
+
+ ClassRep typeClass = typeAST.DotNetType as ClassRep; // If type wasn't found then we will have an InterfaceRep
+
+ ConstructorRep constructor = (typeClass == null ? null : typeClass.Resolve(argVs));
+
+ if (constructor != null && constructor.Java != null)
+ {
+ retAST = (ASTNode) #( [JAVAWRAPPER], [IDENTIFIER, constructor.Java]);
+ for (int i = 0; i < argVs.Count; i++)
+ {
+ string templateVar = "${" + constructor.Params[i].Name + "}";
+ retAST.addChild( #( [IDENTIFIER, templateVar] ) );
+ retAST.addChild( (ASTNode) argVs[i] );
+ }
+ this.addImport(constructor.Imports);
+ retAST.DotNetType = typeAST.DotNetType;
+ }
+
+ return retAST;
+ }
+
+ // expr.(expr*)
+ // invokeAST:#( INVOCATION_EXPR #( MEMBER_ACCESS_EXPR thisAST:expr methodNm:IDENTIFIER)
+ // #( [ELIST] args ) )
+ private ASTNode ResolveMethod(ASTNode invokeAST)
+ {
+ ASTNode retAST = null;
+ ASTNode thisAST = (ASTNode) invokeAST.getFirstChild().getFirstChild();
+ string methodNm = thisAST.getNextSibling().getText();
+
+ ArrayList argVs = new ArrayList();
+ ASTNode argAST = (ASTNode) invokeAST.getFirstChild().getNextSibling().getFirstChild();
+ while (argAST != null)
+ {
+ argVs.Add(astFactory.dupTree(argAST));
+ argAST = (ASTNode) argAST.getNextSibling();
+ }
+
+ MethodRep method = thisAST.DotNetType.Resolve(methodNm, argVs);
+
+ if (method != null) {
+ bool thisIsDummyThis = thisAST.Type == THIS && thisAST.getText() == "DUMMYTHIS";
+ if (thisIsDummyThis)
+ thisAST.setText("this"); // if we need 'this' below, then it better not be 'dummythis'
+ if (method.Java == null)
+ {
+ ASTNode methodAST = (ASTNode) (thisIsDummyThis ? #([IDENTIFIER, methodNm]) : astFactory.dupTree(invokeAST.getFirstChild()));
+ ASTNode argsElistAST = (ASTNode) astFactory.dupTree(invokeAST.getFirstChild().getNextSibling());
+ retAST = #( [INVOCATION_EXPR], methodAST, argsElistAST);
+ }
+ else
+ {
+ retAST = (ASTNode) #( [JAVAWRAPPER], [IDENTIFIER, method.Java],
+ [IDENTIFIER, "${this}"],
+ astFactory.dupTree(thisAST));
+ for (int i = 0; i < argVs.Count; i++)
+ {
+ ASTNode arg = (ASTNode) argVs[i];
+ string templateVar = "${" + method.Params[i].Name + "}";
+ retAST.addChild( #( [IDENTIFIER, templateVar] ) );
+ retAST.addChild( astFactory.dupTree(arg) );
+ // Support for extracting type name from typeof() expressions
+ // typeof() has been transformed to #( [EXPR], #( [JAVAWRAPPER], [IDENTIFIER, ".class"] ) )
+ if (method.Params[i].Name.StartsWith("TYPEOF") &&
+ arg.getFirstChild().Type == JAVAWRAPPER &&
+ arg.getFirstChild().getFirstChild().getText().EndsWith(".class"))
+ {
+ string classCall = arg.getFirstChild().getFirstChild().getText();
+ string typeName = classCall.Substring(0, classCall.Length - 6); // remove trailing ".class"
+ retAST.addChild( #( [IDENTIFIER, "${TYPEOF_TYPE}"] ) );
+ retAST.addChild( #( [IDENTIFIER, typeName] ) );
+
+ }
+ }
+ }
+ retAST.DotNetType = method.Return;
+ this.addImport(method.Imports);
+ }
+ return retAST;
+ }
+
+ // (type) expr
+ // castAST:#( CAST_EXPR tyAST:typeSpec[w] exprAST:expr[w] )
+ private ASTNode ResolveCast(ASTNode castAST)
+ {
+ ASTNode retAST = null;
+ ASTNode tyAST = (ASTNode) castAST.getFirstChild();
+ ASTNode exprAST = (ASTNode) castAST.getFirstChild().getNextSibling();
+ string template = null;
+
+ // We first look for a way to cast expression TO type
+ CastRep cast = tyAST.DotNetType.ResolveCastFrom(exprAST.DotNetType);
+
+ if (cast != null)
+ {
+ // Initialize template
+ template = cast.Java;
+ if (template == null)
+ template = "${to_type}.__castTo${to_type_id}(${expr})";
+ }
+ else
+ {
+ // If we can't cast TO type, can we cast to type FROM expr' type?
+ cast = exprAST.DotNetType.ResolveCastTo(tyAST.DotNetType);
+ if (cast != null)
+ {
+ // Initialize Template
+ template = cast.Java;
+ if (template == null)
+ template = "${from_type}.__castTo${to_type_id}(${expr})";
+ }
+ }
+ if (cast != null)
+ {
+ // We have found an appropriate castercast.Java;
+
+ retAST = (ASTNode) #( [JAVAWRAPPER], [IDENTIFIER, template],
+ [IDENTIFIER, "${expr}"],
+ astFactory.dupTree(exprAST),
+ [IDENTIFIER, "${to_type}"],
+ [IDENTIFIER, tyAST.DotNetType.TypeName],
+ [IDENTIFIER, "${from_type}"],
+ [IDENTIFIER, exprAST.DotNetType.TypeName],
+ [IDENTIFIER, "${to_type_id}"],
+ [IDENTIFIER, typeNameToId(tyAST.DotNetType.TypeName)],
+ [IDENTIFIER, "${from_type_id}"],
+ [IDENTIFIER, typeNameToId(exprAST.DotNetType.TypeName)]
+ );
+ retAST.DotNetType = tyAST.DotNetType;
+ this.addImport(cast.Imports);
+ }
+
+ return retAST;
+ }
+
+
+ // true iff n is being assigned to
+ private bool SetterContext(ASTNode n)
+ {
+
+ int parentType = n.getParent().Type;
+
+ if (n.getPreviousSibling() != null)
+ return false;
+
+ return (parentType == ASSIGN);
+ }
+
+ // Note, that in Java 6.0 there is getTypeUtils() that could be used to do this conversion
+ private Hashtable boxTypeMap = new Hashtable();
+
+ // If typeAST is one of the Java unboxed types (char, int, etc.) convert to boxed equivalent (Character, Integer, etc.)
+ // updates type name in place!
+ private ASTNode boxedType(ASTNode typeAST)
+ {
+ string type = typeAST.getFirstChild().getText();
+ if (boxTypeMap.Contains(type))
+ typeAST.getFirstChild().setText((string)boxTypeMap[type]);
+ return typeAST;
+ }
+
+ private void netTranslatorInit()
+ {
+ // Initialize boxTypeMap (see JLS, ed 3 sec 5.1.7)
+ boxTypeMap["boolean"] = "Boolean";
+ boxTypeMap["byte"] = "Byte";
+ boxTypeMap["char"] = "Character";
+ boxTypeMap["short"] = "Short";
+ boxTypeMap["int"] = "Integer";
+ boxTypeMap["long"] = "Long";
+ boxTypeMap["float"] = "Float";
+ boxTypeMap["double"] = "Double";
+ //initialize(netLib);
+ initialize();
+ }
+
+}
+
+
+
+compilationUnit [object w, DirectoryHT env]
+ {
+ netTranslatorInit();
+ TypeRep.Initialize(env);
+ // TypeRep.Test();
+ //this.ExtendEnvFromNS("Predefined");
+ //this.appEnv = env;
+ //TypeRepTemplate.ExtendTranslationCache(env);
+ uPath.Push("System"); // C# assumes access to built-in types such as String, Decimal, ...
+ }
+ :! #( COMPILATION_UNIT
+ p:packageDefinition[w]
+ u:useDefinitions[w]
+ importDefinitions[w]
+ t:typeDefinition[w] { ## = #( [COMPILATION_UNIT], #p, #u, GetImports(), #t ); }
+ )
+ ;
+
+packageDefinition [object w]
+ : #( PACKAGE_DEF (id:identifier[w] {
+ // keving:
+ // current namespace should be on top of stack, add it when we do search
+ // uPath.Push(idToString(#id));
+ //ExtendSymTabFromNS(idToString(#id));
+ nameSpace = idToString(#id);
+ } )? )
+ ;
+
+useDefinitions [object w]
+ : #( USING_DIRECTIVES
+ (useDefinition[w])*
+ )
+ ;
+
+useDefinition [object w]
+ : #( USING_NAMESPACE_DIRECTIVE
+ use:identifier[w] { string ns = idToString(#use);
+ if (!ns.StartsWith("System") && !ns.StartsWith("Microsoft"))
+ this.addImport(ns + ".*");
+ uPath.Push(ns);
+ //ExtendSymTabFromNS(ns);
+ }
+ )
+ | #( USING_ALIAS_DIRECTIVE
+ alias:identifier[w]
+ aid:identifier[w] { uPath.Push(idToString(#alias) + "=" + idToString(#aid)); }
+ )
+ ;
+
+importDefinitions [object w]
+ : #( IMPORTS
+ ( (importDefinition[w])+ )?
+ )
+ ;
+
+importDefinition [object w]
+ : #( IMPORT
+ id:identifier[w] { this.addImport(#id.getText()); }
+ )
+ ;
+
+typeDefinition [object w]
+ {
+ string saveClass = this.ClassInProcess;
+ TypeRep saveThis = symtab["this"];
+ TypeRep saveSuper = symtab["super"];
+ }
+ :! #(CLASS
+ m:modifiers[w]
+ cn:IDENTIFIER { uPath.Push(nameSpace); uPath.Push(nameSpace + "." + #cn.getText());
+ symtab["this"] = mkType(#cn.getText());
+ symtab["super"] = symtab["this"].Extends;
+ this.ClassInProcess = #cn.getText(); }
+ b:classBase[w]
+ o:objBlock[w] { uPath.Pop(); uPath.Pop(); }
+ )
+
+ {
+ ASTNode baseClause = #( [EXTENDS_CLAUSE, "extends"] );
+ ASTNode ifClause = #( [IMPLEMENTS_CLAUSE, "implements"] );
+
+ ASTNode inherits = (ASTNode) #b.getFirstChild();
+
+ while ( inherits != null)
+ {
+ if (inherits.DotNetType is ClassRep)
+ baseClause.addChild( astFactory.dupTree(inherits) );
+ else
+ ifClause.addChild( astFactory.dupTree(inherits) );
+ inherits = (ASTNode) inherits.getNextSibling();
+ }
+
+ ## = #( [CLASS], #m, #cn, baseClause, ifClause, #o);
+ this.ClassInProcess = saveClass;
+ symtab["this"] = saveThis;
+ symtab["super"] = saveSuper;
+ }
+
+ | #(INTERFACE
+ modifiers[w]
+ ifn:IDENTIFIER { uPath.Push(nameSpace); uPath.Push(nameSpace + "." + #ifn.getText()); this.ClassInProcess = #ifn.getText(); }
+ implementsClause[w]
+ interfaceBlock[w]
+ { this.ClassInProcess = saveClass; } )
+ | #(ENUM
+ modifiers[w]
+ en:IDENTIFIER { uPath.Push(nameSpace); uPath.Push(nameSpace + "." + #en.getText()); this.ClassInProcess = #en.getText(); }
+ implementsClause[w]
+ enumBlock[w]
+ { this.ClassInProcess = saveClass; } )
+ | #(ANNOTATION
+ modifiers[w]
+ ann:IDENTIFIER { uPath.Push(nameSpace); uPath.Push(nameSpace + "." + #ann.getText()); this.ClassInProcess = #ann.getText(); }
+ anno:objBlock[w]
+ { this.ClassInProcess = saveClass; } )
+ ;
+
+classBase [Object w]
+ :
+ #( CLASS_BASE ( type[w] )* )
+ ;
+
+typeSpec! [object w]
+ : #(TYPE
+ t:type[w]
+ rs:rankSpecifiers[w]
+ {
+ string typeName = #t.DotNetType.TypeName;
+ ## = #( [TYPE], #t, #rs );
+ int numRanks = #rs.getNumberOfChildren();
+ for (int i = 0; i < numRanks; i++)
+ typeName += "[]";
+ ##.DotNetType = mkType(typeName);
+ }
+ )
+ ;
+
+ // Int[,][] arr;
+rankSpecifiers [object w]
+ : #( ARRAY_RANKS (rankSpecifier[w])* )
+ ;
+
+rankSpecifier [object w]
+ : #(ARRAY_RANK
+ ( COMMA // Notice, we ignore dimensions.
+ )*
+ )
+ ;
+
+typeSpecArray [object w]
+ : #( ARRAY_DECLARATOR
+ typeSpecArray[w]
+ )
+ | type[w]
+ ;
+
+type! [object w]
+ { TypeRep tyRep = null; }
+ : id:identifier[w] { tyRep = mkType(idToString(#id));
+ this.addImport(tyRep.Imports);
+ if (tyRep.Java != null)
+ ## = #([IDENTIFIER, tyRep.Java]);
+ else
+ ## = #id;
+ ##.DotNetType = tyRep;
+ }
+ | bt:builtInType[w] { tyRep = #bt.DotNetType;
+ this.addImport(tyRep.Imports);
+ if (tyRep.Java != null)
+ ## = #([IDENTIFIER, tyRep.Java]);
+ else
+ ## = #bt;
+ ##.DotNetType = tyRep;
+ }
+ | #(JAVAWRAPPER jid:identifier[w]) { ## = #jid; ##.DotNetType = mkType("A JAVA TYPE"); }
+ ;
+
+builtInType [object w]
+ : VOID { ##.DotNetType = mkType("System.Void"); }
+ | OBJECT { ##.DotNetType = mkType("System.Object"); }
+ | BOOL { ##.DotNetType = mkType("System.Boolean"); }
+ | STRING { ##.DotNetType = mkType("System.String"); }
+ | SBYTE { ##.DotNetType = mkType("System.SByte"); }
+ | "char" { ##.DotNetType = mkType("System.Char"); }
+ | "short" { ##.DotNetType = mkType("System.Int16"); }
+ | "int" { ##.DotNetType = mkType("System.Int32"); }
+ | "float" { ##.DotNetType = mkType("System.Single"); }
+ | "double" { ##.DotNetType = mkType("System.Double"); }
+ | "long" { ##.DotNetType = mkType("System.Int64"); }
+ | UBYTE { ##.DotNetType = mkType("System.Byte"); }
+ | DECIMAL { ##.DotNetType = mkType("System.Decimal"); }
+ | UINT { ##.DotNetType = mkType("System.UInt32"); }
+ | ULONG { ##.DotNetType = mkType("System.UInt64"); }
+ | USHORT { ##.DotNetType = mkType("System.UInt16"); }
+ | BYTE { ##.DotNetType = mkType("System.Byte"); } // What to do?
+ ;
+
+modifiers [object w]
+ : #( MODIFIERS (modifier[w]
+ )* )
+ ;
+
+modifier [object w]
+ : "private"
+ | "public"
+ | "protected"
+ | "static"
+ | "transient"
+ | FINAL
+ | ABSTRACT
+ | "native"
+ | "threadsafe"
+ | "synchronized"
+ | "const"
+ | "volatile"
+ | "strictfp"
+ ;
+
+extendsClause [object w]
+ //OK, OK, really we can only extend 1 class, but the tree stores a list so ....
+ : #(EXTENDS_CLAUSE
+ ( type[w] )*
+ )
+ ;
+
+implementsClause [object w]
+ : #(IMPLEMENTS_CLAUSE
+ ( type[w] )*
+ )
+ ;
+
+
+interfaceBlock [object w]
+ : #( MEMBER_LIST
+ ( methodDecl[w]
+ | variableDef[w, false]
+ | typeDefinition[w]
+ )*
+ )
+ ;
+
+objBlock [object w]
+ : #( MEMBER_LIST
+ ( ctorDef[w]
+ | methodDef[w]
+ | variableDef[w, true]
+ | typeDefinition[w]
+ | operatorDef[w]
+ | #(STATIC_CTOR_DECL
+ slist[w] )
+ | #(INSTANCE_INIT
+ slist[w] )
+ )*
+ )
+ ;
+
+enumBlock [object w]
+ : #( MEMBER_LIST
+ ( #( IDENTIFIER ( expression[w])?)
+ )*
+ )
+ ;
+
+ctorDef [object w]
+ : #(CTOR_DECL
+ modifiers[w]
+ methodHead[w]
+ (slist[w])?)
+ ;
+
+methodDecl [object w]
+ : #(METHOD_DECL
+ modifiers[w]
+ typeSpec[w]
+ methodHead[w])
+ ;
+
+methodDef [object w]
+ : #(METHOD_DECL
+ modifiers[w]
+ typeSpec[w] { symtab.PushLevel(); }
+ methodHead[w]
+ (slist[w])?
+ ) { symtab.PopLevel(); }
+ ;
+
+variableDef [object w, bool isCreate]
+ : #(FIELD_DECL
+ modifiers[w]
+ t:typeSpec[w]
+ (variableDeclarator[w, #t, isCreate])+
+ //varInitializer[w]
+ )
+ ;
+
+operatorDef [object w]
+ { ASTNode retAST = null;
+ }
+ : ( #( UNARY_OP_DECL modifiers[w]
+ typeSpec[w] overloadableUnaryOperator[w]
+ paramList[w]
+ slist[w]
+ )
+ | #( BINARY_OP_DECL modifiers[w]
+ typeSpec[w] overloadableBinaryOperator[w]
+ paramList[w]
+ slist[w]
+ )
+ |! // A Type conversion operator. We translate this to a method "__cast[To/From]()" method
+ // We treat both types as EXPLICIT because (at least for now) we need the explicit cast to tell
+ // us to resolve the conversion
+ #( CONV_OP_DECL m:modifiers[w] { retAST = #( [METHOD_DECL], astFactory.dupTree(#m) ); }
+ ( IMPLICIT | EXPLICIT ) it:typeSpec[w]
+ ips:paramList[w] ib:slist[w]
+ { string convertTo = #it.DotNetType.TypeName;
+ string convertFrom = ((ASTNode) #ips.getFirstChild().getFirstChild()).DotNetType.TypeName;
+ string currentClass = (nameSpace != ""? nameSpace + ".":"") + ClassInProcess;
+ bool isTo = convertTo == currentClass;
+ if (!isTo && convertFrom != currentClass)
+ {
+ Console.Error.Write("ERROR -- (Converting Cast Operator " + convertFrom + " to " + convertTo + ") ");
+ Console.Error.WriteLine("should match enclosing class " + currentClass);
+ }
+ string methodNm = "__castTo" + typeNameToId(convertTo);
+ retAST.addChild( astFactory.dupTree(#it) );
+ retAST.addChild( #([IDENTIFIER, methodNm]) );
+ retAST.addChild( astFactory.dupTree(#ips) );
+ retAST.addChild( #( [THROWS, "throws"], [IDENTIFIER, "Exception"] ) );
+ retAST.addChild( astFactory.dupTree(#ib) );
+ }
+ ) { ## = retAST; }
+ )
+ ;
+
+overloadableUnaryOperator [object w]
+ : UNARY_PLUS
+ | UNARY_MINUS
+ | LOG_NOT
+ | BIN_NOT
+ | INC
+ | DEC
+ | TRUE
+ | FALSE
+ ;
+
+overloadableBinaryOperator [object w]
+ :/*pl:*/PLUS
+ |/*ms:*/MINUS
+ |/*st:*/STAR
+ |/*dv:*/DIV
+ |/*md:*/MOD
+ |/*ba:*/BIN_AND
+ |/*bo:*/BIN_OR
+ |/*bx:*/BIN_XOR
+ |/*sl:*/SHIFTL
+ |/*sr:*/SHIFTR
+ |/*eq:*/EQUAL
+ |/*nq:*/NOT_EQUAL
+ |/*gt:*/GTHAN
+ |/*lt:*/LTHAN
+ |/*ge:*/GTE
+ |/*le:*/LTE
+ ;
+
+parameterDef [object w]
+ : #(PARAMETER_FIXED
+ t:typeSpec[w]
+ id:IDENTIFIER { symtab[#id.getText()] = #t.DotNetType; }
+ )
+ | #(PARAMS tp:typeSpec[w]
+ idp:IDENTIFIER
+ { // idp is actually an array of tp
+ symtab[#idp.getText()] = mkType(#tp.DotNetType.TypeName + "[]")
+ ; }
+ )
+ ;
+
+objectinitializer [object w]
+ : #(INSTANCE_INIT slist[w] )
+ ;
+
+variableDeclarator [object w, ASTNode t, bool isCreate]
+ { bool initted = false; }
+ : #( VAR_DECLARATOR
+ id:IDENTIFIER
+ (varInitializer[w] { initted = true; } )?
+ { symtab[#id.getText()] = t.DotNetType; // keving: I assume id is not valid in initializer
+ if (isCreate && !initted)
+ {
+ if ( t.DotNetType is StructRep )
+ ##.addChild( #( [VAR_INIT], #( [EXPR], #( [OBJ_CREATE_EXPR, "new"],
+ astFactory.dupTree(t),
+ #( [EXPR_LIST] ) ) ) ) );
+ if ( t.DotNetType is EnumRep )
+ {
+ string enumZero = ((EnumRep) t.DotNetType).getField(0);
+ ##.addChild( #( [VAR_INIT], #( [EXPR], #( [MEMBER_ACCESS_EXPR, "."],
+ astFactory.dupTree(t.getFirstChild()),
+ #( [IDENTIFIER, enumZero] ) ) ) ) );
+ }
+ }
+ }
+ )
+// | LBRACK variableDeclarator[w]
+ ;
+
+varInitializer [object w]
+ : #(VAR_INIT
+ initializer[w])
+ ;
+
+initializer [object w]
+ : expression[w]
+ | arrayInitializer[w]
+ ;
+
+arrayInitializer [object w]
+ : #(ARRAY_INIT (initializer[w])* )
+ ;
+
+methodHead [object w]
+ : IDENTIFIER paramList[w] (throwsClause[w])?
+ ;
+
+paramList [object w]
+ : #( FORMAL_PARAMETER_LIST
+ ( parameterDef[w] )*
+ )
+ ;
+
+throwsClause [object w]
+ : #( "throws"
+ ( identifier[w] ( identifier[w] )* )?
+ )
+ ;
+
+identifier [object w]
+ : IDENTIFIER
+ | #( DOT IDENTIFIER identifier[w] )
+ ;
+
+identifierStar [object w]
+ : IDENTIFIER
+ | STAR
+ | #( DOT IDENTIFIER identifier[w] )
+ ;
+
+slist [object w]
+ : #( BLOCK { symtab.PushLevel(); } (stat[w])* { symtab.PopLevel(); } )
+ | EMPTY_STMT
+ ;
+
+// Like a slist[]. Appears in switch alternatives
+statementList [object w]
+ : #( STMT_LIST (stat[w])* )
+ ;
+
+stat [object w]
+ : typeDefinition[w]
+ | variableDef[w, true]
+ | #(EXPR_STMT expression[w])
+ | #(LABELED_STAT IDENTIFIER stat[w])
+ | #(IF
+ expression[w]
+ stat[w]
+ ( #(ELSE
+ stat[w])
+ )?
+ )
+ | #( "for"
+ #(FOR_INIT (variableDef[w, true])* (expression[w] ( expression[w])* )?)
+ #(FOR_COND (expression[w])?)
+ #(FOR_ITER (expression[w] ( expression[w])* )?)
+ stat[w]
+ )
+ |! { foreachCounter++; }
+ #("foreach"
+ def:variableDef[w, true]
+ ce:expression[w]
+ bod:stat[w]
+ )
+ {
+ foreachCounter--;
+ string tempVar = "__o" + (foreachCounter > 0 ? foreachCounter+"" : "");
+ ASTNode retAST;
+ ASTNode typeAST = (ASTNode) #def.getFirstChild().getNextSibling();
+ string typeOfVar = typeToString(typeAST, false);
+ ASTNode initVar = (ASTNode) #def.getFirstChild().getNextSibling().getNextSibling().getFirstChild();
+ // If target expression supports interface IDictionary then we will be getting back DictionaryEntry's, for Java
+ // assume the expression #CE implements interface Map and call entrySet()
+ ASTNode iterableAST;
+ if (mkType("System.Collections.IDictionary").IsA(#ce))
+ {
+ iterableAST = #( [EXPR], #( [JAVAWRAPPER], [IDENTIFIER, "${ce}.entrySet()"],
+ [IDENTIFIER, "${ce}"], astFactory.dupTree(#ce) ) );
+ } else
+ if (mkType("System.String").IsA(#ce))
+ {
+ iterableAST = #( [EXPR], #( [JAVAWRAPPER], [IDENTIFIER, "${ce}.toCharArray()"],
+ [IDENTIFIER, "${ce}"], astFactory.dupTree(#ce) ) );
+ } else
+ {
+ iterableAST = (ASTNode) astFactory.dupTree(#ce);
+ }
+ retAST = #( [FOREACH, "foreach"],
+ #( [FIELD_DECL], #([MODIFIERS]),
+ #( [TYPE], #([IDENTIFIER, "Object"]), #([ARRAY_RANKS]) ),
+ #( [VAR_DECLARATOR], #( [IDENTIFIER, tempVar] ) ) ),
+ iterableAST);
+ retAST.addChild( #( [BLOCK],
+ #( [FIELD_DECL], astFactory.dupTree(#def.getFirstChild()),
+ astFactory.dupTree(typeAST),
+ #( [VAR_DECLARATOR],
+ astFactory.dupTree(initVar),
+ #( [VAR_INIT],
+ #( [EXPR], #( [CAST_EXPR], astFactory.dupTree(boxedType(typeAST)), #( [IDENTIFIER, tempVar] ) ) ) ) ) ),
+ #bod ) );
+
+ ## = retAST;
+ }
+ | #("while"
+ expression[w]
+ stat[w]
+ )
+ | #("do"
+ stat[w]
+ expression[w]
+ )
+ | #("break" ( IDENTIFIER)? )
+ | #("continue" ( IDENTIFIER)? )
+ | #("return" ( expression[w])? )
+ |! { ASTNode scrutinee = null;
+ ASTNode retAST = null;
+ ASTNode iteAST = null;
+ }
+ #("switch"
+ se:expression[w] { if (isValidScrutinee(#se))
+ {
+ retAST = #( [SWITCH, "switch"], #se );
+ }
+ else
+ {
+ // Declare a variable with the right type to hold the scrutinee
+ string scrutType;
+ string scrutVar;
+ if (#se.DotNetType.Java != null)
+ scrutType = #se.DotNetType.Java;
+ else
+ scrutType = #se.DotNetType.TypeName;
+ scrutVar = "__scrut" + scrutineeCounter;
+ scrutineeCounter++;
+ // Add to symtab
+ symtab[scrutVar] = #se.DotNetType;
+ scrutinee = #( [IDENTIFIER, scrutVar] );
+ retAST = #( [BLOCK], #( [FIELD_DECL], [MODIFIERS], #( [TYPE], [IDENTIFIER, scrutType], [ARRAY_RANKS] ),
+ #( [VAR_DECLARATOR], scrutinee, #( [VAR_INIT],
+ astFactory.dupTree(#se) ) ) ) );
+ };
+ }
+ (cg:caseGroup[w, scrutinee] { if (scrutinee == null)
+ {
+ retAST.addChild(#cg);
+ }
+ else
+ {
+ // cg is if (...) { ... }
+ if (iteAST == null)
+ retAST.addChild(#cg);
+ else
+ iteAST.addChild( #( [ELSE, "else"], ( [BLOCK], #cg ) ) );
+ iteAST = #cg;
+ };
+
+ } )*
+ { if (scrutinee != null)
+ scrutineeCounter--;
+ ## = retAST;
+ }
+ )
+ | #("throw" expression[w] )
+ | #("synchronized"
+ expression[w]
+ stat[w]
+ )
+ | tryBlock[w]
+ | slist[w]
+ // uncomment to make assert JDK 1.4 stuff work
+ // | #("assert" expression[w] (expression[w])?)
+ | ctorCall[w]
+ ;
+
+// If s is null then this is a real case, else we are transforming it to if-then-else statements
+caseGroup! [Object w, ASTNode s]
+ { ASTNode retAST = null;
+ ASTNode condAST = null;
+ }
+ : #(SWITCH_SECTION
+ ( #("case" e1:expression[w] { if (s == null)
+ { ASTNode constAST = null;
+ if (mkType("System.Enum").IsA(#e1.DotNetType))
+ {
+ // Enums must not be qualified
+ ASTNode strippedConst = stripQualifier((ASTNode)#e1.getFirstChild());
+ constAST = #( [EXPR], strippedConst);
+ }
+ else
+ constAST = (ASTNode) astFactory.dupTree(#e1);
+ retAST = #( [SWITCH_SECTION],
+ #( [CASE, "case"], constAST ) );
+ }
+ else
+ condAST = #( [JAVAWRAPPER], [IDENTIFIER, "${this}.equals(${arg})"],
+ [IDENTIFIER, "${this}"], astFactory.dupTree(s),
+ [IDENTIFIER, "${arg}"], astFactory.dupTree(#e1.getFirstChild()) ); }
+ )
+ | "default" { if (s == null)
+ retAST = #( [SWITCH_SECTION], #( [DEFAULT, "default"] ) );
+ else
+ condAST = #( [TRUE, "true"] );
+ }
+ )
+ ( #("case" en:expression[w] { if (s == null)
+ {
+ ASTNode constAST = null;
+ if (mkType("System.Enum").IsA(#en.DotNetType))
+ {
+ // Enums must not be qualified
+ ASTNode strippedConst = stripQualifier((ASTNode)#en.getFirstChild());
+ constAST = #( [EXPR], strippedConst);
+ }
+ else
+ constAST = (ASTNode) astFactory.dupTree(#en);
+ retAST.addChild( #( [CASE, "case"], constAST ) );
+ }
+ else
+ {
+ if ( condAST == null || condAST.Type != TRUE )
+ condAST = #( [LOG_OR, "||"], condAST, #( [JAVAWRAPPER], [IDENTIFIER, "${this}.equals(${arg})"],
+ [IDENTIFIER, "${this}"], astFactory.dupTree(s),
+ [IDENTIFIER, "${arg}"], astFactory.dupTree(#en.getFirstChild()) ) ); }
+ }
+ )
+ | "default" { if (s == null)
+ retAST.addChild( #( [DEFAULT, "default"] ) );
+ else
+ condAST = #( [TRUE, "true"] ); // We must always take this option, ignore previous
+ }
+ )*
+ sl:statementList[w]
+ { if (s == null)
+ retAST.addChild( astFactory.dupTree(#sl) );
+ else
+ { // strip trailing break from sl
+ ASTNode slAST = (ASTNode) #sl.getFirstChild();
+ if (slAST != null)
+ {
+ ASTNode prevAST = null;
+ ASTNode nextAST = slAST;
+ while (nextAST.getNextSibling() != null)
+ {
+ prevAST = nextAST;
+ nextAST = (ASTNode) nextAST.getNextSibling();
+ }
+ if (nextAST.Type == BREAK)
+ {
+ // Strip break
+ if (prevAST == null)
+ slAST = null;
+ else
+ prevAST.setNextSibling(null);
+ }
+ }
+ if (condAST == null || condAST.Type == TRUE)
+ retAST = slAST;
+ else
+ retAST = #( [IF, "if"], #( [EXPR], condAST), #( [BLOCK], slAST ) );
+ }
+ ## = retAST;
+ }
+ )
+ ;
+
+tryBlock [object w]
+ : #( "try"
+ slist[w]
+ (handler[w])*
+ (#("finally"
+ slist[w]
+ ))?
+ )
+ ;
+
+handler [object w]
+ : #( "catch"
+ ( // typeSpec[w] |
+ variableDef[w, false] )
+ slist[w]
+ )
+ ;
+
+elist [object w]
+ : #( EXPR_LIST
+ ( expression[w] )*
+ )
+ ;
+
+expression [object w]
+ : #(EXPR e:expr[w]) { ##.DotNetType = #e.DotNetType; }
+ ;
+
+expr [object w]
+ // Set expression type to be the type of the 'then' part (but maybe it should be the least of 'then' and 'else'??)
+ : #( QUESTION expr[w] t1:expr[w] expr[w] ) { ##.DotNetType = #t1.DotNetType; }
+ // binary operators...
+
+ | assignOp[w]
+ | #( BIN_OR op1:expr[w] expr[w] ) { ##.DotNetType = #op1.DotNetType; }
+ | #( BIN_XOR op2:expr[w] expr[w] ) { ##.DotNetType = #op2.DotNetType; }
+ | #( BIN_AND op3:expr[w] expr[w] ) { ##.DotNetType = #op3.DotNetType; }
+ | #( SHIFTL op4:expr[w] expr[w] ) { ##.DotNetType = #op4.DotNetType; }
+ | #( SHIFTR op5:expr[w] expr[w] ) { ##.DotNetType = #op5.DotNetType; }
+ | #( BSR op6:expr[w] expr[w] ) { ##.DotNetType = #op6.DotNetType; }
+ | #( PLUS op7:expr[w] expr[w] ) { ##.DotNetType = #op7.DotNetType; }
+ | #( MINUS op8:expr[w] expr[w] ) { ##.DotNetType = #op8.DotNetType; }
+ | #( DIV op9:expr[w] expr[w] ) { ##.DotNetType = #op9.DotNetType; }
+ | #( MOD op10:expr[w] expr[w] ) { ##.DotNetType = #op10.DotNetType; }
+ | #( STAR op11:expr[w] expr[w] ) { ##.DotNetType = #op11.DotNetType; }
+
+
+ | #( INSTANCEOF expr[w] typeSpec[w] ) { ##.DotNetType = mkType("System.Boolean"); }
+ // In C# strings are always compared by content
+ |! #( ope:EQUAL eq1:expr[w] eq2:expr[w] )
+ { ASTNode retAST = null;
+ if (#eq1.DotNetType.TypeName == "System.String" ||
+ #eq2.DotNetType.TypeName == "System.String" )
+ {
+ retAST = #( [JAVAWRAPPER], [IDENTIFIER, "StringSupport.equals(${s1},${s2})"],
+ [IDENTIFIER, "${s1}"], astFactory.dupTree(#eq1),
+ [IDENTIFIER, "${s2}"], astFactory.dupTree(#eq2) );
+ this.addImport("RusticiSoftware.System.StringSupport");
+ }
+ else
+ if (#eq1.DotNetType.TypeName == "System.DateTime" ||
+ #eq2.DotNetType.TypeName == "System.DateTime" )
+ {
+ retAST = #( [JAVAWRAPPER], [IDENTIFIER, "(${d1} == ${d2} || ${d1}.getTime() == ${d2}.getTime())"],
+ [IDENTIFIER, "${d1}"], astFactory.dupTree(#eq1),
+ [IDENTIFIER, "${d2}"], astFactory.dupTree(#eq2) );
+ }
+ else
+ retAST = #( #ope, #eq1, #eq2);
+ retAST.DotNetType = mkType("System.Boolean");
+ ## = retAST;
+ }
+ |! #( opn:NOT_EQUAL ne1:expr[w] ne2:expr[w] )
+ { ASTNode retAST = null;
+ if (#ne1.DotNetType.TypeName == "System.String" ||
+ #ne2.DotNetType.TypeName == "System.String")
+ {
+ retAST = #( [LOG_NOT, "!"],
+ #( [JAVAWRAPPER], [IDENTIFIER, "StringSupport.equals(${s1}, ${s2})"],
+ [IDENTIFIER, "${s1}"], astFactory.dupTree(#ne1),
+ [IDENTIFIER, "${s2}"], astFactory.dupTree(#ne2) ) );
+ this.addImport("RusticiSoftware.System.StringSupport");
+ }
+ else
+ if (#ne1.DotNetType.TypeName == "System.DateTime" ||
+ #ne2.DotNetType.TypeName == "System.DateTime" )
+ {
+ retAST = #( [JAVAWRAPPER], [IDENTIFIER, "(${d1} != ${d2} && ${d1}.getTime() != ${d2}.getTime())"],
+ [IDENTIFIER, "${d1}"], astFactory.dupTree(#ne1),
+ [IDENTIFIER, "${d2}"], astFactory.dupTree(#ne2) );
+ }
+ else
+ retAST = #( #opn, #ne1, #ne2);
+ retAST.DotNetType = mkType("System.Boolean");
+ ## = retAST;
+ }
+ |! #( opl:LTHAN lt1:expr[w] lt2:expr[w] )
+ { ASTNode retAST = null;
+ if (#lt1.DotNetType.TypeName == "System.DateTime" || #lt2.DotNetType.TypeName == "System.DateTime")
+ retAST = #( [JAVAWRAPPER], [IDENTIFIER, "${this}.before(${arg})"],
+ [IDENTIFIER, "${this}"], astFactory.dupTree(#lt1),
+ [IDENTIFIER, "${arg}"], astFactory.dupTree(#lt2) );
+ else
+ retAST = #( #opl, #lt1, #lt2);
+ retAST.DotNetType = mkType("System.Boolean");
+ ## = retAST;
+ }
+ |! #( opg:GTHAN gt1:expr[w] gt2:expr[w] )
+ { ASTNode retAST = null;
+ if (#gt1.DotNetType.TypeName == "System.DateTime" || #gt2.DotNetType.TypeName == "System.DateTime")
+ retAST = #( [JAVAWRAPPER], [IDENTIFIER, "${this}.after(${arg})"],
+ [IDENTIFIER, "${this}"], astFactory.dupTree(#gt1),
+ [IDENTIFIER, "${arg}"], astFactory.dupTree(#gt2) );
+ else
+ retAST = #( #opg, #gt1, #gt2);
+ retAST.DotNetType = mkType("System.Boolean");
+ ## = retAST;
+ }
+ |! #( opge:GTE ge1:expr[w] ge2:expr[w] )
+ { ASTNode retAST = null;
+ if (#ge1.DotNetType.TypeName == "System.DateTime" || #ge2.DotNetType.TypeName == "System.DateTime")
+ retAST = #( [JAVAWRAPPER], [IDENTIFIER, "(${this}.compareTo(${arg}) >= 0)"],
+ [IDENTIFIER, "${this}"], astFactory.dupTree(#ge1),
+ [IDENTIFIER, "${arg}"], astFactory.dupTree(#ge2) );
+ else
+ retAST = #( #opge, #ge1, #ge2);
+ retAST.DotNetType = mkType("System.Boolean");
+ ## = retAST;
+ }
+ |! #( ople:LTE le1:expr[w] le2:expr[w] )
+ { ASTNode retAST = null;
+ if (#le1.DotNetType.TypeName == "System.DateTime" || #le2.DotNetType.TypeName == "System.DateTime")
+ retAST = #( [JAVAWRAPPER], [IDENTIFIER, "(${this}.compareTo(${arg}) <= 0)"],
+ [IDENTIFIER, "${this}"], astFactory.dupTree(#le1),
+ [IDENTIFIER, "${arg}"], astFactory.dupTree(#le2) );
+ else
+ retAST = #( #ople, #le1, #le2);
+ retAST.DotNetType = mkType("System.Boolean");
+ ## = retAST;
+ }
+ | #( LOG_OR expr[w] expr[w] ) { ##.DotNetType = mkType("System.Boolean"); }
+ | #( LOG_AND expr[w] expr[w] ) { ##.DotNetType = mkType("System.Boolean"); }
+
+
+ | #( INC op12:expr[w] ) { ##.DotNetType = #op12.DotNetType; }
+ | #( DEC op13:expr[w] ) { ##.DotNetType = #op13.DotNetType; }
+ | #( POST_INC_EXPR op14:expr[w] ) { ##.DotNetType = #op14.DotNetType; }
+ | #( POST_DEC_EXPR op15:expr[w] ) { ##.DotNetType = #op15.DotNetType; }
+ | #( UNARY_MINUS op16:expr[w] ) { ##.DotNetType = #op16.DotNetType; }
+ | #( UNARY_PLUS op17:expr[w] ) { ##.DotNetType = #op17.DotNetType; }
+ | #( BIN_NOT op18:expr[w] ) { ##.DotNetType = #op18.DotNetType; }
+ | #( LOG_NOT op19:expr[w] ) { ##.DotNetType = #op19.DotNetType; }
+
+ | primaryExpression[w]
+ ;
+
+assignOp! [Object w]
+
+ : #( op:ASSIGN left:expr[w] right:expr[w] )
+ {
+ ASTNode kosherInp = #( astFactory.dupTree(#op), astFactory.dupTree(#left), astFactory.dupTree(#right) );
+ ASTNode retAST = null;
+ if ( #left.Type == MEMBER_ACCESS_EXPR &&
+ #left.getFirstChild().getNextSibling().Type == IDENTIFIER)
+ {
+ retAST = ResolveSetter( kosherInp );
+ if (retAST == null)
+ retAST = kosherInp;
+ }
+ else if ( #left.Type == ELEMENT_ACCESS_EXPR )
+ {
+ TypeRep at = ((ASTNode)#left.getFirstChild()).DotNetType;
+ if (at.TypeName.EndsWith("[]") || at.TypeName == "System.Array")
+ {
+ // A real array :-)
+ retAST = kosherInp;
+ }
+ else
+ {
+ ASTNode objAST = (ASTNode) astFactory.dupTree(#left.getFirstChild());
+ ASTNode keyAST = (ASTNode) astFactory.dupTree(#left.getFirstChild().getNextSibling().getFirstChild());
+ retAST = ResolveMethod( #( [INVOCATION_EXPR], #( [MEMBER_ACCESS_EXPR], objAST,
+ [IDENTIFIER, "set___idx"]),
+ #( [EXPR_LIST], keyAST,
+ astFactory.dupTree(#right))) );
+ if (retAST == null)
+ {
+ retAST = kosherInp;
+ }
+ }
+ }
+ else if (#left.Type == IDENTIFIER)
+ {
+ // Try to resolve to a local variable / property
+ ASTNode thisNode = #( [THIS, "DUMMYTHIS"] );
+ thisNode.DotNetType = symtab["this"];
+ retAST = ResolveSetter( #( astFactory.dupTree(#op), #( [MEMBER_ACCESS_EXPR], thisNode, astFactory.dupTree(#left) ),
+ astFactory.dupTree(#right) ) );
+ }
+ if (retAST == null)
+ {
+ retAST = kosherInp;
+ }
+ ## = retAST;
+ ##.DotNetType = mkType("System.Void");
+ }
+ ;
+
+primaryExpression [object w]
+ : v:IDENTIFIER {
+ ASTNode retAST = null;
+ TypeRep retType = null;
+
+ // Look for identifier in symbol table
+ retType = symtab[#v.getText()];
+ if (retType != null)
+ {
+ retAST = #v;
+ retAST.DotNetType = retType;
+ }
+ else
+ {
+ if ( ##_in.getParent().Type != INVOCATION_EXPR &&
+ !SetterContext(##_in) )
+ { // Looking for a property or field
+ ASTNode thisNode = #( [THIS, "DUMMYTHIS"] );
+ thisNode.DotNetType = symtab["this"];
+ retAST = ResolveGetter( #( [MEMBER_ACCESS_EXPR], thisNode, #v) );
+ }
+
+ if (retAST == null)
+ {
+ if ( ##_in.getParent().Type == INVOCATION_EXPR)
+ {
+ // method call
+ retAST = #v;
+ retAST.DotNetType = null;
+ }
+ else
+ {
+ // Might be part of a reference to a static member of a type
+ retType = mkType(#v.getText());
+
+ if (retType != null)
+ {
+ retAST = #v;
+ retAST.DotNetType = retType;
+ }
+ else
+ {
+ // TODO: Probably part of a qualified type name
+ retAST = #v;
+ retAST.DotNetType = mkType("UNKNOWN TYPE");
+ }
+ }
+ }
+ }
+ ## = retAST;
+ }
+ | #( JAVAWRAPPER identifier[w] (identifier[w] (expression[w]|expr[w]|elist[w]))* )
+ {
+ if (##.DotNetType == null) {
+ ##.DotNetType = mkType("System.Object");
+ }
+ else {
+ // We saved just the type name on the previous pass
+ ##.DotNetType = mkType(##.DotNetType.TypeName);
+ }
+ }
+ | memberAccessExpr[w]
+ | arrayIndex[w]
+ |! #(INVOCATION_EXPR e:primaryExpression[w] args:elist[w] )
+ {
+ ASTNode kosherInp = #( [INVOCATION_EXPR], #e, #args);
+ ASTNode retAST = null;
+ if (#e.Type == IDENTIFIER && symtab[#e.getText()] == null)
+ {
+ // Is it a local method call?
+ ASTNode thisNode = #( [THIS, "DUMMYTHIS"] );
+ thisNode.DotNetType = symtab["this"];
+ retAST = ResolveMethod( #( [INVOCATION_EXPR], #( [MEMBER_ACCESS_EXPR], thisNode, astFactory.dupTree(#e)),
+ astFactory.dupTree(#args)) );
+ }
+ else if (#e.Type == MEMBER_ACCESS_EXPR && #e.getFirstChild().getNextSibling().Type == IDENTIFIER)
+ { // resolve method call
+ retAST = ResolveMethod( kosherInp );
+ }
+ if (retAST == null) {
+ retAST = kosherInp;
+ retAST.DotNetType = mkType("System.Object");
+ }
+
+ ## = retAST;
+
+ }
+ |! #( CAST_EXPR t:typeSpec[w] ce:expr[w] )
+ {
+ ASTNode kosherInp = #( [CAST_EXPR], #t, #ce );
+ ASTNode retAST = null;
+
+ retAST = ResolveCast( kosherInp );
+ if (retAST == null)
+ {
+ retAST = kosherInp;
+ }
+
+ ## = retAST;
+ ##.DotNetType = #t.DotNetType;
+ }
+ | newExpression[w]
+ | constant[w]
+ | "super" { ##.DotNetType = symtab["super"]; }
+ | "true" { ##.DotNetType = mkType("System.Boolean"); }
+ | "false" { ##.DotNetType = mkType("System.Boolean"); }
+ | "this" { ##.DotNetType = symtab["this"]; }
+ | NULL { ##.DotNetType = mkType("System.Object"); }
+ | typeSpec[w] // type name used with instanceof
+ ;
+
+memberAccessExpr [object w]
+ { ASTNode ret = null; }
+ :! #( MEMBER_ACCESS_EXPR
+ ( te:expr[w]
+ ( m:IDENTIFIER {
+ ASTNode kosherInp = #( [MEMBER_ACCESS_EXPR], #te, #m);
+ ASTNode retAST = null;
+ if ( ##_in.getParent().Type != INVOCATION_EXPR &&
+ !SetterContext(##_in) )
+ { // Looking for a property or field
+ retAST = ResolveGetter( kosherInp );
+ }
+ if ( retAST == null )
+ {
+ retAST = kosherInp;
+ retAST.DotNetType = mkType("System.Object");
+ }
+ ## = retAST;
+ }
+ | ai:arrayIndex[w] { ## = #( [MEMBER_ACCESS_EXPR], #te, #ai); }
+ | th:"this" { ## = #( [MEMBER_ACCESS_EXPR], #te, #th); }
+ | cl:"class" { ## = #( [MEMBER_ACCESS_EXPR], #te, #cl); }
+ | #( n:"new" i:IDENTIFIER es:elist[w] ) { ## = #( [MEMBER_ACCESS_EXPR], #te, #( #n, #i, #es ) ); }
+ | sp:"super" { ## = #( [MEMBER_ACCESS_EXPR], #te, #sp); }
+ )
+ | #(ARRAY_DECLARATOR t:typeSpecArray[w] ) { ## = #( [MEMBER_ACCESS_EXPR], #([ARRAY_DECLARATOR], #t) ); }
+ | bt:builtInType[w] { ## = #( [MEMBER_ACCESS_EXPR], #bt); } (cl1:"class" { ##.addChild(#cl1); } )?
+ )
+ )
+ ;
+
+
+ctorCall [object w]
+ : #( THIS elist[w] )
+ | #( BASE elist[w] )
+ ;
+
+arrayIndex! [object w]
+ : #(ELEMENT_ACCESS_EXPR e:expr[w] idx:elist[w] ) // keving: Strips off one rank
+ {
+ ASTNode retAST = null;
+ TypeRep at = #e.DotNetType;
+ if (at.TypeName.EndsWith("[]") || at.TypeName == "System.Array")
+ {
+ // A real array, keep array notation
+ ArrayList ms = (ArrayList)at.MethodsD["GetValue"];
+ retAST = #( [ELEMENT_ACCESS_EXPR], #e, #idx);
+ retAST.DotNetType = ((MethodRep)ms[0]).Return;
+ }
+ else
+ {
+ // TODO: Setter or Getter?
+ if ( !SetterContext(##_in) )
+ {
+ retAST = ResolveMethod( #( [INVOCATION_EXPR], #( [MEMBER_ACCESS_EXPR], astFactory.dupTree(#e),
+ [IDENTIFIER, "get___idx"]),
+ astFactory.dupTree(#idx)) );
+ if (retAST == null)
+ {
+ retAST = #( [ELEMENT_ACCESS_EXPR], #e, #idx);
+ retAST.DotNetType = mkType("System.Object");
+ }
+ }
+ else
+ {
+ retAST = #( [ELEMENT_ACCESS_EXPR], #e, #idx);
+ retAST.DotNetType = mkType("System.Object");
+ }
+ }
+ ## = retAST;
+ }
+ ;
+
+constant [object w]
+ : INT_LITERAL { ##.DotNetType = mkType("System.Int32"); }
+ | CHAR_LITERAL { ##.DotNetType = mkType("System.Char"); }
+ | STRING_LITERAL { ##.DotNetType = mkType("System.String"); }
+ | NUM_FLOAT { ##.DotNetType = mkType("System.Single"); }
+ | DOUBLE_LITERAL { ##.DotNetType = mkType("System.Double"); }
+ | FLOAT_LITERAL { ##.DotNetType = mkType("System.Single"); }
+ | LONG_LITERAL { ##.DotNetType = mkType("System.Int64"); }
+ | ULONG_LITERAL { ##.DotNetType = mkType("System.UInt64"); }
+ | DECIMAL_LITERAL { ##.DotNetType = mkType("System.Decimal"); }
+ ;
+
+newExpression [object w]
+ :! #( OBJ_CREATE_EXPR
+ t:typeSpec[w]
+ a:elist[w] {
+ ASTNode kosherInp = #( [OBJ_CREATE_EXPR], #t, #a);
+ ASTNode retAST = null;
+ retAST = ResolveNewObj( kosherInp );
+ if (retAST == null)
+ {
+ retAST = kosherInp;
+ retAST.DotNetType = #t.DotNetType;
+ }
+ ## = retAST;
+ }
+ /* keving: This was in the pretty printer, but it is never generated and I can't find reference to it
+ (
+ objBlock[w]
+
+ )?
+ */
+ )
+ | #( ARRAY_CREATE_EXPR
+ at:typeSpec[w]
+ ( arrayInitializer[w] //rankSpecifiers[w]!
+ | elist[w]
+ rankSpecifiers[w] ( arrayInitializer[w] )?
+ )
+ ) { ##.DotNetType = #at.DotNetType; }
+ ;
+
+// newArrayDeclarator [object w]
+// : #( ARRAY_DECLARATOR (newArrayDeclarator[w])? (expression[w])? )
+// ;
diff --git a/CSharpTranslator/Translator/NetTranslatorBase.cs b/CSharpTranslator/Translator/NetTranslatorBase.cs
new file mode 100644
index 0000000..a382879
--- /dev/null
+++ b/CSharpTranslator/Translator/NetTranslatorBase.cs
@@ -0,0 +1,44 @@
+using System;
+using System.IO;
+using System.Collections;
+
+namespace RusticiSoftware.Translator
+{
+ // Generate header specific to the tree-parser CSharp file
+
+
+ /** Net Translator Base Class
+ * Really these routines are part of the NetTranslator, but they are pure C# and it is easier
+ * to develop them in a C# class in VS
+ *
+ * Author: Kevin Glynn
+ *
+ *
+ */
+ public class NetTranslatorBase : JavaTreeParser
+ {
+
+ protected SymbolTable symtab = new SymbolTable();
+
+ //protected TypeRep mkType(string type, int rank)
+ //{
+ // return TypeRep.newInstance(type, rank, uPath);
+ //}
+
+ public void ExtendSymTabFromNS(string ns)
+ {
+ ArrayList EmptyPath = new ArrayList();
+ DirectoryHT env = (DirectoryHT) TypeRep.TypeEnv[ns];
+
+ if (env != null)
+ {
+ // Note GetFiles(dir, "*.xml") won't work because of odd search behaviour with 3 letter extensions ....
+ foreach (string p in env.Leaves.Keys)
+ {
+ TypeRep t = TypeRep.newInstance(ns + "." + p, EmptyPath);
+ symtab.Add(p, t);
+ }
+ }
+ }
+ }
+}
diff --git a/CSharpTranslator/Translator/Properties/AssemblyInfo.cs b/CSharpTranslator/Translator/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0b748e5
--- /dev/null
+++ b/CSharpTranslator/Translator/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Translator")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Translator")]
+[assembly: AssemblyCopyright("Copyright © 2007")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("9fae79e2-bd65-4750-b6fc-cee9b2389420")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/CSharpTranslator/Translator/Set.cs b/CSharpTranslator/Translator/Set.cs
new file mode 100644
index 0000000..e7a9c9c
--- /dev/null
+++ b/CSharpTranslator/Translator/Set.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace RusticiSoftware.Translator
+{
+ public class Set : IEnumerable
+ {
+
+ ///
+ /// Provides the storage for elements in the Set, stored as the key-set
+ /// of a Dictionary object.
+ ///
+ protected Dictionary setD = null;
+ private readonly static object PlaceholderObject = new object();
+
+ public Set()
+ {
+ setD = new Dictionary();
+ }
+
+
+ public IEnumerator GetEnumerator()
+ {
+ return setD.Keys.GetEnumerator();
+ }
+
+
+ ///
+ /// The placeholder object used as the value for the Dictionary object.
+ ///
+ /// There is a single instance of this object globally, used for all Sets.
+ ///
+ protected object Placeholder
+ {
+ get { return PlaceholderObject; }
+ }
+
+
+ ///
+ /// Adds the specified element to this set if it is not already present.
+ /// o: The object to add to the set.
+ /// returns true if the object was added, false if it was already present.
+ public bool Add(T s)
+ {
+ if (setD.ContainsKey(s))
+ return false;
+ else
+ {
+ //The object we are adding is just a placeholder. The thing we are
+ //really concerned with is 'o', the key.
+ setD[s] = PlaceholderObject;
+ return true;
+ }
+ }
+
+ public T[] AsArray()
+ {
+ ICollection keys = setD.Keys;
+ T[] retArr = new T[keys.Count];
+
+ keys.CopyTo(retArr, 0);
+
+ return retArr;
+ }
+ }
+}
diff --git a/CSharpTranslator/Translator/SigEnv.cs b/CSharpTranslator/Translator/SigEnv.cs
new file mode 100644
index 0000000..026a004
--- /dev/null
+++ b/CSharpTranslator/Translator/SigEnv.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections;
+using System.Text;
+
+
+// This is just a holder for parts of a type signature that we need to pass
+// from production to production
+namespace RusticiSoftware.Translator
+{
+ public class SigEnv
+ {
+
+ public SigEnv()
+ { }
+
+ public ArrayList Properties = new ArrayList();
+
+ public ArrayList Methods = new ArrayList();
+
+ public ArrayList Constructors = new ArrayList();
+
+ public ArrayList Fields = new ArrayList();
+
+ public ArrayList Casts = new ArrayList();
+ }
+}
diff --git a/CSharpTranslator/Translator/SymbolTable.cs b/CSharpTranslator/Translator/SymbolTable.cs
new file mode 100644
index 0000000..7b6d217
--- /dev/null
+++ b/CSharpTranslator/Translator/SymbolTable.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections;
+using System.Text;
+
+
+namespace RusticiSoftware.Translator
+{
+ // Holds our symbol table, a multi-level map from identifiers (string) to their type (string)
+
+ public class SymbolTable
+ {
+ // A stack of hashtables
+ private Stack _outer = null;
+
+
+ public SymbolTable()
+ {
+ _outer = new Stack();
+ PushLevel();
+ }
+
+ public void PushLevel()
+ {
+ _outer.Push(new Hashtable());
+ }
+
+ public void PopLevel()
+ {
+ _outer.Pop();
+ }
+
+ // keving: Can we try to add the same var twice??
+ public void Add(string v, TypeRep t)
+ {
+ ((Hashtable)_outer.Peek())[v] = t;
+ }
+
+ public TypeRep Get(string v)
+ {
+ //TypeRep unknownType;
+
+ foreach (Hashtable d in _outer)
+ {
+ if (d.Contains(v))
+ return (TypeRep) d[v];
+ }
+ return null;
+ }
+
+ public TypeRep this[string v]
+ {
+ get
+ {
+ return Get(v);
+ }
+ set
+ {
+ Add(v, value);
+ }
+ }
+
+ public void Dump()
+ {
+ string INDENT = "";
+ Console.WriteLine("symbol Table Dump");
+
+ foreach (Hashtable d in _outer)
+ {
+ foreach (string v in d.Keys)
+ {
+ Console.WriteLine(INDENT + v + ": " + ((TypeRep)d[v]).TypeName);
+ }
+ INDENT += " ";
+ }
+ Console.WriteLine("");
+ }
+
+ }
+
+}
diff --git a/CSharpTranslator/Translator/TranslationTemplate.cs b/CSharpTranslator/Translator/TranslationTemplate.cs
new file mode 100644
index 0000000..67acb18
--- /dev/null
+++ b/CSharpTranslator/Translator/TranslationTemplate.cs
@@ -0,0 +1,424 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Xml;
+using System.Xml.Serialization;
+
+namespace RusticiSoftware.Translator
+{
+
+ public abstract class TranslationBase
+ {
+ protected TranslationBase()
+ {
+ }
+ }
+
+ public class ParamRepTemplate : TranslationBase
+ {
+
+ public string Type;
+
+ public string Name;
+
+ public ParamRepTemplate() : base()
+ {}
+
+ public ParamRepTemplate(string t, string a)
+ {
+ Type = t;
+ Name = a;
+ }
+
+ }
+
+ public class ConstructorRepTemplate : TranslationBase
+ {
+ [XmlArrayItem("Import")]
+ public string[] Imports;
+ [XmlArrayItem("Param")]
+ public ParamRepTemplate[] Params;
+ public string Java;
+
+ public ConstructorRepTemplate()
+ : base()
+ {
+ Imports = new string[0];
+ Params = new ParamRepTemplate[0];
+ }
+
+ public ConstructorRepTemplate(ParamRepTemplate[] pars)
+ : base()
+ {
+ Imports = new string[0];
+ Params = pars;
+ }
+
+ public ConstructorRepTemplate(ParamRepTemplate[] pars, string[] imps, string javaRep)
+ : base()
+ {
+ Imports = imps;
+ Params = pars;
+ Java = javaRep;
+ }
+ }
+
+ public class MethodRepTemplate : ConstructorRepTemplate
+ {
+ public string Return;
+ public string Name;
+
+ public MethodRepTemplate()
+ { }
+
+ public MethodRepTemplate(string retType, string methodName,
+ ParamRepTemplate[] pars, string[] imps, string javaRep)
+ : base(pars, imps, javaRep)
+ {
+ Return = retType;
+ Name = methodName;
+ }
+
+ public MethodRepTemplate(string retType, string methodName,
+ ParamRepTemplate[] pars)
+ : this(retType, methodName, pars, new string[0], null)
+ {
+ }
+
+ }
+
+ public class CastRepTemplate : TranslationBase
+ {
+ [XmlArrayItem("Import")]
+ public string[] Imports;
+ public string From;
+ public string To;
+ public string Java;
+
+ public CastRepTemplate()
+ : base()
+ {
+ Imports = new string[0];
+ }
+
+ public CastRepTemplate(string fType, string tType,
+ string[] imps, string java)
+ {
+ From = fType;
+ To = tType;
+ Imports = imps;
+ Java = java;
+ }
+
+ public CastRepTemplate(string fType, string tType)
+ :
+ this(fType, tType, new string[0], null)
+ {
+ }
+ }
+
+ public class FieldRepTemplate : TranslationBase
+ {
+ [XmlArrayItem("Import")]
+ public string[] Imports;
+ public string Type;
+ public string Name;
+ public string Get;
+
+ public FieldRepTemplate()
+ : base()
+ {
+ Imports = new string[0];
+ }
+
+ public FieldRepTemplate(string fType, string fName,
+ string[] imps, string javaGet)
+ {
+ Type = fType;
+ Name = fName;
+ Imports = imps;
+ Get = javaGet;
+ }
+
+ public FieldRepTemplate(string fType, string fName)
+ :
+ this(fType, fName, new string[0], null)
+ {
+ }
+ }
+
+ public class PropRepTemplate : FieldRepTemplate
+ {
+ public string Set;
+
+ public PropRepTemplate()
+ : base()
+ { }
+
+ public PropRepTemplate(string fType, string fName,
+ string[] imps, string javaGet, string javaSet)
+ : base(fType, fName, imps, javaGet)
+ {
+ Set = javaSet;
+ }
+
+ public PropRepTemplate(string fType, string fName) : this(fType, fName, new string[0], null, null)
+ {
+ }
+
+ }
+
+
+ // Base Template for classes, interfaces, enums, etc.
+ [Serializable]
+ public abstract class TypeRepTemplate : TranslationBase
+ {
+
+ // Fully qualified Type Name
+ [XmlElementAttribute("Name")]
+ public string TypeName;
+
+ // Java equivalent of this type (valid given imports)
+ public string Java;
+
+ // Path to use when resolving types
+ [XmlArrayItem("Namespace")]
+ public string[] NamespacePath;
+
+ [XmlArrayItem("Type")]
+ public string[] Inherits;
+ [XmlArrayItem("Import")]
+ public string[] Imports;
+ [XmlArrayItem("Method")]
+ public MethodRepTemplate[] Methods;
+ [XmlArrayItem("Property")]
+ public PropRepTemplate[] Properties;
+ [XmlArrayItem("Field")]
+ public FieldRepTemplate[] Fields;
+ [XmlArrayItem("Cast")]
+ public CastRepTemplate[] Casts;
+
+ public TypeRepTemplate() : base()
+ {
+ // If these fields are not specified then these will be zero element arrays (rather than null)
+ NamespacePath = new string[0];
+ Inherits = new string[0];
+ Imports = new string[0];
+ Methods = new MethodRepTemplate[0];
+ Properties = new PropRepTemplate[0];
+ Fields = new FieldRepTemplate[0];
+ Casts = new CastRepTemplate[0];
+ }
+
+ protected TypeRepTemplate(string typeName)
+ : this()
+ {
+ TypeName = typeName;
+ }
+
+ protected TypeRepTemplate(string tName, string[] usePath, string[] inherits,
+ MethodRepTemplate[] ms, PropRepTemplate[] ps, FieldRepTemplate[] fs,
+ CastRepTemplate[] cs,
+ string[] imps, string javaTemplate)
+ : base()
+ {
+ TypeName = tName;
+ NamespacePath = usePath;
+ Inherits = inherits;
+ Methods = ms;
+ Properties = ps;
+ Fields = fs;
+ Imports = imps;
+ Casts = cs;
+ Java = javaTemplate;
+ }
+
+ private static object Deserialize(Stream fs, System.Type t)
+ {
+ object o = null;
+
+ XmlSerializer serializer = new XmlSerializer(t);
+ o = serializer.Deserialize(fs);
+ return o;
+ }
+
+
+ private static TypeRepTemplate Deserialize(Stream s)
+ {
+ TypeRepTemplate ret = null;
+ XmlTextReader reader = new XmlTextReader(s);
+ string typeType = null; // class, interface, enum, etc.
+ bool found = false;
+
+ try
+ {
+ while (reader.Read() && !found)
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.LocalName)
+ {
+ case "Class":
+ typeType = "RusticiSoftware.Translator.ClassRepTemplate";
+ break;
+ case "Interface":
+ typeType = "RusticiSoftware.Translator.InterfaceRepTemplate";
+ break;
+ case "Enum":
+ typeType = "RusticiSoftware.Translator.EnumRepTemplate";
+ break;
+ default:
+ typeType = "UnknownType";
+ break;
+ }
+ found = true;
+ }
+ }
+ s.Seek(0, SeekOrigin.Begin);
+ ret = (TypeRepTemplate)Deserialize(s, System.Type.GetType(typeType));
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("WARNING -- (Deserialize) " + e.Message);
+ }
+
+ return ret;
+ }
+
+
+ public static TypeRepTemplate newInstance(Stream s)
+ {
+ return (TypeRepTemplate)Deserialize(s);
+ }
+
+ // Useful because it builds either an empty ClassRep or InterfaceRep or ...
+ public abstract TypeRep mkEmptyRep();
+ }
+
+ [XmlType("Class")]
+ public class ClassRepTemplate : TypeRepTemplate
+ {
+
+ [XmlArrayItem("Constructor")]
+ public ConstructorRepTemplate[] Constructors = new ConstructorRepTemplate[0];
+
+ public ClassRepTemplate()
+ {
+ }
+
+ public ClassRepTemplate(string typeName) : base(typeName)
+ {
+ }
+
+ public ClassRepTemplate(string tName, string[] usePath, string[] inherits,
+ ConstructorRepTemplate[] cs,
+ MethodRepTemplate[] ms, PropRepTemplate[] ps, FieldRepTemplate[] fs,
+ CastRepTemplate[] cts,
+ string[] imps, string javaTemplate)
+ : base(tName, usePath, inherits, ms, ps, fs, cts, imps, javaTemplate)
+ {
+ Constructors = cs;
+ }
+
+ public ClassRepTemplate(string tName, string[] usePath, string[] inherits,
+ ConstructorRepTemplate[] cs,
+ MethodRepTemplate[] ms, PropRepTemplate[] ps, FieldRepTemplate[] fs, CastRepTemplate[] cts)
+ : base(tName, usePath, inherits, ms, ps, fs, cts, new String[0], null)
+ {
+ Constructors = cs;
+ }
+
+ public override TypeRep mkEmptyRep()
+ {
+ return new ClassRep();
+ }
+
+
+ }
+
+ [XmlType("Interface")]
+ public class InterfaceRepTemplate : TypeRepTemplate
+ {
+ public InterfaceRepTemplate()
+ { }
+
+ public InterfaceRepTemplate(string typeName)
+ : base(typeName)
+ {
+ }
+
+ public InterfaceRepTemplate(string tName, string[] usePath, string[] inherits,
+ MethodRepTemplate[] ms, PropRepTemplate[] ps, FieldRepTemplate[] fs,
+ CastRepTemplate[] cts,
+ string[] imps, string javaTemplate)
+ : base(tName, usePath, inherits, ms, ps, fs, cts, imps, javaTemplate)
+ { }
+
+ public override TypeRep mkEmptyRep()
+ {
+ return new InterfaceRep();
+ }
+ }
+
+ [XmlType("Enum")]
+ public class EnumRepTemplate : TypeRepTemplate
+ {
+ public EnumRepTemplate()
+ { }
+
+ public EnumRepTemplate(string typeName)
+ : base(typeName)
+ {
+ }
+
+ public EnumRepTemplate(string tName, string[] usePath, string[] inherits,
+ MethodRepTemplate[] ms, PropRepTemplate[] ps, FieldRepTemplate[] fs,
+ CastRepTemplate[] cts,
+ string[] imps, string javaTemplate)
+ : base(tName, usePath, inherits, ms, ps, fs, cts, imps, javaTemplate)
+ { }
+
+ public override TypeRep mkEmptyRep()
+ {
+ return new EnumRep();
+ }
+ }
+
+ [XmlType("Struct")]
+ public class StructRepTemplate : ClassRepTemplate
+ {
+
+ public StructRepTemplate()
+ {
+ }
+
+ public StructRepTemplate(string typeName) : base(typeName)
+ {
+ }
+
+ public StructRepTemplate(string tName, string[] usePath, string[] inherits,
+ ConstructorRepTemplate[] cs,
+ MethodRepTemplate[] ms, PropRepTemplate[] ps, FieldRepTemplate[] fs,
+ CastRepTemplate[] cts,
+ string[] imps, string javaTemplate)
+ : base(tName, usePath, inherits, cs, ms, ps, fs, cts, imps, javaTemplate)
+ {
+ }
+
+ public StructRepTemplate(string tName, string[] usePath, string[] inherits,
+ ConstructorRepTemplate[] cs,
+ MethodRepTemplate[] ms, PropRepTemplate[] ps, FieldRepTemplate[] fs, CastRepTemplate[] cts)
+ : base(tName, usePath, inherits, cs, ms, ps, fs, cts, new String[0], null)
+ {
+ }
+
+ public override TypeRep mkEmptyRep()
+ {
+ return new StructRep();
+ }
+
+ }
+
+}
diff --git a/CSharpTranslator/Translator/Translator.csproj b/CSharpTranslator/Translator/Translator.csproj
new file mode 100644
index 0000000..341297b
--- /dev/null
+++ b/CSharpTranslator/Translator/Translator.csproj
@@ -0,0 +1,146 @@
+
+
+ Debug
+ AnyCPU
+ 8.0.50727
+ 2.0
+ {D33074E4-1525-4F22-A1DB-A7F30989D8FE}
+ Exe
+ Properties
+ RusticiSoftware.Translator
+ Translator
+
+
+
+
+
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ False
+ ..\dll\antlr.astframe.dll
+
+
+ False
+ ..\dll\antlr.runtime.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UnicodeLexerBase.cs;UnicodeLexerBaseTokenTypes.cs
+
+
+ CSharpLexerBase.cs;CSharpLexerBaseTokenTypes.cs
+ -glib UnicodeLexerBase.g
+
+
+ CSharpLexer.cs;;CSharpLexerTokenTypes.cs
+ -glib UnicodeLexerBase.g;CSharpLexerBase.g
+
+
+ CSharpPreprocessorLexer.cs;CSharpPreprocessTokenTypes.cs
+ -glib UnicodeLexerBase.g;CSharpLexerBase.g
+
+
+ CSharpPreprocessorHooverLexer.cs;CSharpHooverTokenTypes.cs
+ -glib UnicodeLexerBase.g;CSharpLexerBase.g
+
+
+ CSharpParser.cs;CSharpJavaTokenTypes.cs
+
+
+ CSharpEnvBuilder.cs
+
+
+ CSharpTranslator.cs
+
+
+ NetTranslator.cs
+
+
+ JavaPrettyPrinter.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GenerateAntlrCode;$(BuildDependsOn)
+
+
+ CleanAntlrCode;$(CleanDependsOn)
+
+
\ No newline at end of file
diff --git a/CSharpTranslator/Translator/TypeRep.cs b/CSharpTranslator/Translator/TypeRep.cs
new file mode 100644
index 0000000..5d39e31
--- /dev/null
+++ b/CSharpTranslator/Translator/TypeRep.cs
@@ -0,0 +1,891 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Xml.Serialization;
+using T = RusticiSoftware.Translator.CSharpJavaTokenTypes; // We want easy access to the Token mappings
+
+namespace RusticiSoftware.Translator
+{
+
+ public abstract class RepBase
+ {
+
+ protected static DirectoryHT TypeTemplateCache = new DirectoryHT();
+ //
+
+ protected const string TYPEVAR = "${TYPE}";
+
+ protected RepBase()
+ {
+ }
+
+ }
+
+ public class ParamRep : RepBase
+ {
+ private TypeRep _type;
+
+ public TypeRep Type
+ {
+ get { return _type; }
+ set { _type = value; }
+ }
+
+ private string _arg;
+
+ public string Name
+ {
+ get { return _arg; }
+ set { _arg = value; }
+ }
+
+ public ParamRep()
+ {}
+
+ public ParamRep(TypeRep t, string a)
+ {
+ _type = t;
+ _arg = a;
+ }
+
+
+ internal static ParamRep newInstance(ParamRepTemplate pt, ICollection pth)
+ {
+ ParamRep ret = new ParamRep();
+ ret.Name = pt.Name;
+ ret.Type = TypeRep.newInstance(pt.Type, pth);
+ return ret;
+ }
+ }
+
+
+ public class ConstructorRep : RepBase
+ {
+ private string[] _imports;
+
+ public string[] Imports
+ {
+ get { return _imports; }
+ set { _imports = value; }
+ }
+
+ private ParamRep[] _params;
+
+ public ParamRep[] Params
+ {
+ get { return _params; }
+ set { _params = value; }
+ }
+
+ private string _javaRep;
+
+ public string Java
+ {
+ get { return _javaRep; }
+ set { _javaRep = value; }
+ }
+
+ public ConstructorRep() : base()
+ {
+ }
+
+ public ConstructorRep(ParamRep[] pars, string javaRep) : base()
+ {
+ _params = pars;
+ _javaRep = javaRep;
+ }
+
+
+ public ConstructorRep(ConstructorRepTemplate ct, ICollection pth)
+ {
+ Params = new ParamRep[ct.Params.Length];
+ for (int i = 0; i < ct.Params.Length; i++)
+ {
+ Params[i] = ParamRep.newInstance(ct.Params[i], pth);
+ }
+ Imports = new string[ct.Imports.Length];
+ for (int i = 0; i < ct.Imports.Length; i++)
+ {
+ Imports[i] = ct.Imports[i];
+ }
+ Java = ct.Java;
+ }
+ }
+
+ public class MethodRep : ConstructorRep
+ {
+
+ private TypeRep _retType;
+
+ public TypeRep Return
+ {
+ get { return _retType; }
+ set { _retType = value; }
+ }
+
+ private string _methodName;
+
+ public string Name
+ {
+ get { return _methodName; }
+ set { _methodName = value; }
+ }
+
+
+ public MethodRep() : base()
+ {
+ }
+
+ public MethodRep(MethodRepTemplate mt, ICollection pth) : base(mt, pth)
+ {
+ Name = mt.Name;
+ Return = TypeRep.newInstance(mt.Return, pth);
+ }
+ }
+
+ public class CastRep : RepBase
+ {
+ private string[] _imports;
+
+ public string[] Imports
+ {
+ get { return _imports; }
+ set { _imports = value; }
+ }
+
+ private TypeRep _fType;
+
+ public TypeRep FromType
+ {
+ get { return _fType; }
+ set { _fType = value; }
+ }
+
+ private TypeRep _tType;
+
+ public TypeRep ToType
+ {
+ get { return _tType; }
+ set { _tType = value; }
+ }
+ private string _javaRep;
+
+ public string Java
+ {
+ get { return _javaRep; }
+ set { _javaRep = value; }
+ }
+
+ public CastRep()
+ : base()
+ {
+ }
+
+ public CastRep(CastRepTemplate ct, ICollection pth)
+ {
+ FromType = TypeRep.newInstance(ct.From, pth);
+ ToType = TypeRep.newInstance(ct.To, pth);
+ Java = ct.Java;
+ Imports = new string[ct.Imports.Length];
+ for (int i = 0; i < ct.Imports.Length; i++)
+ {
+ Imports[i] = ct.Imports[i];
+ }
+ }
+
+ internal static CastRep newInstance(CastRepTemplate ct, ICollection pth)
+ {
+ return new CastRep(ct, pth);
+ }
+ }
+
+ public class FieldRep : RepBase
+ {
+ private string[] _imports;
+
+ public string[] Imports
+ {
+ get { return _imports; }
+ set { _imports = value; }
+ }
+
+ private TypeRep _type;
+
+ public TypeRep Type
+ {
+ get { return _type; }
+ set { _type = value; }
+ }
+
+ private string _name;
+
+ public string Name
+ {
+ get { return _name; }
+ set { _name = value; }
+ }
+ private string _javaGetRep;
+
+ public string Get
+ {
+ get { return _javaGetRep; }
+ set { _javaGetRep = value; }
+ }
+
+ private string _javaSetRep;
+
+ public string Set
+ {
+ get { return _javaSetRep; }
+ set { _javaSetRep = value; }
+ }
+
+ public FieldRep()
+ : base()
+ {
+ }
+
+ public FieldRep(FieldRepTemplate ft, ICollection pth)
+ {
+ Name = ft.Name;
+ Type = TypeRep.newInstance(ft.Type, pth);
+ Get = ft.Get;
+ Imports = new string[ft.Imports.Length];
+ for (int i = 0; i < ft.Imports.Length; i++)
+ {
+ Imports[i] = ft.Imports[i];
+ }
+ }
+
+ internal static FieldRep newInstance(FieldRepTemplate ft, ICollection pth)
+ {
+ return new FieldRep(ft, pth);
+ }
+ }
+
+ public class PropRep : FieldRep
+ {
+ public PropRep() : base()
+ { }
+
+ public PropRep(PropRepTemplate pt, ICollection pth) : base(pt, pth)
+ {
+ Set = pt.Set;
+ }
+
+
+ internal static PropRep newInstance(PropRepTemplate pt, ICollection pth)
+ {
+ return new PropRep(pt, pth);
+ }
+ }
+
+ public class TypeRep : RepBase
+ {
+ private static Hashtable TypeRepCache = new Hashtable();
+
+ public static void Initialize(DirectoryHT e)
+ {
+ TypeTemplateCache = e;
+ }
+
+ public static DirectoryHT TypeEnv
+ {
+ get { return TypeTemplateCache; }
+ }
+
+ private string _typeName;
+ private string _java;
+ private TypeRep _extends;
+ private TypeRep[] _implements;
+
+ public string TypeName
+ {
+ get { return _typeName; }
+ set { _typeName = value; }
+ }
+
+ public string Java
+ {
+ get { return _java; }
+ set { _java = value; }
+ }
+
+ public TypeRep Extends
+ {
+ get { return _extends; }
+ set { _extends = value; }
+ }
+ public TypeRep[] Implements
+ {
+ get { return _implements; }
+ set { _implements = value; }
+ }
+
+ private string[] _imports;
+ public string[] Imports
+ {
+ get { return _imports; }
+ set { _imports = value; }
+ }
+
+ private Hashtable _methodsD = new Hashtable();
+ public Hashtable MethodsD
+ {
+ get { return _methodsD; }
+ set { _methodsD = value; }
+ }
+
+ private Hashtable _propsD = new Hashtable();
+ public Hashtable PropertiesD
+ {
+ get { return _propsD; }
+ set { _propsD = value; }
+ }
+
+ private Hashtable _fieldsD = new Hashtable();
+ public Hashtable FieldsD
+ {
+ get { return _fieldsD; }
+ set { _fieldsD = value; }
+ }
+
+ private CastRep[] _casts;
+ public CastRep[] Casts
+ {
+ get { return _casts; }
+ set { _casts = value; }
+ }
+
+ public TypeRep()
+ : base()
+ {
+ }
+
+ // Dummy Type
+ protected TypeRep(string name)
+ : base()
+ {
+ TypeName = name;
+ Extends = null;
+ Implements = new TypeRep[0];
+ Imports = new string[0];
+ MethodsD = new Hashtable();
+ PropertiesD = new Hashtable();
+ FieldsD = new Hashtable();
+ Casts = new CastRep[0];
+ }
+
+ protected TypeRep(TypeRepTemplate template) : this()
+ {
+ Build(template);
+ }
+
+ public virtual void Build(TypeRepTemplate template)
+ {
+ ICollection uPath = template.NamespacePath;
+
+ TypeName = template.TypeName;
+ Java = template.Java;
+
+ Imports = new string[template.Imports.Length];
+ for (int i = 0; i < template.Imports.Length; i++)
+ {
+ Imports[i] = template.Imports[i];
+ }
+
+ //Extends = TypeRep.newInstance(template.Extends, uPath);
+ //Implements = new TypeRep[template.Implements.Length];
+ ArrayList TmpImplements = new ArrayList();
+ Extends = null;
+
+ for (int i = 0; i < template.Inherits.Length; i++)
+ {
+ TypeRep trep = TypeRep.newInstance(template.Inherits[i], uPath);
+ if (trep is ClassRep)
+ {
+ if (Extends != null)
+ {
+ Console.Error.Write("Error -- (TypeRep.Build): " + TypeName + " extends more than one type (");
+ Console.Error.WriteLine(Extends.TypeName + " and " + trep.TypeName + ")");
+ }
+ else
+ Extends = trep;
+ }
+ else
+ TmpImplements.Add(trep);
+ }
+ if (Extends == null && TypeName != "System.Object")
+ Extends = TypeRep.newInstance("System.Object");
+
+ Implements = (TypeRep[]) TmpImplements.ToArray(typeof(TypeRep));
+ FieldsD = new Hashtable();
+ foreach (FieldRepTemplate ft in template.Fields)
+ {
+ FieldsD.Add(ft.Name, FieldRep.newInstance(ft, uPath));
+ }
+ Casts = new CastRep[template.Casts.Length];
+ for (int i = 0; i < template.Casts.Length; i++)
+ {
+ Casts[i] = CastRep.newInstance(template.Casts[i], uPath);
+ }
+ PropertiesD = new Hashtable();
+ foreach (PropRepTemplate pt in template.Properties)
+ {
+ PropertiesD.Add(pt.Name, PropRep.newInstance(pt, uPath));
+ }
+ MethodsD = new Hashtable();
+ foreach (MethodRepTemplate mt in template.Methods)
+ {
+ ArrayList ms = (ArrayList)MethodsD[mt.Name];
+ if (ms == null)
+ ms = new ArrayList();
+
+ ms.Add(new MethodRep(mt, uPath));
+ MethodsD[mt.Name] = ms;
+ }
+ }
+
+ private static ClassRep newInstance(ClassRepTemplate template)
+ {
+ return new ClassRep(template);
+ }
+
+ private static InterfaceRep newInstance(InterfaceRepTemplate template)
+ {
+ return new InterfaceRep(template);
+ }
+
+ // While we are constructing a parameterized type (an array), we store
+ // the base type here. This can probably become a dictionary when we
+ // need to build instances of generic types.
+ private static TypeRep __baseType = null;
+
+
+ // Finds a template for typeName by searching the path. typeName must not be an array
+ // type (i.e. end with [])
+ private static TypeRepTemplate TemplateSearch(string typeName, ICollection pth)
+ {
+ TypeRepTemplate ret = null;
+ DirectoryHT ns;
+
+ foreach (string p in pth)
+ {
+ ns = (DirectoryHT)TypeTemplateCache.subDir(p);
+ ret = (ns == null ? null : ns[typeName] as TypeRepTemplate);
+ if (ret != null)
+ break;
+ }
+
+ // Must Search the Global NameSpace too
+ if (ret == null)
+ ret = TypeTemplateCache[typeName] as TypeRepTemplate;
+
+ // If all else fails create a dummy typerep
+ if (ret == null)
+ {
+ // Oh Dear, shouldn't happen.
+ Console.WriteLine("WARNING: (TypeRep.TemplateSearch) -- Could not find a template for " + typeName);
+ ret = new InterfaceRepTemplate(typeName);
+ }
+
+ return ret;
+ }
+
+ public static TypeRep newInstance(string typeName, ICollection pth)
+ {
+ string baseName = typeName;
+ int rank = 0;
+ string arraySuffix = "";
+
+ // Necessary (only) for the parent of System.Object.
+ if (typeName == null)
+ return null;
+
+ if (typeName == TYPEVAR)
+ // keving: gross hack, see above comment.
+ return __baseType;
+
+ // Calculate full, qualified type name and array rank
+ while (baseName.EndsWith("[]"))
+ {
+ rank++;
+ arraySuffix += "[]";
+ baseName = baseName.Substring(0, baseName.Length - 2);
+ }
+
+ // Find the template (and the type's full name)
+ TypeRepTemplate template = TemplateSearch(baseName, pth);
+ if (template == null)
+ {
+ // Oh Dear, shouldn't happen.
+ Console.WriteLine("WARNING: (TypeRep.newInstance) -- Could not find a template for " + baseName);
+ return null;
+ }
+
+ return newInstance(template.TypeName+arraySuffix, template, rank);
+ }
+
+ private readonly static ArrayList EmptyPath = new ArrayList();
+
+ public static TypeRep newInstance(string typeName)
+ {
+ return newInstance(typeName, EmptyPath);
+ }
+
+ private static TypeRep newInstance(string fullTypeName, TypeRepTemplate baseTemplate, int rank)
+ {
+ TypeRep retRep = null;
+
+ if (TypeRepCache[fullTypeName] != null)
+ // Here is one we made earlier
+ return (TypeRep)TypeRepCache[fullTypeName];
+
+
+ // Place a dummy typeRep in the cache
+ if (rank > 0)
+ {
+ // Will eventually be the array typerep
+ retRep = new ClassRep();
+ TypeRepCache[fullTypeName] = retRep;
+ TypeRep savedType = __baseType;
+ __baseType = newInstance(fullTypeName.Substring(0, fullTypeName.Length - 2), baseTemplate, rank-1);
+ retRep.Build(TemplateSearch("System.Array", new ArrayList()));
+ retRep.TypeName = fullTypeName;
+ __baseType = savedType;
+ }
+ else
+ {
+ retRep = baseTemplate.mkEmptyRep();
+ // TODO: keving - nicer fix required!
+ if (fullTypeName != "System.Array") TypeRepCache[fullTypeName] = retRep;
+ retRep.Build(baseTemplate);
+ }
+
+ return retRep;
+ }
+
+ // Returns true iff child is a subclass of parent.
+ public bool IsA(ASTNode child)
+ {
+ if (child == null)
+ return false;
+
+ // Is Child a manifest NULL constant?
+ if (child.Type == T.NULL ||
+ (child.Type == T.EXPR && child.getFirstChild().Type == T.NULL))
+ return true;
+
+ return IsA(child.DotNetType);
+
+ }
+
+ // Returns true iff child is a subclass of parent.
+ public bool IsA(TypeRep child)
+ {
+
+ if (child == null)
+ return false;
+
+ if (child.TypeName.EndsWith("[]"))
+ {
+ if (TypeName == "System.Array")
+ return true;
+ if (TypeName.EndsWith("[]"))
+ // true if basetypes are parent-child
+ return Extends.IsA(child.Extends);
+ return false;
+ }
+ // Non-array child
+ if (TypeName == child.TypeName)
+ return true;
+ // Are we any of child's parents, or interfaces
+ if (IsA(child.Extends))
+ return true;
+ foreach (TypeRep t in child.Implements)
+ {
+ if (IsA(t))
+ return true;
+ }
+ return false;
+ }
+
+ //
+ public FieldRep Resolve(string fieldOrProp)
+ {
+ FieldRep ret = (FieldRep) PropertiesD[fieldOrProp];
+ if (ret == null)
+ ret = (FieldRep) FieldsD[fieldOrProp];
+ if (ret == null && Extends != null)
+ return Extends.Resolve(fieldOrProp);
+ return ret;
+ }
+
+ public MethodRep Resolve(string method, IList ArgVs)
+ {
+ MethodRep ret = null;
+
+ if (MethodsD.Contains(method))
+ {
+ foreach (MethodRep m in (ArrayList) MethodsD[method])
+ {
+ if (m.Params.Length == ArgVs.Count)
+ {
+ ret = m;
+ for (int i = 0; i < ArgVs.Count; i++)
+ {
+ if (!m.Params[i].Type.IsA((ASTNode)ArgVs[i]))
+ {
+ ret = null; // reset to null, this method doesn't match
+ break;
+ }
+ }
+ }
+ if (ret != null)
+ break;
+ }
+ }
+ // If not found, check parents
+ if (ret == null && Extends != null)
+ ret = Extends.Resolve(method, ArgVs);
+ // If still not found check interfaces
+ if (ret == null)
+ {
+ foreach (TypeRep t in Implements)
+ {
+ ret = t.Resolve(method, ArgVs);
+ if (ret != null)
+ break;
+ }
+ }
+ return ret;
+ }
+
+ private CastRep ResolveCastFrom(TypeRep from, bool onlyAny)
+ {
+ CastRep ret = null;
+ foreach (CastRep c in Casts)
+ {
+ if (c.FromType.IsA(from) &&
+ ((onlyAny && c.ToType == null) || (!onlyAny && c.ToType != null && c.ToType.IsA(this))))
+ {
+ ret = c;
+ break;
+ }
+ }
+ if (ret == null)
+ {
+ // Check if compatible cast in our parent, but we can only
+ // have casts that are valid for any descendant
+ if (Extends != null)
+ return ((ClassRep)Extends).ResolveCastFrom(from, true);
+ }
+ return ret;
+ }
+
+ public CastRep ResolveCastFrom(TypeRep from)
+ {
+ return ResolveCastFrom(from, false);
+ }
+
+ public CastRep ResolveCastTo(TypeRep to)
+ {
+ CastRep ret = null;
+ foreach (CastRep c in Casts)
+ {
+ if (c.FromType.IsA(this) && (c.ToType == null || c.ToType.IsA(to)))
+ {
+ ret = c;
+ break;
+ }
+ }
+ if (ret == null)
+ {
+ // Check if compatible cast in parents
+ if (Extends != null)
+ return ((ClassRep)Extends).ResolveCastTo(to);
+ }
+ return ret;
+ }
+
+ // c.f. Type.IsAssignableFrom in .Net
+ //
+ // Returns true iff c and the current TypeRep represent the same type, or if the current TypeRep is
+ // in the inheritance hierarchy of c, or if the current TypeRep is an interface that c implements,
+ // or [if c is a generic type parameter and the current Type represents one of the constraints of c].
+ // false if none of these conditions are true, or if c is a null reference.
+ public bool IsAssignableFrom(TypeRep c)
+ {
+ return true;
+ }
+
+ public static void Test()
+ {
+
+ }
+ }
+
+ public class ClassRep : TypeRep
+ {
+ private ConstructorRep[] _Constructors = new ConstructorRep[0];
+
+ public ConstructorRep[] Constructors
+ {
+ get { return _Constructors; }
+ set { _Constructors = value; }
+ }
+
+ public ClassRep()
+ : base()
+ { }
+
+ // Dummy type
+ public ClassRep(string name)
+ : base(name)
+ {
+ }
+
+ public ClassRep(ClassRepTemplate template)
+ : base(template)
+ {
+ Constructors = new ConstructorRep[template.Constructors.Length];
+ for (int i = 0; i < template.Constructors.Length; i++)
+ {
+ Constructors[i] = new ConstructorRep(template.Constructors[i], template.NamespacePath);
+ }
+ }
+
+ public override void Build(TypeRepTemplate template)
+ {
+ ClassRepTemplate ctemp = (ClassRepTemplate)template;
+ Constructors = new ConstructorRep[ctemp.Constructors.Length];
+ for (int i = 0; i < ctemp.Constructors.Length; i++)
+ {
+ Constructors[i] = new ConstructorRep(ctemp.Constructors[i], ctemp.NamespacePath);
+ }
+
+ base.Build(template);
+
+ }
+
+ public ConstructorRep Resolve(IList ArgVs)
+ {
+ ConstructorRep ret = null;
+ foreach (ConstructorRep c in Constructors)
+ {
+ if (c.Params.Length == ArgVs.Count)
+ {
+ ret = c;
+ for (int i = 0; i < ArgVs.Count; i++)
+ {
+ if (!c.Params[i].Type.IsA((ASTNode)ArgVs[i]))
+ {
+ ret = null; // reset to null, this method doesn't match
+ break;
+ }
+ }
+ }
+ if (ret != null)
+ break;
+ }
+ if (ret == null)
+ {
+ // Check if compatible constructor in parents
+ if (Extends != null)
+ return ((ClassRep)Extends).Resolve(ArgVs);
+ }
+ return ret;
+ }
+
+
+ }
+
+ public class InterfaceRep : TypeRep
+ {
+
+ public InterfaceRep()
+ : base()
+ { }
+
+ // Dummy Interface
+ public InterfaceRep(string name)
+ : base(name)
+ {
+ }
+
+ public InterfaceRep(InterfaceRepTemplate template)
+ : base(template)
+ {
+ }
+
+ public override void Build(TypeRepTemplate template)
+ {
+ base.Build(template);
+ }
+ }
+
+ public class EnumRep : TypeRep
+ {
+ // stores the enum constants by value
+ string[] fieldsA = new string[0];
+
+ public EnumRep()
+ : base()
+ { }
+
+ // Dummy Enum
+ public EnumRep(string name)
+ : base(name)
+ {
+ }
+
+ public EnumRep(EnumRepTemplate template)
+ : base(template)
+ {
+ int numfields = template.Fields.Length;
+ fieldsA = new string[numfields];
+ for (int i = 0; i < numfields; i++)
+ fieldsA[i] = template.Fields[i].Name;
+ }
+
+ public override void Build(TypeRepTemplate template)
+ {
+ int numfields = template.Fields.Length;
+ fieldsA = new string[numfields];
+ for (int i = 0; i < numfields; i++)
+ fieldsA[i] = template.Fields[i].Name;
+ base.Build(template);
+ }
+
+ public string getField(int v)
+ {
+ return fieldsA[v];
+ }
+ }
+
+ public class StructRep : TypeRep
+ {
+
+ public StructRep()
+ : base()
+ { }
+
+ // Dummy Struct
+ public StructRep(string name)
+ : base(name)
+ {
+ }
+
+ public StructRep(StructRepTemplate template)
+ : base(template)
+ {
+ }
+
+ public override void Build(TypeRepTemplate template)
+ {
+ base.Build(template);
+ }
+ }
+}
diff --git a/CSharpTranslator/Translator/TypeTable.cs b/CSharpTranslator/Translator/TypeTable.cs
new file mode 100644
index 0000000..b6d4008
--- /dev/null
+++ b/CSharpTranslator/Translator/TypeTable.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections;
+using System.Text;
+using System.IO;
+using System.Xml.Serialization;
+
+namespace RusticiSoftware.Translator
+{
+ // Holds our symbol table, a multi-level map from identifiers (string) to their type (string)
+
+ public class TypeTable
+ {
+ private Stack _outer = new Stack();
+ // _global always points to the bottom of the stack where global types live
+ private Hashtable _global = null;
+
+ public TypeTable()
+ {
+ // _global always points to the bottom of the stack where global types live
+ PushLevel();
+ _global = (Hashtable) _outer.Peek();
+ }
+
+ public void PushLevel()
+ {
+ _outer.Push(new Hashtable());
+ }
+
+ public void PopLevel()
+ {
+ _outer.Pop();
+ }
+
+
+ public void Add(string typeName, TypeRep t)
+ {
+ ((Hashtable)_outer.Peek())[typeName] = t;
+ }
+
+ public TypeRep Get(string typeName)
+ {
+ foreach (Hashtable d in _outer)
+ {
+ if (d.Contains(typeName))
+ return (TypeRep)d[typeName];
+ }
+ return null;
+ }
+
+ public TypeRep this[string v]
+ {
+ get
+ {
+ return Get(v);
+ }
+ set
+ {
+ Add(v, value);
+ }
+ }
+
+
+ override public string ToString()
+ {
+ return _outer.ToString();
+ }
+ }
+
+}
diff --git a/CSharpTranslator/Translator/UnicodeLexerBase.g b/CSharpTranslator/Translator/UnicodeLexerBase.g
new file mode 100644
index 0000000..9d725f3
--- /dev/null
+++ b/CSharpTranslator/Translator/UnicodeLexerBase.g
@@ -0,0 +1,691 @@
+options
+{
+ language = "CSharp";
+ namespace = "RusticiSoftware.Translator";
+}
+
+/*
+[The "BSD licence"]
+Copyright (c) 2002-2005 Kunle Odutola
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+///
+/// Library of grammar rules that are useful for building Unicode-aware Lexers.
+///
+///
+///
+///
+/// The rules contained in this file were extracted from a Lexer for the ECMA C# language
+/// and are intended to be re-used within other Lexer grammars via the ANTLR grammar
+/// inheritance mechanism.
+///
+///
+///
+/// History
+///
+///
+///
+/// 08-Feb-2003 kunle Extracted the unicode rules from CSharpLexer.g
+///
+///
+///
+
+
+*/
+class UnicodeLexerBase extends Lexer;
+
+options
+{
+ exportVocab = UnicodeLexerBase;
+ charVocabulary = '\u0000'..'\uFFFE'; // All UNICODE characters except \uFFFF
+ k = 1;
+}
+
+protected UNICODE_CLASS_Nl // Unicode Category or Class: Nl
+ : ( '\u16EE'..'\u16F0'
+ | '\u2160'..'\u2183'
+ | '\u3007'..'\u3007'
+ | '\u3021'..'\u3029'
+ | '\u3038'..'\u303A'
+ )
+ ;
+
+protected UNICODE_CLASS_Lt // Unicode Category or Class: Lt
+ : ( '\u01C5' | '\u01C8' | '\u01CB' | '\u01F2'
+ | '\u1F88'..'\u1F8F'
+ | '\u1F98'..'\u1F9F'
+ | '\u1FA8'..'\u1FAF'
+ | '\u1FBC' | '\u1FCC' | '\u1FFC'
+ )
+ ;
+
+protected UNICODE_CLASS_Zs // Unicode Category or Class: Zs
+ : ( '\u0020'
+ | '\u00A0'
+ | '\u1680'
+ | '\u2000'..'\u200B'
+ | '\u202F'
+ | '\u205F'
+ | '\u3000'
+ )
+ ;
+
+protected UNICODE_CLASS_Ll // Unicode Category or Class: Ll
+ : ( '\u0061'..'\u007A'
+ | '\u00AA' | '\u00B5' | '\u00BA'
+ | '\u00DF'..'\u00F6'
+ | '\u00F8'..'\u00FF'
+ | '\u0101' | '\u0103' | '\u0105' | '\u0107' | '\u0109' | '\u010B' | '\u010D' | '\u010F' | '\u0111'
+ | '\u0113' | '\u0115' | '\u0117' | '\u0119' | '\u011B' | '\u011D' | '\u011F' | '\u0121' | '\u0123'
+ | '\u0125' | '\u0127' | '\u0129' | '\u012B' | '\u012D' | '\u012F' | '\u0131' | '\u0133' | '\u0135'
+ | '\u0137'..'\u0138'
+ | '\u013A' | '\u013C' | '\u013E' | '\u0140' | '\u0142' | '\u0144' | '\u0146'
+ | '\u0148'..'\u0149'
+ | '\u014B' | '\u014D' | '\u014F' | '\u0151' | '\u0153' | '\u0155' | '\u0157' | '\u0159' | '\u015B'
+ | '\u015D' | '\u015F' | '\u0161' | '\u0163' | '\u0165' | '\u0167' | '\u0169' | '\u016B' | '\u016D'
+ | '\u016F' | '\u0171' | '\u0173' | '\u0175' | '\u0177' | '\u017A' | '\u017C'
+ | '\u017E'..'\u0180'
+ | '\u0183' | '\u0185' | '\u0188'
+ | '\u018C'..'\u018D'
+ | '\u0192' | '\u0195'
+ | '\u0199'..'\u019B'
+ | '\u019E' | '\u01A1' | '\u01A3' | '\u01A5' | '\u01A8'
+ | '\u01AA'..'\u01AB'
+ | '\u01AD' | '\u01B0' | '\u01B4' | '\u01B6'
+ | '\u01B9'..'\u01BA'
+ | '\u01BD'..'\u01BF'
+ | '\u01C6' | '\u01C9' | '\u01CC' | '\u01CE' | '\u01D0' | '\u01D2' | '\u01D4' | '\u01D6' | '\u01D8'
+ | '\u01DA'
+ | '\u01DC'..'\u01DD'
+ | '\u01DF' | '\u01E1' | '\u01E3' | '\u01E5' | '\u01E7' | '\u01E9' | '\u01EB' | '\u01ED'
+ | '\u01EF'..'\u01F0'
+ | '\u01F3' | '\u01F5' | '\u01F9' | '\u01FB' | '\u01FD' | '\u01FF' | '\u0201' | '\u0203' | '\u0205'
+ | '\u0207' | '\u0209' | '\u020B' | '\u020D' | '\u020F' | '\u0211' | '\u0213' | '\u0215' | '\u0217'
+ | '\u0219' | '\u021B' | '\u021D' | '\u021F' | '\u0223' | '\u0225' | '\u0227' | '\u0229' | '\u022B'
+ | '\u022D' | '\u022F' | '\u0231' | '\u0233'
+ | '\u0250'..'\u02AD'
+ | '\u0390'
+ | '\u03AC'..'\u03CE'
+ | '\u03D0'..'\u03D1'
+ | '\u03D5'..'\u03D7'
+ | '\u03D9' | '\u03DB' | '\u03DD' | '\u03DF' | '\u03E1' | '\u03E3' | '\u03E5' | '\u03E7' | '\u03E9'
+ | '\u03EB' | '\u03ED'
+ | '\u03EF'..'\u03F3'
+ | '\u03F5'
+ | '\u0430'..'\u045F'
+ | '\u0461' | '\u0463' | '\u0465' | '\u0467' | '\u0469' | '\u046B' | '\u046D' | '\u046F' | '\u0471'
+ | '\u0473' | '\u0475' | '\u0477' | '\u0479' | '\u047B' | '\u047D' | '\u047F' | '\u0481' | '\u048B'
+ | '\u048D' | '\u048F' | '\u0491' | '\u0493' | '\u0495' | '\u0497' | '\u0499' | '\u049B' | '\u049D'
+ | '\u049F' | '\u04A1' | '\u04A3' | '\u04A5' | '\u04A7' | '\u04A9' | '\u04AB' | '\u04AD' | '\u04AF'
+ | '\u04B1' | '\u04B3' | '\u04B5' | '\u04B7' | '\u04B9' | '\u04BB' | '\u04BD' | '\u04BF' | '\u04C2'
+ | '\u04C4' | '\u04C6' | '\u04C8' | '\u04CA' | '\u04CC' | '\u04CE' | '\u04D1' | '\u04D3' | '\u04D5'
+ | '\u04D7' | '\u04D9' | '\u04DB' | '\u04DD' | '\u04DF' | '\u04E1' | '\u04E3' | '\u04E5' | '\u04E7'
+ | '\u04E9' | '\u04EB' | '\u04ED' | '\u04EF' | '\u04F1' | '\u04F3' | '\u04F5' | '\u04F9' | '\u0501'
+ | '\u0503' | '\u0505' | '\u0507' | '\u0509' | '\u050B' | '\u050D' | '\u050F'
+ | '\u0561'..'\u0587'
+ | '\u1E01' | '\u1E03' | '\u1E05' | '\u1E07' | '\u1E09' | '\u1E0B' | '\u1E0D' | '\u1E0F' | '\u1E11'
+ | '\u1E13' | '\u1E15' | '\u1E17' | '\u1E19' | '\u1E1B' | '\u1E1D' | '\u1E1F' | '\u1E21' | '\u1E23'
+ | '\u1E25' | '\u1E27' | '\u1E29' | '\u1E2B' | '\u1E2D' | '\u1E2F' | '\u1E31' | '\u1E33' | '\u1E35'
+ | '\u1E37' | '\u1E39' | '\u1E3B' | '\u1E3D' | '\u1E3F' | '\u1E41' | '\u1E43' | '\u1E45' | '\u1E47'
+ | '\u1E49' | '\u1E4B' | '\u1E4D' | '\u1E4F' | '\u1E51' | '\u1E53' | '\u1E55' | '\u1E57' | '\u1E59'
+ | '\u1E5B' | '\u1E5D' | '\u1E5F' | '\u1E61' | '\u1E63' | '\u1E65' | '\u1E67' | '\u1E69' | '\u1E6B'
+ | '\u1E6D' | '\u1E6F' | '\u1E71' | '\u1E73' | '\u1E75' | '\u1E77' | '\u1E79' | '\u1E7B' | '\u1E7D'
+ | '\u1E7F' | '\u1E81' | '\u1E83' | '\u1E85' | '\u1E87' | '\u1E89' | '\u1E8B' | '\u1E8D' | '\u1E8F'
+ | '\u1E91' | '\u1E93'
+ | '\u1E95'..'\u1E9B'
+ | '\u1EA1' | '\u1EA3' | '\u1EA5' | '\u1EA7' | '\u1EA9' | '\u1EAB' | '\u1EAD' | '\u1EAF' | '\u1EB1'
+ | '\u1EB3' | '\u1EB5' | '\u1EB7' | '\u1EB9' | '\u1EBB' | '\u1EBD' | '\u1EBF' | '\u1EC1' | '\u1EC3'
+ | '\u1EC5' | '\u1EC7' | '\u1EC9' | '\u1ECB' | '\u1ECD' | '\u1ECF' | '\u1ED1' | '\u1ED3' | '\u1ED5'
+ | '\u1ED7' | '\u1ED9' | '\u1EDB' | '\u1EDD' | '\u1EDF' | '\u1EE1' | '\u1EE3' | '\u1EE5' | '\u1EE7'
+ | '\u1EE9' | '\u1EEB' | '\u1EED' | '\u1EEF' | '\u1EF1' | '\u1EF3' | '\u1EF5' | '\u1EF7' | '\u1EF9'
+ | '\u1F00'..'\u1F07'
+ | '\u1F10'..'\u1F15'
+ | '\u1F20'..'\u1F27'
+ | '\u1F30'..'\u1F37'
+ | '\u1F40'..'\u1F45'
+ | '\u1F50'..'\u1F57'
+ | '\u1F60'..'\u1F67'
+ | '\u1F70'..'\u1F7D'
+ | '\u1F80'..'\u1F87'
+ | '\u1F90'..'\u1F97'
+ | '\u1FA0'..'\u1FA7'
+ | '\u1FB0'..'\u1FB4'
+ | '\u1FB6'..'\u1FB7'
+ | '\u1FBE'
+ | '\u1FC2'..'\u1FC4'
+ | '\u1FC6'..'\u1FC7'
+ | '\u1FD0'..'\u1FD3'
+ | '\u1FD6'..'\u1FD7'
+ | '\u1FE0'..'\u1FE7'
+ | '\u1FF2'..'\u1FF4'
+ | '\u1FF6'..'\u1FF7'
+ | '\u2071' | '\u207F' | '\u210A'
+ | '\u210E'..'\u210F'
+ | '\u2113' | '\u212F' | '\u2134' | '\u2139' | '\u213D'
+ | '\u2146'..'\u2149'
+ | '\uFB00'..'\uFB06'
+ | '\uFB13'..'\uFB17'
+ | '\uFF41'..'\uFF5A'
+ )
+ ;
+
+protected UNICODE_CLASS_Lu // Unicode Category or Class: Lu
+ : ( '\u0041'..'\u005A'
+ | '\u00C0'..'\u00D6'
+ | '\u00D8'..'\u00DE'
+ | '\u0100' | '\u0102' | '\u0104' | '\u0106' | '\u0108' | '\u010A' | '\u010C' | '\u010E' | '\u0110'
+ | '\u0112' | '\u0114' | '\u0116' | '\u0118' | '\u011A' | '\u011C' | '\u011E' | '\u0120' | '\u0122'
+ | '\u0124' | '\u0126' | '\u0128' | '\u012A' | '\u012C' | '\u012E' | '\u0130' | '\u0132' | '\u0134'
+ | '\u0136' | '\u0139' | '\u013B' | '\u013D' | '\u013F' | '\u0141' | '\u0143' | '\u0145' | '\u0147'
+ | '\u014A' | '\u014C' | '\u014E' | '\u0150' | '\u0152' | '\u0154' | '\u0156' | '\u0158' | '\u015A'
+ | '\u015C' | '\u015E' | '\u0160' | '\u0162' | '\u0164' | '\u0166' | '\u0168' | '\u016A' | '\u016C'
+ | '\u016E' | '\u0170' | '\u0172' | '\u0174' | '\u0176'
+ | '\u0178'..'\u0179'
+ | '\u017B' | '\u017D'
+ | '\u0181'..'\u0182'
+ | '\u0184'
+ | '\u0186'..'\u0187'
+ | '\u0189'..'\u018B'
+ | '\u018E'..'\u0191'
+ | '\u0193'..'\u0194'
+ | '\u0196'..'\u0198'
+ | '\u019C'..'\u019D'
+ | '\u019F'..'\u01A0'
+ | '\u01A2' | '\u01A4'
+ | '\u01A6'..'\u01A7'
+ | '\u01A9' | '\u01AC'
+ | '\u01AE'..'\u01AF'
+ | '\u01B1'..'\u01B3'
+ | '\u01B5'
+ | '\u01B7'..'\u01B8'
+ | '\u01BC' | '\u01C4' | '\u01C7' | '\u01CA' | '\u01CD' | '\u01CF' | '\u01D1' | '\u01D3' | '\u01D5'
+ | '\u01D7' | '\u01D9' | '\u01DB' | '\u01DE' | '\u01E0' | '\u01E2' | '\u01E4' | '\u01E6' | '\u01E8'
+ | '\u01EA' | '\u01EC' | '\u01EE' | '\u01F1' | '\u01F4'
+ | '\u01F6'..'\u01F8'
+ | '\u01FA' | '\u01FC' | '\u01FE' | '\u0200' | '\u0202' | '\u0204' | '\u0206' | '\u0208' | '\u020A'
+ | '\u020C' | '\u020E' | '\u0210' | '\u0212' | '\u0214' | '\u0216' | '\u0218' | '\u021A' | '\u021C'
+ | '\u021E' | '\u0220' | '\u0222' | '\u0224' | '\u0226' | '\u0228' | '\u022A' | '\u022C' | '\u022E'
+ | '\u0230' | '\u0232' | '\u0386'
+ | '\u0388'..'\u038A'
+ | '\u038C'
+ | '\u038E'..'\u038F'
+ | '\u0391'..'\u03A1'
+ | '\u03A3'..'\u03AB'
+ | '\u03D2'..'\u03D4'
+ | '\u03D8' | '\u03DA' | '\u03DC' | '\u03DE' | '\u03E0' | '\u03E2' | '\u03E4' | '\u03E6' | '\u03E8'
+ | '\u03EA' | '\u03EC' | '\u03EE' | '\u03F4'
+ | '\u0400'..'\u042F'
+ | '\u0460' | '\u0462' | '\u0464' | '\u0466' | '\u0468' | '\u046A' | '\u046C' | '\u046E' | '\u0470'
+ | '\u0472' | '\u0474' | '\u0476' | '\u0478' | '\u047A' | '\u047C' | '\u047E' | '\u0480' | '\u048A'
+ | '\u048C' | '\u048E' | '\u0490' | '\u0492' | '\u0494' | '\u0496' | '\u0498' | '\u049A' | '\u049C'
+ | '\u049E' | '\u04A0' | '\u04A2' | '\u04A4' | '\u04A6' | '\u04A8' | '\u04AA' | '\u04AC' | '\u04AE'
+ | '\u04B0' | '\u04B2' | '\u04B4' | '\u04B6' | '\u04B8' | '\u04BA' | '\u04BC' | '\u04BE'
+ | '\u04C0'..'\u04C1'
+ | '\u04C3' | '\u04C5' | '\u04C7' | '\u04C9' | '\u04CB' | '\u04CD' | '\u04D0' | '\u04D2' | '\u04D4'
+ | '\u04D6' | '\u04D8' | '\u04DA' | '\u04DC' | '\u04DE' | '\u04E0' | '\u04E2' | '\u04E4' | '\u04E6'
+ | '\u04E8' | '\u04EA' | '\u04EC' | '\u04EE' | '\u04F0' | '\u04F2' | '\u04F4' | '\u04F8' | '\u0500'
+ | '\u0502' | '\u0504' | '\u0506' | '\u0508' | '\u050A' | '\u050C' | '\u050E'
+ | '\u0531'..'\u0556'
+ | '\u10A0'..'\u10C5'
+ | '\u1E00' | '\u1E02' | '\u1E04' | '\u1E06' | '\u1E08' | '\u1E0A' | '\u1E0C' | '\u1E0E' | '\u1E10'
+ | '\u1E12' | '\u1E14' | '\u1E16' | '\u1E18' | '\u1E1A' | '\u1E1C' | '\u1E1E' | '\u1E20' | '\u1E22'
+ | '\u1E24' | '\u1E26' | '\u1E28' | '\u1E2A' | '\u1E2C' | '\u1E2E' | '\u1E30' | '\u1E32' | '\u1E34'
+ | '\u1E36' | '\u1E38' | '\u1E3A' | '\u1E3C' | '\u1E3E' | '\u1E40' | '\u1E42' | '\u1E44' | '\u1E46'
+ | '\u1E48' | '\u1E4A' | '\u1E4C' | '\u1E4E' | '\u1E50' | '\u1E52' | '\u1E54' | '\u1E56' | '\u1E58'
+ | '\u1E5A' | '\u1E5C' | '\u1E5E' | '\u1E60' | '\u1E62' | '\u1E64' | '\u1E66' | '\u1E68' | '\u1E6A'
+ | '\u1E6C' | '\u1E6E' | '\u1E70' | '\u1E72' | '\u1E74' | '\u1E76' | '\u1E78' | '\u1E7A' | '\u1E7C'
+ | '\u1E7E' | '\u1E80' | '\u1E82' | '\u1E84' | '\u1E86' | '\u1E88' | '\u1E8A' | '\u1E8C' | '\u1E8E'
+ | '\u1E90' | '\u1E92' | '\u1E94' | '\u1EA0' | '\u1EA2' | '\u1EA4' | '\u1EA6' | '\u1EA8' | '\u1EAA'
+ | '\u1EAC' | '\u1EAE' | '\u1EB0' | '\u1EB2' | '\u1EB4' | '\u1EB6' | '\u1EB8' | '\u1EBA' | '\u1EBC'
+ | '\u1EBE' | '\u1EC0' | '\u1EC2' | '\u1EC4' | '\u1EC6' | '\u1EC8' | '\u1ECA' | '\u1ECC' | '\u1ECE'
+ | '\u1ED0' | '\u1ED2' | '\u1ED4' | '\u1ED6' | '\u1ED8' | '\u1EDA' | '\u1EDC' | '\u1EDE' | '\u1EE0'
+ | '\u1EE2' | '\u1EE4' | '\u1EE6' | '\u1EE8' | '\u1EEA' | '\u1EEC' | '\u1EEE' | '\u1EF0' | '\u1EF2'
+ | '\u1EF4' | '\u1EF6' | '\u1EF8'
+ | '\u1F08'..'\u1F0F'
+ | '\u1F18'..'\u1F1D'
+ | '\u1F28'..'\u1F2F'
+ | '\u1F38'..'\u1F3F'
+ | '\u1F48'..'\u1F4D'
+ | '\u1F59' | '\u1F5B' | '\u1F5D' | '\u1F5F'
+ | '\u1F68'..'\u1F6F'
+ | '\u1FB8'..'\u1FBB'
+ | '\u1FC8'..'\u1FCB'
+ | '\u1FD8'..'\u1FDB'
+ | '\u1FE8'..'\u1FEC'
+ | '\u1FF8'..'\u1FFB'
+ | '\u2102' | '\u2107'
+ | '\u210B'..'\u210D'
+ | '\u2110'..'\u2112'
+ | '\u2115'
+ | '\u2119'..'\u211D'
+ | '\u2124' | '\u2126' | '\u2128'
+ | '\u212A'..'\u212D'
+ | '\u2130'..'\u2131'
+ | '\u2133'
+ | '\u213E'..'\u213F'
+ | '\u2145'
+ | '\uFF21'..'\uFF3A'
+ )
+ ;
+
+protected UNICODE_CLASS_Lo // Unicode Category or Class: XX
+ : ( '\u01BB'
+ | '\u01C0'..'\u01C3'
+ | '\u05D0'..'\u05EA'
+ | '\u05F0'..'\u05F2'
+ | '\u0621'..'\u063A'
+ | '\u0641'..'\u064A'
+ | '\u066E'..'\u066F'
+ | '\u0671'..'\u06D3'
+ | '\u06D5'
+ | '\u06FA'..'\u06FC'
+ | '\u0710'
+ | '\u0712'..'\u072C'
+ | '\u0780'..'\u07A5'
+ | '\u07B1'
+ | '\u0905'..'\u0939'
+ | '\u093D' | '\u0950'
+ | '\u0958'..'\u0961'
+ | '\u0985'..'\u098C'
+ | '\u098F'..'\u0990'
+ | '\u0993'..'\u09A8'
+ | '\u09AA'..'\u09B0'
+ | '\u09B2'
+ | '\u09B6'..'\u09B9'
+ | '\u09DC'..'\u09DD'
+ | '\u09DF'..'\u09E1'
+ | '\u09F0'..'\u09F1'
+ | '\u0A05'..'\u0A0A'
+ | '\u0A0F'..'\u0A10'
+ | '\u0A13'..'\u0A28'
+ | '\u0A2A'..'\u0A30'
+ | '\u0A32'..'\u0A33'
+ | '\u0A35'..'\u0A36'
+ | '\u0A38'..'\u0A39'
+ | '\u0A59'..'\u0A5C'
+ | '\u0A5E'
+ | '\u0A72'..'\u0A74'
+ | '\u0A85'..'\u0A8B'
+ | '\u0A8D'
+ | '\u0A8F'..'\u0A91'
+ | '\u0A93'..'\u0AA8'
+ | '\u0AAA'..'\u0AB0'
+ | '\u0AB2'..'\u0AB3'
+ | '\u0AB5'..'\u0AB9'
+ | '\u0ABD' | '\u0AD0' | '\u0AE0'
+ | '\u0B05'..'\u0B0C'
+ | '\u0B0F'..'\u0B10'
+ | '\u0B13'..'\u0B28'
+ | '\u0B2A'..'\u0B30'
+ | '\u0B32'..'\u0B33'
+ | '\u0B36'..'\u0B39'
+ | '\u0B3D'
+ | '\u0B5C'..'\u0B5D'
+ | '\u0B5F'..'\u0B61'
+ | '\u0B83'
+ | '\u0B85'..'\u0B8A'
+ | '\u0B8E'..'\u0B90'
+ | '\u0B92'..'\u0B95'
+ | '\u0B99'..'\u0B9A'
+ | '\u0B9C'
+ | '\u0B9E'..'\u0B9F'
+ | '\u0BA3'..'\u0BA4'
+ | '\u0BA8'..'\u0BAA'
+ | '\u0BAE'..'\u0BB5'
+ | '\u0BB7'..'\u0BB9'
+ | '\u0C05'..'\u0C0C'
+ | '\u0C0E'..'\u0C10'
+ | '\u0C12'..'\u0C28'
+ | '\u0C2A'..'\u0C33'
+ | '\u0C35'..'\u0C39'
+ | '\u0C60'..'\u0C61'
+ | '\u0C85'..'\u0C8C'
+ | '\u0C8E'..'\u0C90'
+ | '\u0C92'..'\u0CA8'
+ | '\u0CAA'..'\u0CB3'
+ | '\u0CB5'..'\u0CB9'
+ | '\u0CDE'
+ | '\u0CE0'..'\u0CE1'
+ | '\u0D05'..'\u0D0C'
+ | '\u0D0E'..'\u0D10'
+ | '\u0D12'..'\u0D28'
+ | '\u0D2A'..'\u0D39'
+ | '\u0D60'..'\u0D61'
+ | '\u0D85'..'\u0D96'
+ | '\u0D9A'..'\u0DB1'
+ | '\u0DB3'..'\u0DBB'
+ | '\u0DBD'
+ | '\u0DC0'..'\u0DC6'
+ | '\u0E01'..'\u0E30'
+ | '\u0E32'..'\u0E33'
+ | '\u0E40'..'\u0E45'
+ | '\u0E81'..'\u0E82'
+ | '\u0E84'
+ | '\u0E87'..'\u0E88'
+ | '\u0E8A' | '\u0E8D'
+ | '\u0E94'..'\u0E97'
+ | '\u0E99'..'\u0E9F'
+ | '\u0EA1'..'\u0EA3'
+ | '\u0EA5' | '\u0EA7'
+ | '\u0EAA'..'\u0EAB'
+ | '\u0EAD'..'\u0EB0'
+ | '\u0EB2'..'\u0EB3'
+ | '\u0EBD'
+ | '\u0EC0'..'\u0EC4'
+ | '\u0EDC'..'\u0EDD'
+ | '\u0F00'
+ | '\u0F40'..'\u0F47'
+ | '\u0F49'..'\u0F6A'
+ | '\u0F88'..'\u0F8B'
+ | '\u1000'..'\u1021'
+ | '\u1023'..'\u1027'
+ | '\u1029'..'\u102A'
+ | '\u1050'..'\u1055'
+ | '\u10D0'..'\u10F8'
+ | '\u1100'..'\u1159'
+ | '\u115F'..'\u11A2'
+ | '\u11A8'..'\u11F9'
+ | '\u1200'..'\u1206'
+ | '\u1208'..'\u1246'
+ | '\u1248'
+ | '\u124A'..'\u124D'
+ | '\u1250'..'\u1256'
+ | '\u1258'
+ | '\u125A'..'\u125D'
+ | '\u1260'..'\u1286'
+ | '\u1288'
+ | '\u128A'..'\u128D'
+ | '\u1290'..'\u12AE'
+ | '\u12B0'
+ | '\u12B2'..'\u12B5'
+ | '\u12B8'..'\u12BE'
+ | '\u12C0'
+ | '\u12C2'..'\u12C5'
+ | '\u12C8'..'\u12CE'
+ | '\u12D0'..'\u12D6'
+ | '\u12D8'..'\u12EE'
+ | '\u12F0'..'\u130E'
+ | '\u1310'
+ | '\u1312'..'\u1315'
+ | '\u1318'..'\u131E'
+ | '\u1320'..'\u1346'
+ | '\u1348'..'\u135A'
+ | '\u13A0'..'\u13F4'
+ | '\u1401'..'\u166C'
+ | '\u166F'..'\u1676'
+ | '\u1681'..'\u169A'
+ | '\u16A0'..'\u16EA'
+ | '\u1700'..'\u170C'
+ | '\u170E'..'\u1711'
+ | '\u1720'..'\u1731'
+ | '\u1740'..'\u1751'
+ | '\u1760'..'\u176C'
+ | '\u176E'..'\u1770'
+ | '\u1780'..'\u17B3'
+ | '\u17DC'
+ | '\u1820'..'\u1842'
+ | '\u1844'..'\u1877'
+ | '\u1880'..'\u18A8'
+ | '\u2135'..'\u2138'
+ | '\u3006' | '\u303C'
+ | '\u3041'..'\u3096'
+ | '\u309F'
+ | '\u30A1'..'\u30FA'
+ | '\u30FF'
+ | '\u3105'..'\u312C'
+ | '\u3131'..'\u318E'
+ | '\u31A0'..'\u31B7'
+ | '\u31F0'..'\u31FF'
+ | '\u3400' | '\u4DB5' | '\u4E00' | '\u9FA5'
+ | '\uA000'..'\uA48C'
+ | '\uAC00' | '\uD7A3'
+ | '\uF900'..'\uFA2D'
+ | '\uFA30'..'\uFA6A'
+ | '\uFB1D'
+ | '\uFB1F'..'\uFB28'
+ | '\uFB2A'..'\uFB36'
+ | '\uFB38'..'\uFB3C'
+ | '\uFB3E'
+ | '\uFB40'..'\uFB41'
+ | '\uFB43'..'\uFB44'
+ | '\uFB46'..'\uFBB1'
+ | '\uFBD3'..'\uFD3D'
+ | '\uFD50'..'\uFD8F'
+ | '\uFD92'..'\uFDC7'
+ | '\uFDF0'..'\uFDFB'
+ | '\uFE70'..'\uFE74'
+ | '\uFE76'..'\uFEFC'
+ | '\uFF66'..'\uFF6F'
+ | '\uFF71'..'\uFF9D'
+ | '\uFFA0'..'\uFFBE'
+ | '\uFFC2'..'\uFFC7'
+ | '\uFFCA'..'\uFFCF'
+ | '\uFFD2'..'\uFFD7'
+ | '\uFFDA'..'\uFFDC'
+ )
+ ;
+
+protected UNICODE_CLASS_Lm // Unicode Category or Class: Lm
+ : ( '\u02B0'..'\u02B8'
+ | '\u02BB'..'\u02C1'
+ | '\u02D0'..'\u02D1'
+ | '\u02E0'..'\u02E4'
+ | '\u02EE' | '\u037A' | '\u0559' | '\u0640'
+ | '\u06E5'..'\u06E6'
+ | '\u0E46' | '\u0EC6' | '\u17D7' | '\u1843' | '\u3005'
+ | '\u3031'..'\u3035'
+ | '\u303B'
+ | '\u309D'..'\u309E'
+ | '\u30FC'..'\u30FE'
+ | '\uFF70'
+ | '\uFF9E'..'\uFF9F'
+ )
+ ;
+
+protected UNICODE_CLASS_Mn // Unicode Category or Class: Mn
+ : ( '\u0300'..'\u034F'
+ | '\u0360'..'\u036F'
+ | '\u0483'..'\u0486'
+ | '\u0591'..'\u05A1'
+ | '\u05A3'..'\u05B9'
+ | '\u05BB'..'\u05BD'
+ | '\u05BF'
+ | '\u05C1'..'\u05C2'
+ | '\u05C4'
+ | '\u064B'..'\u0655'
+ | '\u0670'
+ | '\u06D6'..'\u06DC'
+ | '\u06DF'..'\u06E4'
+ | '\u06E7'..'\u06E8'
+ | '\u06EA'..'\u06ED'
+ | '\u0711'
+ | '\u0730'..'\u074A'
+ | '\u07A6'..'\u07B0'
+ | '\u0901'..'\u0902'
+ | '\u093C'
+ | '\u0941'..'\u0948'
+ | '\u094D'
+ | '\u0951'..'\u0954'
+ | '\u0962'..'\u0963'
+ | '\u0981' | '\u09BC'
+ | '\u09C1'..'\u09C4'
+ | '\u09CD'
+ | '\u09E2'..'\u09E3'
+ | '\u0A02' | '\u0A3C'
+ | '\u0A41'..'\u0A42'
+ | '\u0A47'..'\u0A48'
+ | '\u0A4B'..'\u0A4D'
+ | '\u0A70'..'\u0A71'
+ | '\u0A81'..'\u0A82'
+ | '\u0ABC'
+ | '\u0AC1'..'\u0AC5'
+ | '\u0AC7'..'\u0AC8'
+ | '\u0ACD' | '\u0B01' | '\u0B3C' | '\u0B3F'
+ | '\u0B41'..'\u0B43'
+ | '\u0B4D' | '\u0B56' | '\u0B82' | '\u0BC0' | '\u0BCD'
+ | '\u0C3E'..'\u0C40'
+ | '\u0C46'..'\u0C48'
+ | '\u0C4A'..'\u0C4D'
+ | '\u0C55'..'\u0C56'
+ | '\u0CBF' | '\u0CC6'
+ | '\u0CCC'..'\u0CCD'
+ | '\u0D41'..'\u0D43'
+ | '\u0D4D' | '\u0DCA'
+ | '\u0DD2'..'\u0DD4'
+ | '\u0DD6' | '\u0E31'
+ | '\u0E34'..'\u0E3A'
+ | '\u0E47'..'\u0E4E'
+ | '\u0EB1'
+ | '\u0EB4'..'\u0EB9'
+ | '\u0EBB'..'\u0EBC'
+ | '\u0EC8'..'\u0ECD'
+ | '\u0F18'..'\u0F19'
+ | '\u0F35' | '\u0F37' | '\u0F39'
+ | '\u0F71'..'\u0F7E'
+ | '\u0F80'..'\u0F84'
+ | '\u0F86'..'\u0F87'
+ | '\u0F90'..'\u0F97'
+ | '\u0F99'..'\u0FBC'
+ | '\u0FC6'
+ | '\u102D'..'\u1030'
+ | '\u1032'
+ | '\u1036'..'\u1037'
+ | '\u1039'
+ | '\u1058'..'\u1059'
+ | '\u1712'..'\u1714'
+ | '\u1732'..'\u1734'
+ | '\u1752'..'\u1753'
+ | '\u1772'..'\u1773'
+ | '\u17B7'..'\u17BD'
+ | '\u17C6'
+ | '\u17C9'..'\u17D3'
+ | '\u180B'..'\u180D'
+ | '\u18A9'
+ | '\u20D0'..'\u20DC'
+ | '\u20E1'
+ | '\u20E5'..'\u20EA'
+ | '\u302A'..'\u302F'
+ | '\u3099'..'\u309A'
+ | '\uFB1E'
+ | '\uFE00'..'\uFE0F'
+ | '\uFE20'..'\uFE23'
+ )
+ ;
+
+protected UNICODE_CLASS_Mc // Unicode Category or Class: Mc
+ : ( '\u0903'
+ | '\u093E'..'\u0940'
+ | '\u0949'..'\u094C'
+ | '\u0982'..'\u0983'
+ | '\u09BE'..'\u09C0'
+ | '\u09C7'..'\u09C8'
+ | '\u09CB'..'\u09CC'
+ | '\u09D7'
+ | '\u0A3E'..'\u0A40'
+ | '\u0A83'
+ | '\u0ABE'..'\u0AC0'
+ | '\u0AC9'
+ | '\u0ACB'..'\u0ACC'
+ | '\u0B02'..'\u0B03'
+ | '\u0B3E' | '\u0B40'
+ | '\u0B47'..'\u0B48'
+ | '\u0B4B'..'\u0B4C'
+ | '\u0B57'
+ | '\u0BBE'..'\u0BBF'
+ | '\u0BC1'..'\u0BC2'
+ | '\u0BC6'..'\u0BC8'
+ | '\u0BCA'..'\u0BCC'
+ | '\u0BD7'
+ | '\u0C01'..'\u0C03'
+ | '\u0C41'..'\u0C44'
+ | '\u0C82'..'\u0C83'
+ | '\u0CBE'
+ | '\u0CC0'..'\u0CC4'
+ | '\u0CC7'..'\u0CC8'
+ | '\u0CCA'..'\u0CCB'
+ | '\u0CD5'..'\u0CD6'
+ | '\u0D02'..'\u0D03'
+ | '\u0D3E'..'\u0D40'
+ | '\u0D46'..'\u0D48'
+ | '\u0D4A'..'\u0D4C'
+ | '\u0D57'
+ | '\u0D82'..'\u0D83'
+ | '\u0DCF'..'\u0DD1'
+ | '\u0DD8'..'\u0DDF'
+ | '\u0DF2'..'\u0DF3'
+ | '\u0F3E'..'\u0F3F'
+ | '\u0F7F' | '\u102C' | '\u1031' | '\u1038'
+ | '\u1056'..'\u1057'
+ | '\u17B4'..'\u17B6'
+ | '\u17BE'..'\u17C5'
+ | '\u17C7'..'\u17C8'
+ )
+ ;
+
+protected UNICODE_CLASS_Nd // Unicode Category or Class: Nd
+ : ( '\u0030'..'\u0039'
+ | '\u0660'..'\u0669'
+ | '\u06F0'..'\u06F9'
+ | '\u0966'..'\u096F'
+ | '\u09E6'..'\u09EF'
+ | '\u0A66'..'\u0A6F'
+ | '\u0AE6'..'\u0AEF'
+ | '\u0B66'..'\u0B6F'
+ | '\u0BE7'..'\u0BEF'
+ | '\u0C66'..'\u0C6F'
+ | '\u0CE6'..'\u0CEF'
+ | '\u0D66'..'\u0D6F'
+ | '\u0E50'..'\u0E59'
+ | '\u0ED0'..'\u0ED9'
+ | '\u0F20'..'\u0F29'
+ | '\u1040'..'\u1049'
+ | '\u1369'..'\u1371'
+ | '\u17E0'..'\u17E9'
+ | '\u1810'..'\u1819'
+ | '\uFF10'..'\uFF19'
+ )
+ ;
+
+protected UNICODE_CLASS_Pc // Unicode Category or Class: Pc
+ : ( '\u005F'
+ | '\u203F'..'\u2040'
+ | '\u30FB'
+ | '\uFE33'..'\uFE34'
+ | '\uFE4D'..'\uFE4F'
+ | '\uFF3F' | '\uFF65'
+ )
+ ;
+
+protected UNICODE_CLASS_Cf // Unicode Category or Class: Cf
+ : ( '\u06DD' | '\u070F' | '\u180E'
+ | '\u200C'..'\u200F'
+ | '\u202A'..'\u202E'
+ | '\u2060'..'\u2063'
+ | '\u206A'..'\u206F'
+ | '\uFEFF'
+ | '\uFFF9'..'\uFFFB'
+ )
+ ;
diff --git a/CSharpTranslator/build.properties b/CSharpTranslator/build.properties
new file mode 100644
index 0000000..2a474dc
--- /dev/null
+++ b/CSharpTranslator/build.properties
@@ -0,0 +1,56 @@
+build.dir=${basedir}/../build
+
+builder.ant.lib=${basedir}/lib
+builder.ant.dll=${basedir}/dll
+
+
+## For Building cs2j
+
+# Location of .Net on this machine (this is standard .Net 2.0 location)
+windows.dotnet.release=v2.0.50727
+windows.dotnet.dir=C:/WINDOWS/Microsoft.NET/Framework/${windows.dotnet.release}
+
+# Location of antlr dlls on this machine
+antlr.dll.dir=${builder.ant.dll}
+
+cs2jtx.src.dir=${basedir}/Translator
+cs2jtx.bin.dir=${cs2jtx.src.dir}/bin/Debug
+
+cs2jtx.build.dir=${build.dir}/cs2jtx
+
+
+
+## For running cs2j
+
+cs2jtx.exe= ${cs2jtx.bin.dir}/Translator.exe
+#cs2jtx.exe= ${basedir}/../bin/Translator.exe
+
+
+#whichbranch=AmazonBranch
+whichbranch=TrunkBranch
+
+
+
+# Sources, by default these are sibling directories of this script
+#cs2j.dir=${basedir}/../../AmazonBranch/CS2JLibrary
+#cheats.dir=${basedir}/../AmazonBranch/Cheats
+
+cs2j.dir=${basedir}/../../${whichbranch}/CS2JLibrary
+cheats.dir=${basedir}/../${whichbranch}/Cheats
+
+# Directories to build into, against
+cs.app.name=ScormEngineNetTrunk
+#cs.app.name=Amazonsimpledb4thed
+#cs.app.dir=${user.home}/My Documents/gitrepos/${cs.app.name}/src/app/ScormEngine.Core
+cs.app.dir=${user.home}/My Documents/Visual Studio 2005/Projects/${cs.app.name}/src/app/ScormEngine.Core
+
+# Set cs.tx.project if you want to translate a subset of the application
+#cs.tx.project=ScormEngine.Core/Logic
+cs.tx.project=Logic
+cs.tx.dir=${cs.app.dir}/${cs.tx.project}
+
+# Object of the translation, by default in the build area
+#java.output.dir=${user.home}/My Documents/AmazonBranch/RusticiSoftware.ScormContentPlayer.Logic/src
+java.output.dir=${user.home}/My Documents/${whichbranch}/RusticiSoftware.ScormContentPlayer.Logic/src
+
+
diff --git a/CSharpTranslator/build.xml b/CSharpTranslator/build.xml
new file mode 100644
index 0000000..89b9824
--- /dev/null
+++ b/CSharpTranslator/build.xml
@@ -0,0 +1,175 @@
+
+
+
+
+ This script builds the cs2j translator and translates C# code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "${cs2jtx.exe} -dumpxml -odir ${java.output.dir} -netdir ${cs2j.dir} -appdir ${cs.app.dir} -cheatdir ${cheats.dir} ${cs.tx.dir}"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CSharpTranslator/dll/antlr.astframe.dll b/CSharpTranslator/dll/antlr.astframe.dll
new file mode 100644
index 0000000..56744ba
Binary files /dev/null and b/CSharpTranslator/dll/antlr.astframe.dll differ
diff --git a/CSharpTranslator/dll/antlr.runtime.dll b/CSharpTranslator/dll/antlr.runtime.dll
new file mode 100644
index 0000000..8bf0b84
Binary files /dev/null and b/CSharpTranslator/dll/antlr.runtime.dll differ
diff --git a/CSharpTranslator/lib/ant-dotnet-1.0.jar b/CSharpTranslator/lib/ant-dotnet-1.0.jar
new file mode 100644
index 0000000..2d48db4
Binary files /dev/null and b/CSharpTranslator/lib/ant-dotnet-1.0.jar differ
diff --git a/CSharpTranslator/lib/antform.LICENSE b/CSharpTranslator/lib/antform.LICENSE
new file mode 100644
index 0000000..56ee163
--- /dev/null
+++ b/CSharpTranslator/lib/antform.LICENSE
@@ -0,0 +1,146 @@
+GNU Lesser General Public License
+
+Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+ [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
+
+This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
+
+When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
+
+To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
+
+We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
+
+To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
+
+Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
+
+When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
+
+We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
+
+For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
+
+In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
+
+Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
+
+The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
+
+ These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.
+
+ In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
+
+However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
+
+When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
+
+6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
+
+ a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
+
+For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
+
+ b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
+
+8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+END OF TERMS AND CONDITIONS
+
diff --git a/CSharpTranslator/lib/antform.jar b/CSharpTranslator/lib/antform.jar
new file mode 100644
index 0000000..f3aee88
Binary files /dev/null and b/CSharpTranslator/lib/antform.jar differ
diff --git a/CSharpTranslator/lib/antlr.jar b/CSharpTranslator/lib/antlr.jar
new file mode 100644
index 0000000..a9e5e38
Binary files /dev/null and b/CSharpTranslator/lib/antlr.jar differ