diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/JavaScriptBinding.sln b/src/AddIns/BackendBindings/JavaScriptBinding/JavaScriptBinding.sln
new file mode 100644
index 0000000000..8bc9e46196
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/JavaScriptBinding.sln
@@ -0,0 +1,120 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+# SharpDevelop 4.1.0.7683-alpha
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaScriptBinding", "Project\JavaScriptBinding.csproj", "{062B7E01-AF3D-430D-BE33-17FF3EF4F647}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaScriptBinding.Tests", "Test\JavaScriptBinding.Tests.csproj", "{66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop", "..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj", "{2748AD25-9C63-4E12-877B-4DCE96FBED54}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core", "..\..\..\Main\Core\Project\ICSharpCode.Core.csproj", "{35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvalonDock", "..\..\..\Libraries\AvalonDock\AvalonDock\AvalonDock.csproj", "{87E61430-4243-45F2-B74E-0A4C096CEBF3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.AvalonEdit", "..\..\..\Libraries\AvalonEdit\ICSharpCode.AvalonEdit\ICSharpCode.AvalonEdit.csproj", "{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactory", "..\..\..\Libraries\NRefactory\Project\NRefactory.csproj", "{3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.Presentation", "..\..\..\Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj", "{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Core.WinForms", "..\..\..\Main\ICSharpCode.Core.WinForms\ICSharpCode.Core.WinForms.csproj", "{857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Dom", "..\..\..\Main\ICSharpCode.SharpDevelop.Dom\Project\ICSharpCode.SharpDevelop.Dom.csproj", "{924EE450-603D-49C1-A8E5-4AFAA31CE6F3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.SharpDevelop.Widgets", "..\..\..\Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj", "{8035765F-D51F-4A0C-A746-2FD100E19419}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {062B7E01-AF3D-430D-BE33-17FF3EF4F647}.Debug|x86.Build.0 = Debug|x86
+ {062B7E01-AF3D-430D-BE33-17FF3EF4F647}.Debug|x86.ActiveCfg = Debug|x86
+ {062B7E01-AF3D-430D-BE33-17FF3EF4F647}.Release|x86.Build.0 = Release|x86
+ {062B7E01-AF3D-430D-BE33-17FF3EF4F647}.Release|x86.ActiveCfg = Release|x86
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Debug|x86.Build.0 = Debug|x86
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Debug|x86.ActiveCfg = Debug|x86
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Release|x86.Build.0 = Release|x86
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Release|x86.ActiveCfg = Release|x86
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {66B1741A-CCCE-4692-81EA-1D5D58ECC5E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|x86.Build.0 = Debug|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|x86.Build.0 = Release|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|x86.ActiveCfg = Release|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|x86.Build.0 = Debug|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|x86.Build.0 = Release|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|x86.ActiveCfg = Release|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|x86.Build.0 = Debug|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|x86.Build.0 = Release|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|x86.ActiveCfg = Release|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {87E61430-4243-45F2-B74E-0A4C096CEBF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.Build.0 = Debug|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.Build.0 = Release|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|x86.ActiveCfg = Release|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Debug|x86.Build.0 = Debug|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Release|x86.Build.0 = Release|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Release|x86.ActiveCfg = Release|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3A9AE6AA-BC07-4A2F-972C-581E3AE2F195}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|x86.Build.0 = Debug|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|x86.Build.0 = Release|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|x86.ActiveCfg = Release|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|x86.Build.0 = Debug|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|x86.Build.0 = Release|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|x86.ActiveCfg = Release|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|Any CPU.Build.0 = Release|Any CPU
+ {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|x86.Build.0 = Debug|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|x86.Build.0 = Release|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|x86.ActiveCfg = Release|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|x86.Build.0 = Debug|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|x86.Build.0 = Release|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|x86.ActiveCfg = Release|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8035765F-D51F-4A0C-A746-2FD100E19419}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Configuration/AssemblyInfo.cs b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Configuration/AssemblyInfo.cs
new file mode 100644
index 0000000000..f4e92e20ca
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Configuration/AssemblyInfo.cs
@@ -0,0 +1,16 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System.Reflection;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("JavaScript Binding")]
+[assembly: AssemblyDescription("JavaScript language binding for SharpDevelop")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/JavaScriptBinding.addin b/src/AddIns/BackendBindings/JavaScriptBinding/Project/JavaScriptBinding.addin
new file mode 100644
index 0000000000..cd4a17abe7
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/JavaScriptBinding.addin
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/JavaScriptBinding.csproj b/src/AddIns/BackendBindings/JavaScriptBinding/Project/JavaScriptBinding.csproj
new file mode 100644
index 0000000000..e94962270b
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/JavaScriptBinding.csproj
@@ -0,0 +1,99 @@
+
+
+
+ {062B7E01-AF3D-430D-BE33-17FF3EF4F647}
+ Debug
+ x86
+ Library
+ ICSharpCode.JavaScriptBinding
+ JavaScriptBinding
+ v4.0
+ Properties
+ ..\..\..\..\..\AddIns\BackendBindings\JavaScriptBinding\
+ False
+ False
+ 4
+ false
+
+
+ x86
+ False
+ Auto
+ 4194304
+ 4096
+
+
+ true
+ Full
+ False
+ False
+ DEBUG;TRACE
+
+
+ False
+ None
+ True
+ False
+ TRACE
+
+
+
+ ..\RequiredLibraries\Antlr3.Runtime.dll
+
+
+
+
+
+
+ Configuration\GlobalAssemblyInfo.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+
+
+
+ {2748AD25-9C63-4E12-877B-4DCE96FBED54}
+ ICSharpCode.SharpDevelop
+ False
+
+
+ {35CEF10F-2D4C-45F2-9DD1-161E0FEC583C}
+ ICSharpCode.Core
+ False
+
+
+ {924EE450-603D-49C1-A8E5-4AFAA31CE6F3}
+ ICSharpCode.SharpDevelop.Dom
+ False
+
+
+
+
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/CommonTreeExtensions.cs b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/CommonTreeExtensions.cs
new file mode 100644
index 0000000000..b384302775
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/CommonTreeExtensions.cs
@@ -0,0 +1,37 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using Antlr.Runtime.Tree;
+using Xebic.Parsers.ES3;
+
+namespace ICSharpCode.JavaScriptBinding
+{
+ public static class CommonTreeExtensions
+ {
+ public static bool IsFunction(this CommonTree tree)
+ {
+ return tree.Type == ES3Parser.FUNCTION;
+ }
+
+ public static bool HasChildren(this CommonTree tree)
+ {
+ return tree.ChildCount > 0;
+ }
+
+ public static CommonTree GetFirstChild(this CommonTree tree)
+ {
+ return tree.GetChild(0) as CommonTree;
+ }
+
+ public static CommonTree GetFirstChildArguments(this CommonTree tree)
+ {
+ return tree.GetFirstChildWithType(ES3Parser.ARGS) as CommonTree;
+ }
+
+ public static int BeginColumn(this CommonTree tree)
+ {
+ return tree.CharPositionInLine + 1;
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3.g3 b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3.g3
new file mode 100644
index 0000000000..9a195552c9
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3.g3
@@ -0,0 +1,1324 @@
+/*
+
+Copyrights 2008 Xebic Reasearch BV. All rights reserved (see license.txt).
+Owner : Patrick Hulsmeijer.
+
+This ANTLR 3 LL(*) grammar is based on Ecma-262 3rd edition (JavaScript 1.5, JScript 5.5).
+The annotations refer to the "A Grammar Summary" section (e.g. A.1 Lexical Grammar) and the numbers in parenthesis to the paragraph numbers (e.g. (7.8) ).
+This document is best viewed with ANTLRWorks (www.antlr.org).
+
+
+The major challenges faced in defining this grammar were:
+
+-1- Ambiguity surrounding the DIV sign in relation to the multiplicative expression and the regular expression literal.
+This is solved with some lexer driven magic: a gated semantical predicate turns the recognition of regular expressions on or off, based on the
+value of the RegularExpressionsEnabled property. When regular expressions are enabled they take precedence over division expressions. The decision whether
+regular expressions are enabled is based on the heuristics that the previous token can be considered as last token of a left-hand-side operand of a division.
+
+-2- Automatic semicolon insertion.
+This is solved within the parser. The semicolons are not physically inserted but the situations in which they should are recognized and treated as if they were.
+The physical insertion of semicolons would be undesirable because of several reasons:
+- performance degration because of how ANTLR handles tokens in token streams
+- the alteration of the input, which we need to have unchanged
+- it is superfluous being of no interest to AST construction
+
+-3- Unicode identifiers
+Because ANTLR couldn't handle the unicode tables defined in the specification well and for performance reasons unicode identifiers are implemented as an action
+driven alternative to ASCII identifiers. First the ASCII version is tried that is defined in detail in this grammar and then the unicode alternative is tried action driven.
+Because of the fact that the ASCII version is defined in detail the mTokens switch generation in the lexer can predict identifiers appropriately.
+For details see the identifier rules.
+
+
+The minor challenges were related to converting the grammar to an ANTLR LL(*) grammar:
+- Resolving the ambiguity between functionDeclaration vs functionExpression and block vs objectLiteral stemming from the expressionStatement production.
+- Left recursive nature of the left hand side expressions.
+- The assignmentExpression production.
+- The forStatement production.
+The grammar was kept as close as possible to the grammar in the "A Grammar Summary" section of Ecma-262.
+
+*/
+
+grammar ES3 ;
+
+options
+{
+ output = AST ;
+ language = CSharp2 ;
+}
+
+tokens
+{
+// Reserved words
+ NULL = 'null' ;
+ TRUE = 'true' ;
+ FALSE = 'false' ;
+
+// Keywords
+ BREAK = 'break' ;
+ CASE = 'case' ;
+ CATCH = 'catch' ;
+ CONTINUE = 'continue' ;
+ DEFAULT = 'default' ;
+ DELETE = 'delete' ;
+ DO = 'do' ;
+ ELSE = 'else' ;
+ FINALLY = 'finally' ;
+ FOR = 'for' ;
+ FUNCTION = 'function' ;
+ IF = 'if' ;
+ IN = 'in' ;
+ INSTANCEOF = 'instanceof' ;
+ NEW = 'new' ;
+ RETURN = 'return' ;
+ SWITCH = 'switch' ;
+ THIS = 'this' ;
+ THROW = 'throw' ;
+ TRY = 'try' ;
+ TYPEOF = 'typeof' ;
+ VAR = 'var' ;
+ VOID = 'void' ;
+ WHILE = 'while' ;
+ WITH = 'with' ;
+
+// Future reserved words
+ ABSTRACT = 'abstract' ;
+ BOOLEAN = 'boolean' ;
+ BYTE = 'byte' ;
+ CHAR = 'char' ;
+ CLASS = 'class' ;
+ CONST = 'const' ;
+ DEBUGGER = 'debugger' ;
+ DOUBLE = 'double' ;
+ ENUM = 'enum' ;
+ EXPORT = 'export' ;
+ EXTENDS = 'extends' ;
+ FINAL = 'final' ;
+ FLOAT = 'float' ;
+ GOTO = 'goto' ;
+ IMPLEMENTS = 'implements' ;
+ IMPORT = 'import' ;
+ INT = 'int' ;
+ INTERFACE = 'interface' ;
+ LONG = 'long' ;
+ NATIVE = 'native' ;
+ PACKAGE = 'package' ;
+ PRIVATE = 'private' ;
+ PROTECTED = 'protected' ;
+ PUBLIC = 'public' ;
+ SHORT = 'short' ;
+ STATIC = 'static' ;
+ SUPER = 'super' ;
+ SYNCHRONIZED = 'synchronized' ;
+ THROWS = 'throws' ;
+ TRANSIENT = 'transient' ;
+ VOLATILE = 'volatile' ;
+
+// Punctuators
+ LBRACE = '{' ;
+ RBRACE = '}' ;
+ LPAREN = '(' ;
+ RPAREN = ')' ;
+ LBRACK = '[' ;
+ RBRACK = ']' ;
+ DOT = '.' ;
+ SEMIC = ';' ;
+ COMMA = ',' ;
+ LT = '<' ;
+ GT = '>' ;
+ LTE = '<=' ;
+ GTE = '>=' ;
+ EQ = '==' ;
+ NEQ = '!=' ;
+ SAME = '===' ;
+ NSAME = '!==' ;
+ ADD = '+' ;
+ SUB = '-' ;
+ MUL = '*' ;
+ MOD = '%' ;
+ INC = '++' ;
+ DEC = '--' ;
+ SHL = '<<' ;
+ SHR = '>>' ;
+ SHU = '>>>' ;
+ AND = '&' ;
+ OR = '|' ;
+ XOR = '^' ;
+ NOT = '!' ;
+ INV = '~' ;
+ LAND = '&&' ;
+ LOR = '||' ;
+ QUE = '?' ;
+ COLON = ':' ;
+ ASSIGN = '=' ;
+ ADDASS = '+=' ;
+ SUBASS = '-=' ;
+ MULASS = '*=' ;
+ MODASS = '%=' ;
+ SHLASS = '<<=' ;
+ SHRASS = '>>=' ;
+ SHUASS = '>>>=' ;
+ ANDASS = '&=' ;
+ ORASS = '|=' ;
+ XORASS = '^=' ;
+ DIV = '/' ;
+ DIVASS = '/=' ;
+
+// Imaginary
+ ARGS ;
+ ARRAY ;
+ BLOCK ;
+ BYFIELD ;
+ BYINDEX ;
+ CALL ;
+ CEXPR ;
+ EXPR ;
+ FORITER ;
+ FORSTEP ;
+ ITEM ;
+ LABELLED ;
+ NAMEDVALUE ;
+ NEG ;
+ OBJECT ;
+ PAREXPR ;
+ PDEC ;
+ PINC ;
+ POS ;
+}
+
+@lexer::namespace { Xebic.Parsers.ES3 }
+
+@lexer::header { #pragma warning disable 219, 162 }
+
+@parser::namespace { Xebic.Parsers.ES3 }
+
+@parser::header { #pragma warning disable 219, 162 }
+
+//
+// $< A.1 Lexical Grammar (7)
+//
+
+// Added for lexing purposes
+
+fragment BSLASH
+ : '\\'
+ ;
+
+fragment DQUOTE
+ : '"'
+ ;
+
+fragment SQUOTE
+ : '\''
+ ;
+
+// $< Whitespace (7.2)
+
+fragment TAB
+ : '\u0009'
+ ;
+
+fragment VT // Vertical TAB
+ : '\u000b'
+ ;
+
+fragment FF // Form Feed
+ : '\u000c'
+ ;
+
+fragment SP // Space
+ : '\u0020'
+ ;
+
+fragment NBSP // Non-Breaking Space
+ : '\u00a0'
+ ;
+
+fragment USP // Unicode Space Separator (rest of Unicode category Zs)
+ : '\u1680' // OGHAM SPACE MARK
+ | '\u180E' // MONGOLIAN VOWEL SEPARATOR
+ | '\u2000' // EN QUAD
+ | '\u2001' // EM QUAD
+ | '\u2002' // EN SPACE
+ | '\u2003' // EM SPACE
+ | '\u2004' // THREE-PER-EM SPACE
+ | '\u2005' // FOUR-PER-EM SPACE
+ | '\u2006' // SIX-PER-EM SPACE
+ | '\u2007' // FIGURE SPACE
+ | '\u2008' // PUNCTUATION SPACE
+ | '\u2009' // THIN SPACE
+ | '\u200A' // HAIR SPACE
+ | '\u202F' // NARROW NO-BREAK SPACE
+ | '\u205F' // MEDIUM MATHEMATICAL SPACE
+ | '\u3000' // IDEOGRAPHIC SPACE
+ ;
+
+WhiteSpace
+ : ( TAB | VT | FF | SP | NBSP | USP )+ { $channel = HIDDEN; }
+ ;
+
+// $>
+
+// $< Line terminators (7.3)
+
+fragment LF // Line Feed
+ : '\n'
+ ;
+
+fragment CR // Carriage Return
+ : '\r'
+ ;
+
+fragment LS // Line Separator
+ : '\u2028'
+ ;
+
+fragment PS // Paragraph Separator
+ : '\u2029'
+ ;
+
+fragment LineTerminator
+ : CR | LF | LS | PS
+ ;
+
+EOL
+ : ( ( CR LF? ) | LF | LS | PS ) { $channel = HIDDEN; }
+ ;
+// $>
+
+// $< Comments (7.4)
+
+MultiLineComment
+ : '/*' ( options { greedy = false; } : . )* '*/' { $channel = HIDDEN; }
+ ;
+
+SingleLineComment
+ : '//' ( ~( LineTerminator ) )* { $channel = HIDDEN; }
+ ;
+
+// $>
+
+// $< Tokens (7.5)
+
+token
+ : reservedWord
+ | Identifier
+ | punctuator
+ | numericLiteral
+ | StringLiteral
+ ;
+
+// $< Reserved words (7.5.1)
+
+reservedWord
+ : keyword
+ | futureReservedWord
+ | NULL
+ | booleanLiteral
+ ;
+
+// $>
+
+// $< Keywords (7.5.2)
+
+keyword
+ : BREAK
+ | CASE
+ | CATCH
+ | CONTINUE
+ | DEFAULT
+ | DELETE
+ | DO
+ | ELSE
+ | FINALLY
+ | FOR
+ | FUNCTION
+ | IF
+ | IN
+ | INSTANCEOF
+ | NEW
+ | RETURN
+ | SWITCH
+ | THIS
+ | THROW
+ | TRY
+ | TYPEOF
+ | VAR
+ | VOID
+ | WHILE
+ | WITH
+ ;
+
+// $>
+
+// $< Future reserved words (7.5.3)
+
+futureReservedWord
+ : ABSTRACT
+ | BOOLEAN
+ | BYTE
+ | CHAR
+ | CLASS
+ | CONST
+ | DEBUGGER
+ | DOUBLE
+ | ENUM
+ | EXPORT
+ | EXTENDS
+ | FINAL
+ | FLOAT
+ | GOTO
+ | IMPLEMENTS
+ | IMPORT
+ | INT
+ | INTERFACE
+ | LONG
+ | NATIVE
+ | PACKAGE
+ | PRIVATE
+ | PROTECTED
+ | PUBLIC
+ | SHORT
+ | STATIC
+ | SUPER
+ | SYNCHRONIZED
+ | THROWS
+ | TRANSIENT
+ | VOLATILE
+ ;
+
+// $>
+
+// $>
+
+// $< Identifiers (7.6)
+
+fragment IdentifierStartASCII
+ : 'a'..'z' | 'A'..'Z'
+ | '$'
+ | '_'
+ | BSLASH 'u' HexDigit HexDigit HexDigit HexDigit // UnicodeEscapeSequence
+ ;
+
+/*
+The first two alternatives define how ANTLR can match ASCII characters which can be considered as part of an identifier.
+The last alternative matches other characters in the unicode range that can be sonsidered as part of an identifier.
+*/
+fragment IdentifierPart
+ : DecimalDigit
+ | IdentifierStartASCII
+ | { IsIdentifierPartUnicode(input.LA(1)) }? { MatchAny(); }
+ ;
+
+fragment IdentifierNameASCIIStart
+ : IdentifierStartASCII IdentifierPart*
+ ;
+
+/*
+The second alternative acts as an action driven fallback to evaluate other characters in the unicode range than the ones in the ASCII subset.
+Due to the first alternative this grammar defines enough so that ANTLR can generate a lexer that correctly predicts identifiers with characters in the ASCII range.
+In that way keywords, other reserved words and ASCII identifiers are recognized with standard ANTLR driven logic. When the first character for an identifier fails to
+match this ASCII definition, the lexer calls ConsumeIdentifierUnicodeStart because of the action in the alternative. This method checks whether the character matches
+as first character in ranges other than ASCII and consumes further characters belonging to the identifier with help of mIdentifierPart generated out of the
+IdentifierPart rule above.
+*/
+Identifier
+ : IdentifierNameASCIIStart
+ | { ConsumeIdentifierUnicodeStart(); }
+ ;
+
+// $>
+
+// $< Punctuators (7.7)
+
+punctuator
+ : LBRACE
+ | RBRACE
+ | LPAREN
+ | RPAREN
+ | LBRACK
+ | RBRACK
+ | DOT
+ | SEMIC
+ | COMMA
+ | LT
+ | GT
+ | LTE
+ | GTE
+ | EQ
+ | NEQ
+ | SAME
+ | NSAME
+ | ADD
+ | SUB
+ | MUL
+ | MOD
+ | INC
+ | DEC
+ | SHL
+ | SHR
+ | SHU
+ | AND
+ | OR
+ | XOR
+ | NOT
+ | INV
+ | LAND
+ | LOR
+ | QUE
+ | COLON
+ | ASSIGN
+ | ADDASS
+ | SUBASS
+ | MULASS
+ | MODASS
+ | SHLASS
+ | SHRASS
+ | SHUASS
+ | ANDASS
+ | ORASS
+ | XORASS
+ | DIV
+ | DIVASS
+ ;
+
+// $>
+
+// $< Literals (7.8)
+
+literal
+ : NULL
+ | booleanLiteral
+ | numericLiteral
+ | StringLiteral
+ | RegularExpressionLiteral
+ ;
+
+booleanLiteral
+ : TRUE
+ | FALSE
+ ;
+
+// $< Numeric literals (7.8.3)
+
+/*
+Note: octal literals are described in the B Compatibility section.
+These are removed from the standards but are here for backwards compatibility with earlier ECMAScript definitions.
+*/
+
+fragment DecimalDigit
+ : '0'..'9'
+ ;
+
+fragment HexDigit
+ : DecimalDigit | 'a'..'f' | 'A'..'F'
+ ;
+
+fragment OctalDigit
+ : '0'..'7'
+ ;
+
+fragment ExponentPart
+ : ( 'e' | 'E' ) ( '+' | '-' )? DecimalDigit+
+ ;
+
+fragment DecimalIntegerLiteral
+ : '0'
+ | '1'..'9' DecimalDigit*
+ ;
+
+DecimalLiteral
+ : DecimalIntegerLiteral '.' DecimalDigit* ExponentPart?
+ | '.' DecimalDigit+ ExponentPart?
+ | DecimalIntegerLiteral ExponentPart?
+ ;
+
+OctalIntegerLiteral
+ : '0' OctalDigit+
+ ;
+
+HexIntegerLiteral
+ : ( '0x' | '0X' ) HexDigit+
+ ;
+
+numericLiteral
+ : DecimalLiteral
+ | OctalIntegerLiteral
+ | HexIntegerLiteral
+ ;
+
+// $>
+
+// $< String literals (7.8.4)
+
+/*
+Note: octal escape sequences are described in the B Compatibility section.
+These are removed from the standards but are here for backwards compatibility with earlier ECMAScript definitions.
+*/
+
+fragment CharacterEscapeSequence
+ : ~( DecimalDigit | 'x' | 'u' | LineTerminator ) // Concatenation of SingleEscapeCharacter and NonEscapeCharacter
+ ;
+
+fragment ZeroToThree
+ : '0'..'3'
+ ;
+
+fragment OctalEscapeSequence
+ : OctalDigit
+ | ZeroToThree OctalDigit
+ | '4'..'7' OctalDigit
+ | ZeroToThree OctalDigit OctalDigit
+ ;
+
+fragment HexEscapeSequence
+ : 'x' HexDigit HexDigit
+ ;
+
+fragment UnicodeEscapeSequence
+ : 'u' HexDigit HexDigit HexDigit HexDigit
+ ;
+
+fragment EscapeSequence
+ :
+ BSLASH
+ (
+ CharacterEscapeSequence
+ | OctalEscapeSequence
+ | HexEscapeSequence
+ | UnicodeEscapeSequence
+ )
+ ;
+
+StringLiteral
+ : SQUOTE ( ~( SQUOTE | BSLASH | LineTerminator ) | EscapeSequence )* SQUOTE
+ | DQUOTE ( ~( DQUOTE | BSLASH | LineTerminator ) | EscapeSequence )* DQUOTE
+ ;
+
+// $>
+
+// $< Regular expression literals (7.8.5)
+
+fragment BackslashSequence
+ : BSLASH ~( LineTerminator )
+ ;
+
+fragment RegularExpressionFirstChar
+ : ~ ( LineTerminator | MUL | BSLASH | DIV )
+ | BackslashSequence
+ ;
+
+fragment RegularExpressionChar
+ : ~ ( LineTerminator | BSLASH | DIV )
+ | BackslashSequence
+ ;
+
+RegularExpressionLiteral
+ : { AreRegularExpressionsEnabled }?=> DIV RegularExpressionFirstChar RegularExpressionChar* DIV IdentifierPart*
+ ;
+
+// $>
+
+// $>
+
+// $>
+
+//
+// $< A.3 Expressions (11)
+//
+
+// $ ^( PAREXPR[$lpar, "PAREXPR"] expression )
+ ;
+
+arrayLiteral
+ : lb=LBRACK ( arrayItem ( COMMA arrayItem )* )? RBRACK
+ -> ^( ARRAY[$lb, "ARRAY"] arrayItem* )
+ ;
+
+arrayItem
+ : ( expr=assignmentExpression | { input.LA(1) == COMMA }? )
+ -> ^( ITEM $expr? )
+ ;
+
+objectLiteral
+ : lb=LBRACE ( nameValuePair ( COMMA nameValuePair )* )? RBRACE
+ -> ^( OBJECT[$lb, "OBJECT"] nameValuePair* )
+ ;
+
+nameValuePair
+ : propertyName COLON assignmentExpression
+ -> ^( NAMEDVALUE propertyName assignmentExpression )
+ ;
+
+propertyName
+ : Identifier
+ | StringLiteral
+ | numericLiteral
+ ;
+
+// $>
+
+// $ ^( ARGS assignmentExpression* )
+ ;
+
+leftHandSideExpression
+ :
+ (
+ memberExpression -> memberExpression
+ )
+ (
+ arguments -> ^( CALL $leftHandSideExpression arguments )
+ | LBRACK expression RBRACK -> ^( BYINDEX $leftHandSideExpression expression )
+ | DOT Identifier -> ^( BYFIELD $leftHandSideExpression Identifier )
+ )*
+ ;
+
+// $>
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $ leftHandSideExpression assignmentOperator^ assignmentExpression
+ | conditionalExpression
+ ;
+assignmentOperator
+ : ASSIGN | MULASS | DIVASS | MODASS | ADDASS | SUBASS | SHLASS | SHRASS | SHUASS | ANDASS | XORASS | ORASS
+ ;
+
+But that didn't seem to work. Terence Par writes in his book that LL(*) conflicts in general can best be solved with auto backtracking. But that would be
+a performance killer for such a heavy used rule.
+The solution I came up with is to always invoke the conditionalExpression first and than decide what to do based on the result of that rule.
+When the rule results in a Tree that can't be coming from a left hand side expression, then we're done.
+When it results in a Tree that is coming from a left hand side expression and the LA(1) is an assignment operator then parse the assignment operator
+followed by the right recursive call.
+*/
+assignmentExpression
+@init
+{
+ bool? isLhs = null;
+}
+ : lhs=conditionalExpression
+ ( { IsLeftHandSideAssign(lhs, ref isLhs) }? assignmentOperator^ assignmentExpression )?
+ ;
+
+assignmentOperator
+ : ASSIGN | MULASS | DIVASS | MODASS | ADDASS | SUBASS | SHLASS | SHRASS | SHUASS | ANDASS | XORASS | ORASS
+ ;
+
+assignmentExpressionNoIn
+@init
+{
+ bool? isLhs = null;
+}
+ : lhs=conditionalExpressionNoIn
+ ( { IsLeftHandSideAssign(lhs, ref isLhs) }? assignmentOperator^ assignmentExpressionNoIn )?
+ ;
+
+// $>
+
+// $ { $exprs.Count > 1 }? ^( CEXPR $exprs+ )
+ -> $exprs
+ ;
+
+expressionNoIn
+ : exprs+=assignmentExpressionNoIn ( COMMA exprs+=assignmentExpressionNoIn )*
+ -> { $exprs.Count > 1 }? ^( CEXPR $exprs+ )
+ -> $exprs
+ ;
+
+// $>
+
+// $>
+
+//
+// $< A.4 Statements (12)
+//
+
+/*
+This rule handles semicolons reported by the lexer and situations where the ECMA 3 specification states there should be semicolons automaticly inserted.
+The auto semicolons are not actually inserted but this rule behaves as if they were.
+
+In the following situations an ECMA 3 parser should auto insert absent but grammaticly required semicolons:
+- the current token is a right brace
+- the current token is the end of file (EOF) token
+- there is at least one end of line (EOL) token between the current token and the previous token.
+
+The RBRACE is handled by matching it but not consuming it.
+The EOF needs no further handling because it is not consumed by default.
+The EOL situation is handled by promoting the EOL or MultiLineComment with an EOL present from off channel to on channel
+and thus making it parseable instead of handling it as white space. This promoting is done in the action PromoteEOL.
+*/
+semic
+@init
+{
+ // Mark current position so we can unconsume a RBRACE.
+ int marker = input.Mark();
+ // Promote EOL if appropriate
+ PromoteEOL(retval);
+}
+ : SEMIC
+ | EOF
+ | RBRACE { input.Rewind(marker); }
+ | EOL | MultiLineComment // (with EOL in it)
+ ;
+
+/*
+To solve the ambiguity between block and objectLiteral via expressionStatement all but the block alternatives have been moved to statementTail.
+Now when k = 1 and a semantical predicate is defined ANTLR generates code that always will prefer block when the LA(1) is a LBRACE.
+This will result in the same behaviour that is described in the specification under 12.4 on the expressionStatement rule.
+*/
+statement
+options
+{
+ k = 1 ;
+}
+ : { input.LA(1) == LBRACE }? block
+ | statementTail
+ ;
+
+statementTail
+ : variableStatement
+ | emptyStatement
+ | expressionStatement
+ | ifStatement
+ | iterationStatement
+ | continueStatement
+ | breakStatement
+ | returnStatement
+ | withStatement
+ | labelledStatement
+ | switchStatement
+ | throwStatement
+ | tryStatement
+ ;
+
+// $ ^( BLOCK[$lb, "BLOCK"] statement* )
+ ;
+
+// $>
+
+// $ ^( VAR variableDeclaration+ )
+ ;
+
+variableDeclaration
+ : Identifier ( ASSIGN^ assignmentExpression )?
+ ;
+
+variableDeclarationNoIn
+ : Identifier ( ASSIGN^ assignmentExpressionNoIn )?
+ ;
+
+// $>
+
+// $
+
+// $
+
+// $ ^( IF expression statement+ )
+ ;
+
+// $>
+
+// $ ^( DO statement expression )
+ ;
+
+whileStatement
+ : WHILE^ LPAREN! expression RPAREN! statement
+ ;
+
+/*
+The forStatement production is refactored considerably as the specification contains a very none LL(*) compliant definition.
+The initial version was like this:
+
+forStatement
+ : FOR^ LPAREN! forControl RPAREN! statement
+ ;
+forControl
+options
+{
+ backtrack = true ;
+ //k = 3 ;
+}
+ : stepClause
+ | iterationClause
+ ;
+stepClause
+options
+{
+ memoize = true ;
+}
+ : ( ex1=expressionNoIn | var=VAR variableDeclarationNoIn ( COMMA variableDeclarationNoIn )* )? SEMIC ex2=expression? SEMIC ex3=expression?
+ -> { $var != null }? ^( FORSTEP ^( VAR[$var] variableDeclarationNoIn+ ) ^( EXPR $ex2? ) ^( EXPR $ex3? ) )
+ -> ^( FORSTEP ^( EXPR $ex1? ) ^( EXPR $ex2? ) ^( EXPR $ex3? ) )
+ ;
+iterationClause
+options
+{
+ memoize = true ;
+}
+ : ( leftHandSideExpression | var=VAR variableDeclarationNoIn ) IN expression
+ -> { $var != null }? ^( FORITER ^( VAR[$var] variableDeclarationNoIn ) ^( EXPR expression ) )
+ -> ^( FORITER ^( EXPR leftHandSideExpression ) ^( EXPR expression ) )
+ ;
+
+But this completely relies on the backtrack feature and capabilities of ANTLR.
+Furthermore backtracking seemed to have 3 major drawbacks:
+- the performance cost of backtracking is considerably
+- didn't seem to work well with ANTLRWorks
+- when introducing a k value to optimize the backtracking away, ANTLR runs out of heap space
+*/
+forStatement
+ : FOR^ LPAREN! forControl RPAREN! statement
+ ;
+
+forControl
+ : forControlVar
+ | forControlExpression
+ | forControlSemic
+ ;
+
+forControlVar
+ : VAR variableDeclarationNoIn
+ (
+ (
+ IN expression
+ -> ^( FORITER ^( VAR variableDeclarationNoIn ) ^( EXPR expression ) )
+ )
+ |
+ (
+ ( COMMA variableDeclarationNoIn )* SEMIC ex1=expression? SEMIC ex2=expression?
+ -> ^( FORSTEP ^( VAR variableDeclarationNoIn+ ) ^( EXPR $ex1? ) ^( EXPR $ex2? ) )
+ )
+ )
+ ;
+
+forControlExpression
+@init
+{
+ bool? isLhs = null;
+}
+ : ex1=expressionNoIn
+ (
+ { IsLeftHandSideIn(ex1, ref isLhs) }? (
+ IN ex2=expression
+ -> ^( FORITER ^( EXPR $ex1 ) ^( EXPR $ex2 ) )
+ )
+ |
+ (
+ SEMIC ex2=expression? SEMIC ex3=expression?
+ -> ^( FORSTEP ^( EXPR $ex1 ) ^( EXPR $ex2? ) ^( EXPR $ex3? ) )
+ )
+ )
+ ;
+
+forControlSemic
+ : SEMIC ex1=expression? SEMIC ex2=expression?
+ -> ^( FORSTEP ^( EXPR ) ^( EXPR $ex1? ) ^( EXPR $ex2? ) )
+ ;
+
+// $>
+
+// $
+
+// $
+
+// $
+
+// $
+
+// $ defaultClause { defaultClauseCount++; } | caseClause )* RBRACE
+ -> ^( SWITCH expression defaultClause? caseClause* )
+ ;
+
+caseClause
+ : CASE^ expression COLON! statement*
+ ;
+
+defaultClause
+ : DEFAULT^ COLON! statement*
+ ;
+
+// $>
+
+// $ ^( LABELLED Identifier statement )
+ ;
+
+// $>
+
+// $
+
+// $
+
+// $>
+
+//
+// $< A.5 Functions and Programs (13, 14)
+//
+
+// $< Function Definition (13)
+
+functionDeclaration
+ : FUNCTION name=Identifier formalParameterList functionBody
+ -> ^( FUNCTION $name formalParameterList functionBody )
+ ;
+
+functionExpression
+ : FUNCTION name=Identifier? formalParameterList functionBody
+ -> ^( FUNCTION $name? formalParameterList functionBody )
+ ;
+
+formalParameterList
+ : LPAREN ( Identifier ( COMMA Identifier )* )? RPAREN
+ -> ^( ARGS Identifier* )
+ ;
+
+functionBody
+ : lb=LBRACE sourceElement* RBRACE
+ -> ^( BLOCK[$lb, "BLOCK"] sourceElement* )
+ ;
+
+// $>
+
+// $< Program (14)
+
+program
+ : sourceElement*
+ ;
+
+/*
+By setting k to 1 for this rule and adding the semantical predicate ANTRL will generate code that will always prefer functionDeclararion over functionExpression
+here and therefor remove the ambiguity between these to production.
+This will result in the same behaviour that is described in the specification under 12.4 on the expressionStatement rule.
+*/
+sourceElement
+options
+{
+ k = 1 ;
+}
+ : { input.LA(1) == FUNCTION }? functionDeclaration
+ | statement
+ ;
+
+// $>
+
+// $>
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Lexer.Action.cs b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Lexer.Action.cs
new file mode 100644
index 0000000000..11e57f5cf0
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Lexer.Action.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Text;
+
+using Antlr.Runtime;
+
+namespace Xebic.Parsers.ES3
+{
+ using IToken = Antlr.Runtime.IToken;
+
+ ///
+ /// This partial class is complementary to the lexer generated with ANTLR from the JavaScript.g grammar.
+ /// It implements the actions used in the lexer.
+ ///
+ public partial class ES3Lexer
+ {
+ ///
+ /// Containts the last on channel token.
+ ///
+ protected IToken last;
+
+ ///
+ /// Indicates whether regular expression (yields true) or division expression recognition (false) in the lexer is enabled.
+ /// These are mutual exclusive and the decision which is active in the lexer is based on the previous on channel token.
+ /// When the previous token can be identified as a possible left operand for a division this results in false, otherwise true.
+ ///
+ private bool AreRegularExpressionsEnabled
+ {
+ get
+ {
+ if (last == null)
+ {
+ return true;
+ }
+
+ switch (last.Type)
+ {
+ // identifier
+ case Identifier:
+ // literals
+ case NULL:
+ case TRUE:
+ case FALSE:
+ case THIS:
+ case OctalIntegerLiteral:
+ case DecimalLiteral:
+ case HexIntegerLiteral:
+ case StringLiteral:
+ // member access ending
+ case RBRACK:
+ // function call or nested expression ending
+ case RPAREN:
+ return false;
+
+ // otherwise OK
+ default:
+ return true;
+ }
+ }
+ }
+
+ ///
+ /// Consumes an unicode identifier after validating that the first character can be the starting character.
+ /// This method is called by the lexer logic as fallback alternative when a character can not be considered as start of an identifier in the ASCII range.
+ /// See the Identfier lexer rule for more details.
+ ///
+ private void ConsumeIdentifierUnicodeStart()
+ {
+ int ch = (char)input.LA(1);
+ if (IsIdentifierStartUnicode(ch))
+ {
+ MatchAny();
+ do
+ {
+ ch = (char)input.LA(1);
+ if (ch == '$' || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || ch == '\\' || ch == '_' || (ch >= 'a' && ch <= 'z') || IsIdentifierPartUnicode(ch))
+ {
+ mIdentifierPart();
+ }
+ else
+ {
+ return;
+ }
+ }
+ while (true);
+ }
+ else
+ {
+ throw new NoViableAltException();
+ }
+ }
+
+ ///
+ /// Indicates whether a given character can be a part of an unicode identifier.
+ /// This method doesn't consider ASCII characters that can be a part of an identifier, that is left to the mIdentifierPart method.
+ /// The latter method will call this method to check other characters in the unicode range after evaluating those in the ASCII range.
+ ///
+ /// The character to check.
+ /// True when the character matches, false otherwise.
+ public static bool IsIdentifierPartUnicode(int ch)
+ {
+ switch (Char.GetUnicodeCategory((char)ch))
+ {
+ // UnicodeLetter
+ case UnicodeCategory.UppercaseLetter: // Lu
+ case UnicodeCategory.LowercaseLetter: // Ll
+ case UnicodeCategory.TitlecaseLetter: // Lt
+ case UnicodeCategory.ModifierLetter: // Lm
+ case UnicodeCategory.OtherLetter: // Lo
+ case UnicodeCategory.LetterNumber: // Nl
+ // UnicodeCombiningMark
+ case UnicodeCategory.NonSpacingMark: // Mn
+ case UnicodeCategory.SpacingCombiningMark: // Mc
+ // UnicodeDigit
+ case UnicodeCategory.DecimalDigitNumber: // Nd
+ // UnicodeConnectorPuntuation
+ case UnicodeCategory.ConnectorPunctuation: // Pc
+ return true;
+
+ // Not matching
+ default:
+ return false;
+ }
+ }
+
+ ///
+ /// Indicates whether a given character can be the first character of an unicode identifier.
+ /// This method doesn't consider ASCII characters as it is used in a fallback scenario after the ASCII range is evaluated.
+ ///
+ /// The character to check.
+ /// True when the character matches, false otherwise.
+ public static bool IsIdentifierStartUnicode(int ch)
+ {
+ switch (Char.GetUnicodeCategory((char)ch))
+ {
+ // UnicodeLetter
+ case UnicodeCategory.UppercaseLetter: // Lu
+ case UnicodeCategory.LowercaseLetter: // Ll
+ case UnicodeCategory.TitlecaseLetter: // Lt
+ case UnicodeCategory.ModifierLetter: // Lm
+ case UnicodeCategory.OtherLetter: // Lo
+ case UnicodeCategory.LetterNumber: // Nl
+ return true;
+
+ // Not matching
+ default:
+ return false;
+ }
+ }
+
+ ///
+ /// Override of base to track previous on channel token.
+ /// This token is needed as input to decide whether regular expression or division expression recognition is enabled.
+ ///
+ public override IToken NextToken()
+ {
+ IToken result = base.NextToken();
+ if (result.Channel == DefaultTokenChannel)
+ {
+ last = result;
+ }
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Parser.Action.cs b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Parser.Action.cs
new file mode 100644
index 0000000000..a20ac34e85
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/ES3Parser.Action.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using Antlr.Runtime;
+using Antlr.Runtime.Tree;
+
+namespace Xebic.Parsers.ES3
+{
+ using IToken = Antlr.Runtime.IToken;
+
+ ///
+ /// This partial class is complementary to the parser generated with ANTLR from the JavaScript.g grammar.
+ /// It implements the actions used in the parser.
+ ///
+ public partial class ES3Parser
+ {
+ ///
+ /// Is a RuleReturnScope node candidate for the left-hand-side of an assignment expression?
+ ///
+ /// The RuleReturnScope node
+ /// The cached result of a former call to this method
+ /// True if so, false otherwise
+ public bool IsLeftHandSideAssign(IAstRuleReturnScope lhs, ref bool? cached)
+ {
+ if (cached.HasValue)
+ {
+ return cached.Value;
+ }
+
+ bool result;
+ if (IsLeftHandSideExpression(lhs))
+ {
+ switch (input.LA(1))
+ {
+ case ASSIGN:
+ case MULASS:
+ case DIVASS:
+ case MODASS:
+ case ADDASS:
+ case SUBASS:
+ case SHLASS:
+ case SHRASS:
+ case SHUASS:
+ case ANDASS:
+ case XORASS:
+ case ORASS:
+ result = true;
+ break;
+
+ default:
+ result = false;
+ break;
+ }
+ }
+ else
+ {
+ result = false;
+ }
+
+ cached = result;
+ return result;
+ }
+
+ ///
+ /// Is a RuleReturnScope node candidate a left-hand-side expression?
+ ///
+ /// The RuleReturnScope node
+ /// True if so, false otherwise
+ private bool IsLeftHandSideExpression(IAstRuleReturnScope lhs)
+ {
+ if (lhs.Tree == null) // e.g. during backtracking
+ {
+ return true;
+ }
+ else
+ {
+ switch (((ITree)lhs.Tree).Type)
+ {
+ // primaryExpression
+ case THIS:
+ case Identifier:
+ case NULL:
+ case TRUE:
+ case FALSE:
+ case DecimalLiteral:
+ case OctalIntegerLiteral:
+ case HexIntegerLiteral:
+ case StringLiteral:
+ case RegularExpressionLiteral:
+ case ARRAY:
+ case OBJECT:
+ case PAREXPR:
+ // functionExpression
+ case FUNCTION:
+ // newExpression
+ case NEW:
+ // leftHandSideExpression
+ case CALL:
+ case BYFIELD:
+ case BYINDEX:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+ }
+
+ ///
+ /// Is a RuleReturnScope node candidate for the left-hand-side of an in expression?
+ ///
+ /// The RuleReturnScope node
+ /// The cached result of a former call to this method
+ /// True if so, false otherwise
+ public bool IsLeftHandSideIn(IAstRuleReturnScope lhs, ref bool? cached)
+ {
+ if (cached.HasValue)
+ {
+ return cached.Value;
+ }
+
+ bool result = IsLeftHandSideExpression(lhs) && (input.LA(1) == IN);
+
+ cached = result;
+ return result;
+ }
+
+ ///
+ /// This method handles promotion of an EOL token to on channel in situations where the ECMA 3 specification
+ /// states there should be a semicolon inserted because of an EOL between the current (offending) token
+ /// and the previous token.
+ /// So an semicolon is not actually inserted but the EOL present is switched from off to on channel. In this
+ /// way that EOL gets the notion of an "virtual" semicolon.
+ /// As a side effect a given rule's return scope starting point is set to the found EOL and the input stream is repositioned on it.
+ /// A multi line comment with an EOL is also promoted.
+ ///
+ /// The invoking rule's return scope
+ public void PromoteEOL(ParserRuleReturnScope rule)
+ {
+ // Get current token and its type (the possibly offending token).
+ IToken lt = input.LT(1);
+ int la = lt.Type;
+
+ // We only need to promote an EOL when the current token is offending (not a SEMIC, EOF, RBRACE or EOL).
+ // Promoting an EOL means switching it from off channel to on channel.
+ if (!(la == SEMIC || la == EOF || la == RBRACE || la == EOL))
+ {
+ // Start on the possition before the current token and scan backwards off channel tokens until the previous on channel token.
+ for (int ix = lt.TokenIndex - 1; ix > 0; ix--)
+ {
+ lt = input.Get(ix);
+ if (lt.Channel == DefaultTokenChannel)
+ {
+ // On channel token found: stop scanning.
+ break;
+ }
+ else if (lt.Type == EOL || (lt.Type == MultiLineComment && Regex.IsMatch(lt.Text, "/.*\r\n|\r|\n")))
+ {
+ // We found our EOL: promote it to on channel, position the input on it and reset the rule start.
+ lt.Channel = DefaultTokenChannel;
+ input.Seek(lt.TokenIndex);
+ if (rule != null)
+ {
+ rule.Start = lt;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/Generated/ES3Lexer.cs b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/Generated/ES3Lexer.cs
new file mode 100644
index 0000000000..181b49e4fc
--- /dev/null
+++ b/src/AddIns/BackendBindings/JavaScriptBinding/Project/Src/ES3/Generated/ES3Lexer.cs
@@ -0,0 +1,8149 @@
+// $ANTLR 3.3 Nov 30, 2010 12:45:30 D:\\downloads\\antlr\\ES3\\CSharp\\ES3.g3 2011-07-31 12:36:33
+
+// The variable 'variable' is assigned but its value is never used.
+#pragma warning disable 168, 219
+// Unreachable code detected.
+#pragma warning disable 162
+
+ #pragma warning disable 219, 162
+
+using System;
+using System.Collections.Generic;
+using Antlr.Runtime;
+using Stack = System.Collections.Generic.Stack