Bug 742191 - Part c: Update testharness.js and friends some more; r=Aryeh
authorMs2ger <ms2ger@gmail.com>
Sun, 14 Oct 2012 09:48:14 +0200
changeset 110184 57304bbf9c0e
parent 110183 d2f47ce40141
child 110233 942ed5747b63
child 110983 67067745ab9a
push id23676
push userMs2ger@gmail.com
push date2012-10-14 07:53 +0000
treeherdermozilla-central@57304bbf9c0e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersAryeh
bugs742191
milestone19.0a1
first release with
nightly linux32
57304bbf9c0e / 19.0a1 / 20121014030627 / files
nightly linux64
57304bbf9c0e / 19.0a1 / 20121014030627 / files
nightly mac
57304bbf9c0e / 19.0a1 / 20121014030627 / files
nightly win32
57304bbf9c0e / 19.0a1 / 20121014030627 / files
nightly win64
57304bbf9c0e / 19.0a1 / 20121014030627 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 742191 - Part c: Update testharness.js and friends some more; r=Aryeh
dom/imptests/WebIDLParser.js
dom/imptests/failures/webapps/XMLHttpRequest/tests/submissions/Ms2ger/test_interfaces.html.json
dom/imptests/idlharness.js
dom/imptests/webapps/XMLHttpRequest/tests/submissions/Ms2ger/test_interfaces.html
--- a/dom/imptests/WebIDLParser.js
+++ b/dom/imptests/WebIDLParser.js
@@ -1,6986 +1,5990 @@
 // From https://github.com/darobin/webidl.js/tree/, under MIT license
 window.WebIDLParser = (function(){
-  /* Generated by PEG.js 0.6.2 (http://pegjs.majda.cz/). */
+  /*
+   * Generated by PEG.js 0.7.0.
+   *
+   * http://pegjs.majda.cz/
+   */
+  
+  function quote(s) {
+    /*
+     * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
+     * string literal except for the closing quote character, backslash,
+     * carriage return, line separator, paragraph separator, and line feed.
+     * Any character may appear in the form of an escape sequence.
+     *
+     * For portability, we also escape escape all control and non-ASCII
+     * characters. Note that "\0" and "\v" escape sequences are not used
+     * because JSHint does not like the first and IE the second.
+     */
+     return '"' + s
+      .replace(/\\/g, '\\\\')  // backslash
+      .replace(/"/g, '\\"')    // closing quote character
+      .replace(/\x08/g, '\\b') // backspace
+      .replace(/\t/g, '\\t')   // horizontal tab
+      .replace(/\n/g, '\\n')   // line feed
+      .replace(/\f/g, '\\f')   // form feed
+      .replace(/\r/g, '\\r')   // carriage return
+      .replace(/[\x00-\x07\x0B\x0E-\x1F\x80-\uFFFF]/g, escape)
+      + '"';
+  }
   
   var result = {
     /*
      * Parses the input with a generated parser. If the parsing is successfull,
      * returns a value explicitly or implicitly specified by the grammar from
      * which the parser was generated (see |PEG.buildParser|). If the parsing is
      * unsuccessful, throws |PEG.parser.SyntaxError| describing the error.
      */
     parse: function(input, startRule) {
       var parseFunctions = {
-        "AbsoluteScopedName": parse_AbsoluteScopedName,
-        "Argument": parse_Argument,
-        "Arguments": parse_Arguments,
-        "ArgumentsRest": parse_ArgumentsRest,
+        "space": parse_space,
+        "s": parse_s,
+        "w": parse_w,
+        "identifier": parse_identifier,
+        "octal": parse_octal,
+        "hex": parse_hex,
+        "decimal": parse_decimal,
+        "integer": parse_integer,
+        "floatEe": parse_floatEe,
+        "expFloat": parse_expFloat,
+        "leadFloat": parse_leadFloat,
+        "dotFloat": parse_dotFloat,
+        "float": parse_float,
+        "string": parse_string,
+        "other": parse_other,
+        "type": parse_type,
+        "TypeDesc": parse_TypeDesc,
+        "Sequence": parse_Sequence,
         "ArrayType": parse_ArrayType,
-        "Attribute": parse_Attribute,
-        "BooleanLiteral": parse_BooleanLiteral,
-        "EnumValues": parse_EnumValues,
-        "EnumValuesRest": parse_EnumValuesRest,
-        "ExtAttr": parse_ExtAttr,
-        "ExtAttrArgList": parse_ExtAttrArgList,
-        "ExtAttrNameValue": parse_ExtAttrNameValue,
-        "ExtAttrNamedArgList": parse_ExtAttrNamedArgList,
-        "ExtAttrNoArg": parse_ExtAttrNoArg,
-        "ExtAttrs": parse_ExtAttrs,
-        "ExtAttrsRest": parse_ExtAttrsRest,
-        "FloatType": parse_FloatType,
-        "GetRaises": parse_GetRaises,
-        "Nullable": parse_Nullable,
-        "Operation": parse_Operation,
-        "OperationRest": parse_OperationRest,
-        "PrimitiveType": parse_PrimitiveType,
-        "Qualifiers": parse_Qualifiers,
-        "Raises": parse_Raises,
-        "RelativeScopedName": parse_RelativeScopedName,
-        "ReturnType": parse_ReturnType,
-        "ScopedName": parse_ScopedName,
-        "ScopedNameList": parse_ScopedNameList,
-        "ScopedNameListRest": parse_ScopedNameListRest,
-        "ScopedNameRest": parse_ScopedNameRest,
-        "Sequence": parse_Sequence,
-        "SetRaises": parse_SetRaises,
-        "SimpleType": parse_SimpleType,
-        "Special": parse_Special,
-        "Stringifier": parse_Stringifier,
-        "TypeDesc": parse_TypeDesc,
+        "UnionType": parse_UnionType,
         "TypeList": parse_TypeList,
         "TypeListRest": parse_TypeListRest,
-        "UnionType": parse_UnionType,
+        "SimpleType": parse_SimpleType,
+        "PrimitiveType": parse_PrimitiveType,
+        "FloatType": parse_FloatType,
         "UnsignedIntegerType": parse_UnsignedIntegerType,
-        "attrOrOp": parse_attrOrOp,
+        "ScopedNameList": parse_ScopedNameList,
+        "ScopedNameListRest": parse_ScopedNameListRest,
+        "ScopedName": parse_ScopedName,
+        "AbsoluteScopedName": parse_AbsoluteScopedName,
+        "RelativeScopedName": parse_RelativeScopedName,
+        "ScopedNameRest": parse_ScopedNameRest,
+        "BooleanLiteral": parse_BooleanLiteral,
+        "Nullable": parse_Nullable,
+        "ReturnType": parse_ReturnType,
+        "definitions": parse_definitions,
+        "definition": parse_definition,
+        "partialinterface": parse_partialinterface,
+        "partialdictionary": parse_partialdictionary,
+        "callbackinterface": parse_callbackinterface,
+        "module": parse_module,
+        "implements": parse_implements,
+        "interface": parse_interface,
+        "enum": parse_enum,
         "callback": parse_callback,
-        "callbackinterface": parse_callbackinterface,
+        "EnumValues": parse_EnumValues,
+        "EnumValuesRest": parse_EnumValuesRest,
+        "Inheritance": parse_Inheritance,
+        "InheritanceInner": parse_InheritanceInner,
+        "InterfaceMemberList": parse_InterfaceMemberList,
+        "InterfaceMember": parse_InterfaceMember,
         "const": parse_const,
         "constExpr": parse_constExpr,
-        "decimal": parse_decimal,
-        "defaultValue": parse_defaultValue,
-        "definition": parse_definition,
-        "definitions": parse_definitions,
+        "attrOrOp": parse_attrOrOp,
+        "Stringifier": parse_Stringifier,
+        "Attribute": parse_Attribute,
+        "GetRaises": parse_GetRaises,
+        "SetRaises": parse_SetRaises,
+        "Operation": parse_Operation,
+        "Qualifiers": parse_Qualifiers,
+        "Special": parse_Special,
+        "OperationRest": parse_OperationRest,
+        "Arguments": parse_Arguments,
+        "ArgumentsRest": parse_ArgumentsRest,
+        "Argument": parse_Argument,
+        "Raises": parse_Raises,
         "dictionary": parse_dictionary,
-        "dictionaryMember": parse_dictionaryMember,
-        "dotFloat": parse_dotFloat,
-        "enum": parse_enum,
-        "exMember": parse_exMember,
+        "DictionaryMemberList": parse_DictionaryMemberList,
+        "DictionaryMember": parse_DictionaryMember,
+        "defaultValue": parse_defaultValue,
+        "typedef": parse_typedef,
         "exception": parse_exception,
-        "expFloat": parse_expFloat,
-        "extendedAttributeList": parse_extendedAttributeList,
+        "ExceptionMembers": parse_ExceptionMembers,
+        "ExceptionMember": parse_ExceptionMember,
         "field": parse_field,
-        "float": parse_float,
-        "floatEe": parse_floatEe,
-        "hex": parse_hex,
-        "identifier": parse_identifier,
-        "ifInheritance": parse_ifInheritance,
-        "ifMember": parse_ifMember,
-        "implements": parse_implements,
-        "integer": parse_integer,
-        "interface": parse_interface,
-        "leadFloat": parse_leadFloat,
-        "module": parse_module,
-        "octal": parse_octal,
-        "other": parse_other,
-        "partialinterface": parse_partialinterface,
-        "s": parse_s,
-        "space": parse_space,
-        "string": parse_string,
-        "type": parse_type,
-        "typedef": parse_typedef,
-        "w": parse_w
+        "ExtendedAttributeList": parse_ExtendedAttributeList,
+        "ExtendedAttributeListInner": parse_ExtendedAttributeListInner,
+        "ExtAttrs": parse_ExtAttrs,
+        "ExtAttrsRest": parse_ExtAttrsRest,
+        "ExtAttr": parse_ExtAttr,
+        "ExtAttrNoArg": parse_ExtAttrNoArg,
+        "ExtAttrNameValue": parse_ExtAttrNameValue,
+        "ExtAttrNamedArgList": parse_ExtAttrNamedArgList,
+        "ExtAttrNamedArgList": parse_ExtAttrNamedArgList,
+        "ExtAttrArgList": parse_ExtAttrArgList
       };
       
       if (startRule !== undefined) {
         if (parseFunctions[startRule] === undefined) {
           throw new Error("Invalid rule name: " + quote(startRule) + ".");
         }
       } else {
         startRule = "definitions";
       }
       
       var pos = 0;
-      var reportMatchFailures = true;
-      var rightmostMatchFailuresPos = 0;
-      var rightmostMatchFailuresExpected = [];
-      var cache = {};
+      var reportFailures = 0;
+      var rightmostFailuresPos = 0;
+      var rightmostFailuresExpected = [];
       
       function padLeft(input, padding, length) {
         var result = input;
         
         var padLength = length - input.length;
         for (var i = 0; i < padLength; i++) {
           result = padding + result;
         }
         
         return result;
       }
       
       function escape(ch) {
         var charCode = ch.charCodeAt(0);
+        var escapeChar;
+        var length;
         
         if (charCode <= 0xFF) {
-          var escapeChar = 'x';
-          var length = 2;
+          escapeChar = 'x';
+          length = 2;
         } else {
-          var escapeChar = 'u';
-          var length = 4;
+          escapeChar = 'u';
+          length = 4;
         }
         
         return '\\' + escapeChar + padLeft(charCode.toString(16).toUpperCase(), '0', length);
       }
       
-      function quote(s) {
-        /*
-         * ECMA-262, 5th ed., 7.8.4: All characters may appear literally in a
-         * string literal except for the closing quote character, backslash,
-         * carriage return, line separator, paragraph separator, and line feed.
-         * Any character may appear in the form of an escape sequence.
-         */
-        return '"' + s
-          .replace(/\\/g, '\\\\')            // backslash
-          .replace(/"/g, '\\"')              // closing quote character
-          .replace(/\r/g, '\\r')             // carriage return
-          .replace(/\n/g, '\\n')             // line feed
-          .replace(/[\x80-\uFFFF]/g, escape) // non-ASCII characters
-          + '"';
-      }
-      
       function matchFailed(failure) {
-        if (pos < rightmostMatchFailuresPos) {
+        if (pos < rightmostFailuresPos) {
           return;
         }
         
-        if (pos > rightmostMatchFailuresPos) {
-          rightmostMatchFailuresPos = pos;
-          rightmostMatchFailuresExpected = [];
+        if (pos > rightmostFailuresPos) {
+          rightmostFailuresPos = pos;
+          rightmostFailuresExpected = [];
         }
         
-        rightmostMatchFailuresExpected.push(failure);
+        rightmostFailuresExpected.push(failure);
       }
       
       function parse_space() {
-        var cacheKey = 'space@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3;
+        var pos0, pos1, pos2;
         
-        
-        if (input.substr(pos, 1) === " ") {
-          var result20 = " ";
-          pos += 1;
+        if (input.charCodeAt(pos) === 32) {
+          result0 = " ";
+          pos++;
         } else {
-          var result20 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\" \"");
           }
         }
-        if (result20 !== null) {
-          var result0 = result20;
-        } else {
-          if (input.substr(pos, 1) === "	") {
-            var result19 = "	";
-            pos += 1;
+        if (result0 === null) {
+          if (input.charCodeAt(pos) === 9) {
+            result0 = "\t";
+            pos++;
           } else {
-            var result19 = null;
-            if (reportMatchFailures) {
-              matchFailed("\"	\"");
+            result0 = null;
+            if (reportFailures === 0) {
+              matchFailed("\"\\t\"");
             }
           }
-          if (result19 !== null) {
-            var result0 = result19;
-          } else {
-            if (input.substr(pos, 1) === "\r") {
-              var result18 = "\r";
-              pos += 1;
+          if (result0 === null) {
+            if (input.charCodeAt(pos) === 13) {
+              result0 = "\r";
+              pos++;
             } else {
-              var result18 = null;
-              if (reportMatchFailures) {
+              result0 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"\\r\"");
               }
             }
-            if (result18 !== null) {
-              var result0 = result18;
-            } else {
-              if (input.substr(pos, 1) === "\n") {
-                var result17 = "\n";
-                pos += 1;
+            if (result0 === null) {
+              if (input.charCodeAt(pos) === 10) {
+                result0 = "\n";
+                pos++;
               } else {
-                var result17 = null;
-                if (reportMatchFailures) {
+                result0 = null;
+                if (reportFailures === 0) {
                   matchFailed("\"\\n\"");
                 }
               }
-              if (result17 !== null) {
-                var result0 = result17;
-              } else {
-                if (input.substr(pos, 1) === "") {
-                  var result16 = "";
-                  pos += 1;
+              if (result0 === null) {
+                if (input.charCodeAt(pos) === 12) {
+                  result0 = "\f";
+                  pos++;
                 } else {
-                  var result16 = null;
-                  if (reportMatchFailures) {
-                    matchFailed("\"\"");
+                  result0 = null;
+                  if (reportFailures === 0) {
+                    matchFailed("\"\\f\"");
                   }
                 }
-                if (result16 !== null) {
-                  var result0 = result16;
-                } else {
-                  var savedPos3 = pos;
+                if (result0 === null) {
+                  pos0 = pos;
                   if (input.substr(pos, 2) === "//") {
-                    var result12 = "//";
+                    result0 = "//";
                     pos += 2;
                   } else {
-                    var result12 = null;
-                    if (reportMatchFailures) {
+                    result0 = null;
+                    if (reportFailures === 0) {
                       matchFailed("\"//\"");
                     }
                   }
-                  if (result12 !== null) {
-                    var result13 = [];
-                    if (input.substr(pos).match(/^[^\n]/) !== null) {
-                      var result15 = input.charAt(pos);
+                  if (result0 !== null) {
+                    result1 = [];
+                    if (/^[^\n]/.test(input.charAt(pos))) {
+                      result2 = input.charAt(pos);
                       pos++;
                     } else {
-                      var result15 = null;
-                      if (reportMatchFailures) {
+                      result2 = null;
+                      if (reportFailures === 0) {
                         matchFailed("[^\\n]");
                       }
                     }
-                    while (result15 !== null) {
-                      result13.push(result15);
-                      if (input.substr(pos).match(/^[^\n]/) !== null) {
-                        var result15 = input.charAt(pos);
+                    while (result2 !== null) {
+                      result1.push(result2);
+                      if (/^[^\n]/.test(input.charAt(pos))) {
+                        result2 = input.charAt(pos);
                         pos++;
                       } else {
-                        var result15 = null;
-                        if (reportMatchFailures) {
+                        result2 = null;
+                        if (reportFailures === 0) {
                           matchFailed("[^\\n]");
                         }
                       }
                     }
-                    if (result13 !== null) {
-                      if (input.substr(pos, 1) === "\n") {
-                        var result14 = "\n";
-                        pos += 1;
+                    if (result1 !== null) {
+                      if (input.charCodeAt(pos) === 10) {
+                        result2 = "\n";
+                        pos++;
                       } else {
-                        var result14 = null;
-                        if (reportMatchFailures) {
+                        result2 = null;
+                        if (reportFailures === 0) {
                           matchFailed("\"\\n\"");
                         }
                       }
-                      if (result14 !== null) {
-                        var result11 = [result12, result13, result14];
+                      if (result2 !== null) {
+                        result0 = [result0, result1, result2];
                       } else {
-                        var result11 = null;
-                        pos = savedPos3;
+                        result0 = null;
+                        pos = pos0;
                       }
                     } else {
-                      var result11 = null;
-                      pos = savedPos3;
+                      result0 = null;
+                      pos = pos0;
                     }
                   } else {
-                    var result11 = null;
-                    pos = savedPos3;
+                    result0 = null;
+                    pos = pos0;
                   }
-                  if (result11 !== null) {
-                    var result0 = result11;
-                  } else {
-                    var savedPos0 = pos;
+                  if (result0 === null) {
+                    pos0 = pos;
                     if (input.substr(pos, 2) === "/*") {
-                      var result2 = "/*";
+                      result0 = "/*";
                       pos += 2;
                     } else {
-                      var result2 = null;
-                      if (reportMatchFailures) {
+                      result0 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\"/*\"");
                       }
                     }
-                    if (result2 !== null) {
-                      var result3 = [];
-                      if (input.substr(pos).match(/^[^*]/) !== null) {
-                        var result10 = input.charAt(pos);
+                    if (result0 !== null) {
+                      result1 = [];
+                      if (/^[^*]/.test(input.charAt(pos))) {
+                        result2 = input.charAt(pos);
                         pos++;
                       } else {
-                        var result10 = null;
-                        if (reportMatchFailures) {
+                        result2 = null;
+                        if (reportFailures === 0) {
                           matchFailed("[^*]");
                         }
                       }
-                      if (result10 !== null) {
-                        var result5 = result10;
-                      } else {
-                        var savedPos1 = pos;
-                        if (input.substr(pos, 1) === "*") {
-                          var result7 = "*";
-                          pos += 1;
+                      if (result2 === null) {
+                        pos1 = pos;
+                        if (input.charCodeAt(pos) === 42) {
+                          result2 = "*";
+                          pos++;
                         } else {
-                          var result7 = null;
-                          if (reportMatchFailures) {
+                          result2 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\"*\"");
                           }
                         }
-                        if (result7 !== null) {
-                          var savedPos2 = pos;
-                          var savedReportMatchFailuresVar0 = reportMatchFailures;
-                          reportMatchFailures = false;
-                          if (input.substr(pos, 1) === "/") {
-                            var result9 = "/";
-                            pos += 1;
+                        if (result2 !== null) {
+                          pos2 = pos;
+                          reportFailures++;
+                          if (input.charCodeAt(pos) === 47) {
+                            result3 = "/";
+                            pos++;
                           } else {
-                            var result9 = null;
-                            if (reportMatchFailures) {
+                            result3 = null;
+                            if (reportFailures === 0) {
                               matchFailed("\"/\"");
                             }
                           }
-                          reportMatchFailures = savedReportMatchFailuresVar0;
-                          if (result9 === null) {
-                            var result8 = '';
+                          reportFailures--;
+                          if (result3 === null) {
+                            result3 = "";
                           } else {
-                            var result8 = null;
-                            pos = savedPos2;
+                            result3 = null;
+                            pos = pos2;
                           }
-                          if (result8 !== null) {
-                            var result6 = [result7, result8];
+                          if (result3 !== null) {
+                            result2 = [result2, result3];
                           } else {
-                            var result6 = null;
-                            pos = savedPos1;
+                            result2 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result6 = null;
-                          pos = savedPos1;
+                          result2 = null;
+                          pos = pos1;
                         }
-                        if (result6 !== null) {
-                          var result5 = result6;
-                        } else {
-                          var result5 = null;;
-                        };
                       }
-                      while (result5 !== null) {
-                        result3.push(result5);
-                        if (input.substr(pos).match(/^[^*]/) !== null) {
-                          var result10 = input.charAt(pos);
+                      while (result2 !== null) {
+                        result1.push(result2);
+                        if (/^[^*]/.test(input.charAt(pos))) {
+                          result2 = input.charAt(pos);
                           pos++;
                         } else {
-                          var result10 = null;
-                          if (reportMatchFailures) {
+                          result2 = null;
+                          if (reportFailures === 0) {
                             matchFailed("[^*]");
                           }
                         }
-                        if (result10 !== null) {
-                          var result5 = result10;
-                        } else {
-                          var savedPos1 = pos;
-                          if (input.substr(pos, 1) === "*") {
-                            var result7 = "*";
-                            pos += 1;
+                        if (result2 === null) {
+                          pos1 = pos;
+                          if (input.charCodeAt(pos) === 42) {
+                            result2 = "*";
+                            pos++;
                           } else {
-                            var result7 = null;
-                            if (reportMatchFailures) {
+                            result2 = null;
+                            if (reportFailures === 0) {
                               matchFailed("\"*\"");
                             }
                           }
-                          if (result7 !== null) {
-                            var savedPos2 = pos;
-                            var savedReportMatchFailuresVar0 = reportMatchFailures;
-                            reportMatchFailures = false;
-                            if (input.substr(pos, 1) === "/") {
-                              var result9 = "/";
-                              pos += 1;
+                          if (result2 !== null) {
+                            pos2 = pos;
+                            reportFailures++;
+                            if (input.charCodeAt(pos) === 47) {
+                              result3 = "/";
+                              pos++;
                             } else {
-                              var result9 = null;
-                              if (reportMatchFailures) {
+                              result3 = null;
+                              if (reportFailures === 0) {
                                 matchFailed("\"/\"");
                               }
                             }
-                            reportMatchFailures = savedReportMatchFailuresVar0;
-                            if (result9 === null) {
-                              var result8 = '';
+                            reportFailures--;
+                            if (result3 === null) {
+                              result3 = "";
                             } else {
-                              var result8 = null;
-                              pos = savedPos2;
+                              result3 = null;
+                              pos = pos2;
                             }
-                            if (result8 !== null) {
-                              var result6 = [result7, result8];
+                            if (result3 !== null) {
+                              result2 = [result2, result3];
                             } else {
-                              var result6 = null;
-                              pos = savedPos1;
+                              result2 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result6 = null;
-                            pos = savedPos1;
+                            result2 = null;
+                            pos = pos1;
                           }
-                          if (result6 !== null) {
-                            var result5 = result6;
-                          } else {
-                            var result5 = null;;
-                          };
                         }
                       }
-                      if (result3 !== null) {
+                      if (result1 !== null) {
                         if (input.substr(pos, 2) === "*/") {
-                          var result4 = "*/";
+                          result2 = "*/";
                           pos += 2;
                         } else {
-                          var result4 = null;
-                          if (reportMatchFailures) {
+                          result2 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\"*/\"");
                           }
                         }
-                        if (result4 !== null) {
-                          var result1 = [result2, result3, result4];
+                        if (result2 !== null) {
+                          result0 = [result0, result1, result2];
                         } else {
-                          var result1 = null;
-                          pos = savedPos0;
+                          result0 = null;
+                          pos = pos0;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos0;
+                        result0 = null;
+                        pos = pos0;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos0;
+                      result0 = null;
+                      pos = pos0;
                     }
-                    if (result1 !== null) {
-                      var result0 = result1;
-                    } else {
-                      var result0 = null;;
-                    };
-                  };
-                };
-              };
-            };
-          };
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+                  }
+                }
+              }
+            }
+          }
+        }
         return result0;
       }
       
       function parse_s() {
-        var cacheKey = 's@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1;
         
-        
-        var result1 = parse_space();
+        result1 = parse_space();
         if (result1 !== null) {
-          var result0 = [];
+          result0 = [];
           while (result1 !== null) {
             result0.push(result1);
-            var result1 = parse_space();
+            result1 = parse_space();
           }
         } else {
-          var result0 = null;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+        }
         return result0;
       }
       
       function parse_w() {
-        var cacheKey = 'w@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
         
-        var result1 = parse_s();
-        var result0 = result1 !== null ? result1 : '';
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        result0 = parse_s();
+        result0 = result0 !== null ? result0 : "";
         return result0;
       }
       
       function parse_identifier() {
-        var cacheKey = 'identifier@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos).match(/^[A-Z_a-z]/) !== null) {
-          var result3 = input.charAt(pos);
+        pos0 = pos;
+        pos1 = pos;
+        if (/^[A-Z_a-z]/.test(input.charAt(pos))) {
+          result0 = input.charAt(pos);
           pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("[A-Z_a-z]");
           }
         }
-        if (result3 !== null) {
-          var result4 = [];
-          if (input.substr(pos).match(/^[0-9A-Z_a-z]/) !== null) {
-            var result5 = input.charAt(pos);
+        if (result0 !== null) {
+          result1 = [];
+          if (/^[0-9A-Z_a-z]/.test(input.charAt(pos))) {
+            result2 = input.charAt(pos);
             pos++;
           } else {
-            var result5 = null;
-            if (reportMatchFailures) {
+            result2 = null;
+            if (reportFailures === 0) {
               matchFailed("[0-9A-Z_a-z]");
             }
           }
-          while (result5 !== null) {
-            result4.push(result5);
-            if (input.substr(pos).match(/^[0-9A-Z_a-z]/) !== null) {
-              var result5 = input.charAt(pos);
+          while (result2 !== null) {
+            result1.push(result2);
+            if (/^[0-9A-Z_a-z]/.test(input.charAt(pos))) {
+              result2 = input.charAt(pos);
               pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9A-Z_a-z]");
               }
             }
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(nmstart, nmchars) { return nmstart + nmchars.join(""); })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, nmstart, nmchars) { return nmstart + nmchars.join(""); })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_octal() {
-        var cacheKey = 'octal@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === "0") {
-          var result3 = "0";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 48) {
+          result0 = "0";
+          pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"0\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = [];
-          if (input.substr(pos).match(/^[0-7]/) !== null) {
-            var result5 = input.charAt(pos);
+        if (result0 !== null) {
+          result1 = [];
+          if (/^[0-7]/.test(input.charAt(pos))) {
+            result2 = input.charAt(pos);
             pos++;
           } else {
-            var result5 = null;
-            if (reportMatchFailures) {
+            result2 = null;
+            if (reportFailures === 0) {
               matchFailed("[0-7]");
             }
           }
-          while (result5 !== null) {
-            result4.push(result5);
-            if (input.substr(pos).match(/^[0-7]/) !== null) {
-              var result5 = input.charAt(pos);
+          while (result2 !== null) {
+            result1.push(result2);
+            if (/^[0-7]/.test(input.charAt(pos))) {
+              result2 = input.charAt(pos);
               pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-7]");
               }
             }
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(value) { return "0" + value.join(""); })(result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, value) { return "0" + value.join(""); })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_hex() {
-        var cacheKey = 'hex@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === "0") {
-          var result3 = "0";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 48) {
+          result0 = "0";
+          pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"0\"");
           }
         }
-        if (result3 !== null) {
-          if (input.substr(pos).match(/^[Xx]/) !== null) {
-            var result4 = input.charAt(pos);
+        if (result0 !== null) {
+          if (/^[Xx]/.test(input.charAt(pos))) {
+            result1 = input.charAt(pos);
             pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("[Xx]");
             }
           }
-          if (result4 !== null) {
-            if (input.substr(pos).match(/^[0-9A-Fa-f]/) !== null) {
-              var result6 = input.charAt(pos);
+          if (result1 !== null) {
+            if (/^[0-9A-Fa-f]/.test(input.charAt(pos))) {
+              result3 = input.charAt(pos);
               pos++;
             } else {
-              var result6 = null;
-              if (reportMatchFailures) {
+              result3 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9A-Fa-f]");
               }
             }
-            if (result6 !== null) {
-              var result5 = [];
-              while (result6 !== null) {
-                result5.push(result6);
-                if (input.substr(pos).match(/^[0-9A-Fa-f]/) !== null) {
-                  var result6 = input.charAt(pos);
+            if (result3 !== null) {
+              result2 = [];
+              while (result3 !== null) {
+                result2.push(result3);
+                if (/^[0-9A-Fa-f]/.test(input.charAt(pos))) {
+                  result3 = input.charAt(pos);
                   pos++;
                 } else {
-                  var result6 = null;
-                  if (reportMatchFailures) {
+                  result3 = null;
+                  if (reportFailures === 0) {
                     matchFailed("[0-9A-Fa-f]");
                   }
                 }
               }
             } else {
-              var result5 = null;
+              result2 = null;
             }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(x, value) { return "0" + x + value.join(""); })(result1[1], result1[2])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, x, value) { return "0" + x + value.join(""); })(pos0, result0[1], result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_decimal() {
-        var cacheKey = 'decimal@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos).match(/^[0-9]/) !== null) {
-          var result3 = input.charAt(pos);
+        pos0 = pos;
+        pos1 = pos;
+        if (/^[0-9]/.test(input.charAt(pos))) {
+          result0 = input.charAt(pos);
           pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("[0-9]");
           }
         }
-        if (result3 !== null) {
-          var result4 = [];
-          if (input.substr(pos).match(/^[0-9]/) !== null) {
-            var result5 = input.charAt(pos);
+        if (result0 !== null) {
+          result1 = [];
+          if (/^[0-9]/.test(input.charAt(pos))) {
+            result2 = input.charAt(pos);
             pos++;
           } else {
-            var result5 = null;
-            if (reportMatchFailures) {
+            result2 = null;
+            if (reportFailures === 0) {
               matchFailed("[0-9]");
             }
           }
-          while (result5 !== null) {
-            result4.push(result5);
-            if (input.substr(pos).match(/^[0-9]/) !== null) {
-              var result5 = input.charAt(pos);
+          while (result2 !== null) {
+            result1.push(result2);
+            if (/^[0-9]/.test(input.charAt(pos))) {
+              result2 = input.charAt(pos);
               pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9]");
               }
             }
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(numStart, numRest) { return numStart + numRest.join(""); })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, numStart, numRest) { return numStart + numRest.join(""); })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_integer() {
-        var cacheKey = 'integer@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === "-") {
-          var result8 = "-";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 45) {
+          result0 = "-";
+          pos++;
         } else {
-          var result8 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"-\"");
           }
         }
-        var result3 = result8 !== null ? result8 : '';
-        if (result3 !== null) {
-          var result7 = parse_hex();
-          if (result7 !== null) {
-            var result4 = result7;
+        result0 = result0 !== null ? result0 : "";
+        if (result0 !== null) {
+          result1 = parse_hex();
+          if (result1 === null) {
+            result1 = parse_octal();
+            if (result1 === null) {
+              result1 = parse_decimal();
+            }
+          }
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result6 = parse_octal();
-            if (result6 !== null) {
-              var result4 = result6;
-            } else {
-              var result5 = parse_decimal();
-              if (result5 !== null) {
-                var result4 = result5;
-              } else {
-                var result4 = null;;
-              };
-            };
-          }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
-          } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(neg, num) { return neg + num; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, neg, num) { return neg + num; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_floatEe() {
-        var cacheKey = 'floatEe@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos).match(/^[Ee]/) !== null) {
-          var result3 = input.charAt(pos);
+        pos0 = pos;
+        pos1 = pos;
+        if (/^[Ee]/.test(input.charAt(pos))) {
+          result0 = input.charAt(pos);
           pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("[Ee]");
           }
         }
-        if (result3 !== null) {
-          if (input.substr(pos).match(/^[+\-]/) !== null) {
-            var result7 = input.charAt(pos);
+        if (result0 !== null) {
+          if (/^[+\-]/.test(input.charAt(pos))) {
+            result1 = input.charAt(pos);
             pos++;
           } else {
-            var result7 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("[+\\-]");
             }
           }
-          var result4 = result7 !== null ? result7 : '';
-          if (result4 !== null) {
-            if (input.substr(pos).match(/^[0-9]/) !== null) {
-              var result6 = input.charAt(pos);
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
+            if (/^[0-9]/.test(input.charAt(pos))) {
+              result3 = input.charAt(pos);
               pos++;
             } else {
-              var result6 = null;
-              if (reportMatchFailures) {
+              result3 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9]");
               }
             }
-            if (result6 !== null) {
-              var result5 = [];
-              while (result6 !== null) {
-                result5.push(result6);
-                if (input.substr(pos).match(/^[0-9]/) !== null) {
-                  var result6 = input.charAt(pos);
+            if (result3 !== null) {
+              result2 = [];
+              while (result3 !== null) {
+                result2.push(result3);
+                if (/^[0-9]/.test(input.charAt(pos))) {
+                  result3 = input.charAt(pos);
                   pos++;
                 } else {
-                  var result6 = null;
-                  if (reportMatchFailures) {
+                  result3 = null;
+                  if (reportFailures === 0) {
                     matchFailed("[0-9]");
                   }
                 }
               }
             } else {
-              var result5 = null;
+              result2 = null;
             }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(e, sign, exp) { return e + sign + exp.join(""); })(result1[0], result1[1], result1[2])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, e, sign, exp) { return e + sign + exp.join(""); })(pos0, result0[0], result0[1], result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_expFloat() {
-        var cacheKey = 'expFloat@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos).match(/^[0-9]/) !== null) {
-          var result5 = input.charAt(pos);
+        pos0 = pos;
+        pos1 = pos;
+        if (/^[0-9]/.test(input.charAt(pos))) {
+          result1 = input.charAt(pos);
           pos++;
         } else {
-          var result5 = null;
-          if (reportMatchFailures) {
+          result1 = null;
+          if (reportFailures === 0) {
             matchFailed("[0-9]");
           }
         }
-        if (result5 !== null) {
-          var result3 = [];
-          while (result5 !== null) {
-            result3.push(result5);
-            if (input.substr(pos).match(/^[0-9]/) !== null) {
-              var result5 = input.charAt(pos);
+        if (result1 !== null) {
+          result0 = [];
+          while (result1 !== null) {
+            result0.push(result1);
+            if (/^[0-9]/.test(input.charAt(pos))) {
+              result1 = input.charAt(pos);
               pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result1 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9]");
               }
             }
           }
         } else {
-          var result3 = null;
-        }
-        if (result3 !== null) {
-          var result4 = parse_floatEe();
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          result0 = null;
+        }
+        if (result0 !== null) {
+          result1 = parse_floatEe();
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(num, fee) { return num.join("") + fee; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, num, fee) { return num.join("") + fee; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_leadFloat() {
-        var cacheKey = 'leadFloat@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos).match(/^[0-9]/) !== null) {
-          var result9 = input.charAt(pos);
+        pos0 = pos;
+        pos1 = pos;
+        if (/^[0-9]/.test(input.charAt(pos))) {
+          result1 = input.charAt(pos);
           pos++;
         } else {
-          var result9 = null;
-          if (reportMatchFailures) {
+          result1 = null;
+          if (reportFailures === 0) {
             matchFailed("[0-9]");
           }
         }
-        if (result9 !== null) {
-          var result3 = [];
-          while (result9 !== null) {
-            result3.push(result9);
-            if (input.substr(pos).match(/^[0-9]/) !== null) {
-              var result9 = input.charAt(pos);
+        if (result1 !== null) {
+          result0 = [];
+          while (result1 !== null) {
+            result0.push(result1);
+            if (/^[0-9]/.test(input.charAt(pos))) {
+              result1 = input.charAt(pos);
               pos++;
             } else {
-              var result9 = null;
-              if (reportMatchFailures) {
+              result1 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9]");
               }
             }
           }
         } else {
-          var result3 = null;
-        }
-        if (result3 !== null) {
-          if (input.substr(pos, 1) === ".") {
-            var result4 = ".";
-            pos += 1;
+          result0 = null;
+        }
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 46) {
+            result1 = ".";
+            pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\".\"");
             }
           }
-          if (result4 !== null) {
-            var result5 = [];
-            if (input.substr(pos).match(/^[0-9]/) !== null) {
-              var result8 = input.charAt(pos);
+          if (result1 !== null) {
+            result2 = [];
+            if (/^[0-9]/.test(input.charAt(pos))) {
+              result3 = input.charAt(pos);
               pos++;
             } else {
-              var result8 = null;
-              if (reportMatchFailures) {
+              result3 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9]");
               }
             }
-            while (result8 !== null) {
-              result5.push(result8);
-              if (input.substr(pos).match(/^[0-9]/) !== null) {
-                var result8 = input.charAt(pos);
+            while (result3 !== null) {
+              result2.push(result3);
+              if (/^[0-9]/.test(input.charAt(pos))) {
+                result3 = input.charAt(pos);
                 pos++;
               } else {
-                var result8 = null;
-                if (reportMatchFailures) {
+                result3 = null;
+                if (reportFailures === 0) {
                   matchFailed("[0-9]");
                 }
               }
             }
-            if (result5 !== null) {
-              var result7 = parse_floatEe();
-              var result6 = result7 !== null ? result7 : '';
-              if (result6 !== null) {
-                var result1 = [result3, result4, result5, result6];
+            if (result2 !== null) {
+              result3 = parse_floatEe();
+              result3 = result3 !== null ? result3 : "";
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(num, dec, fee) { return num.join("") + "." + dec.join("") + fee; })(result1[0], result1[2], result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, num, dec, fee) { return num.join("") + "." + dec.join("") + fee; })(pos0, result0[0], result0[2], result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_dotFloat() {
-        var cacheKey = 'dotFloat@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = [];
-        if (input.substr(pos).match(/^[0-9]/) !== null) {
-          var result9 = input.charAt(pos);
+        pos0 = pos;
+        pos1 = pos;
+        result0 = [];
+        if (/^[0-9]/.test(input.charAt(pos))) {
+          result1 = input.charAt(pos);
           pos++;
         } else {
-          var result9 = null;
-          if (reportMatchFailures) {
+          result1 = null;
+          if (reportFailures === 0) {
             matchFailed("[0-9]");
           }
         }
-        while (result9 !== null) {
-          result3.push(result9);
-          if (input.substr(pos).match(/^[0-9]/) !== null) {
-            var result9 = input.charAt(pos);
+        while (result1 !== null) {
+          result0.push(result1);
+          if (/^[0-9]/.test(input.charAt(pos))) {
+            result1 = input.charAt(pos);
             pos++;
           } else {
-            var result9 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("[0-9]");
             }
           }
         }
-        if (result3 !== null) {
-          if (input.substr(pos, 1) === ".") {
-            var result4 = ".";
-            pos += 1;
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 46) {
+            result1 = ".";
+            pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\".\"");
             }
           }
-          if (result4 !== null) {
-            if (input.substr(pos).match(/^[0-9]/) !== null) {
-              var result8 = input.charAt(pos);
+          if (result1 !== null) {
+            if (/^[0-9]/.test(input.charAt(pos))) {
+              result3 = input.charAt(pos);
               pos++;
             } else {
-              var result8 = null;
-              if (reportMatchFailures) {
+              result3 = null;
+              if (reportFailures === 0) {
                 matchFailed("[0-9]");
               }
             }
-            if (result8 !== null) {
-              var result5 = [];
-              while (result8 !== null) {
-                result5.push(result8);
-                if (input.substr(pos).match(/^[0-9]/) !== null) {
-                  var result8 = input.charAt(pos);
+            if (result3 !== null) {
+              result2 = [];
+              while (result3 !== null) {
+                result2.push(result3);
+                if (/^[0-9]/.test(input.charAt(pos))) {
+                  result3 = input.charAt(pos);
                   pos++;
                 } else {
-                  var result8 = null;
-                  if (reportMatchFailures) {
+                  result3 = null;
+                  if (reportFailures === 0) {
                     matchFailed("[0-9]");
                   }
                 }
               }
             } else {
-              var result5 = null;
+              result2 = null;
             }
-            if (result5 !== null) {
-              var result7 = parse_floatEe();
-              var result6 = result7 !== null ? result7 : '';
-              if (result6 !== null) {
-                var result1 = [result3, result4, result5, result6];
+            if (result2 !== null) {
+              result3 = parse_floatEe();
+              result3 = result3 !== null ? result3 : "";
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(num, dec, fee) { return num.join("") + "." + dec.join("") + fee; })(result1[0], result1[2], result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, num, dec, fee) { return num.join("") + "." + dec.join("") + fee; })(pos0, result0[0], result0[2], result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_float() {
-        var cacheKey = 'float@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === "-") {
-          var result9 = "-";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 45) {
+          result0 = "-";
+          pos++;
         } else {
-          var result9 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"-\"");
           }
         }
-        var result3 = result9 !== null ? result9 : '';
-        if (result3 !== null) {
-          var result8 = parse_leadFloat();
-          if (result8 !== null) {
-            var result4 = result8;
-          } else {
-            var result7 = parse_dotFloat();
-            if (result7 !== null) {
-              var result4 = result7;
-            } else {
-              var result6 = parse_expFloat();
-              if (result6 !== null) {
-                var result4 = result6;
-              } else {
+        result0 = result0 !== null ? result0 : "";
+        if (result0 !== null) {
+          result1 = parse_leadFloat();
+          if (result1 === null) {
+            result1 = parse_dotFloat();
+            if (result1 === null) {
+              result1 = parse_expFloat();
+              if (result1 === null) {
                 if (input.substr(pos, 8) === "Infinity") {
-                  var result5 = "Infinity";
+                  result1 = "Infinity";
                   pos += 8;
                 } else {
-                  var result5 = null;
-                  if (reportMatchFailures) {
+                  result1 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"Infinity\"");
                   }
                 }
-                if (result5 !== null) {
-                  var result4 = result5;
-                } else {
-                  var result4 = null;;
-                };
-              };
-            };
+              }
+            }
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(neg, num) { return neg + num; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, neg, num) { return neg + num; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_string() {
-        var cacheKey = 'string@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === "\"") {
-          var result3 = "\"";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 34) {
+          result0 = "\"";
+          pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"\\\"\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = [];
-          if (input.substr(pos).match(/^[^""]/) !== null) {
-            var result6 = input.charAt(pos);
+        if (result0 !== null) {
+          result1 = [];
+          if (/^[^""]/.test(input.charAt(pos))) {
+            result2 = input.charAt(pos);
             pos++;
           } else {
-            var result6 = null;
-            if (reportMatchFailures) {
+            result2 = null;
+            if (reportFailures === 0) {
               matchFailed("[^\"\"]");
             }
           }
-          while (result6 !== null) {
-            result4.push(result6);
-            if (input.substr(pos).match(/^[^""]/) !== null) {
-              var result6 = input.charAt(pos);
+          while (result2 !== null) {
+            result1.push(result2);
+            if (/^[^""]/.test(input.charAt(pos))) {
+              result2 = input.charAt(pos);
               pos++;
             } else {
-              var result6 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("[^\"\"]");
               }
             }
           }
-          if (result4 !== null) {
-            if (input.substr(pos, 1) === "\"") {
-              var result5 = "\"";
-              pos += 1;
+          if (result1 !== null) {
+            if (input.charCodeAt(pos) === 34) {
+              result2 = "\"";
+              pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"\\\"\"");
               }
             }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(str) { return str.join(""); })(result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, str) { return str.join(""); })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_other() {
-        var cacheKey = 'other@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1;
+        var pos0;
         
-        
-        var savedPos0 = pos;
-        if (input.substr(pos).match(/^[^	\n\r 0-9A-Z_a-z]/) !== null) {
-          var result3 = input.charAt(pos);
+        pos0 = pos;
+        if (/^[^\t\n\r 0-9A-Z_a-z]/.test(input.charAt(pos))) {
+          result1 = input.charAt(pos);
           pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
-            matchFailed("[^	\\n\\r 0-9A-Z_a-z]");
+          result1 = null;
+          if (reportFailures === 0) {
+            matchFailed("[^\\t\\n\\r 0-9A-Z_a-z]");
           }
         }
-        if (result3 !== null) {
-          var result1 = [];
-          while (result3 !== null) {
-            result1.push(result3);
-            if (input.substr(pos).match(/^[^	\n\r 0-9A-Z_a-z]/) !== null) {
-              var result3 = input.charAt(pos);
+        if (result1 !== null) {
+          result0 = [];
+          while (result1 !== null) {
+            result0.push(result1);
+            if (/^[^\t\n\r 0-9A-Z_a-z]/.test(input.charAt(pos))) {
+              result1 = input.charAt(pos);
               pos++;
             } else {
-              var result3 = null;
-              if (reportMatchFailures) {
-                matchFailed("[^	\\n\\r 0-9A-Z_a-z]");
+              result1 = null;
+              if (reportFailures === 0) {
+                matchFailed("[^\\t\\n\\r 0-9A-Z_a-z]");
               }
             }
           }
         } else {
-          var result1 = null;
-        }
-        var result2 = result1 !== null
-          ? (function(other) { return other.join(""); })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, other) { return other.join(""); })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_type() {
-        var cacheKey = 'type@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_TypeDesc();
-        if (result3 !== null) {
-          var result4 = parse_Nullable();
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_TypeDesc();
+        if (result0 !== null) {
+          result1 = parse_Nullable();
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(type, nullable) {
-                      if (!type.sequence) type.sequence = false;
-                      type.nullable = nullable;
-                      return type; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, type, nullable) {
+                    if (!type.sequence) type.sequence = false;
+                    type.nullable = nullable;
+                    return type; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_TypeDesc() {
-        var cacheKey = 'TypeDesc@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result6 = parse_Sequence();
-        if (result6 !== null) {
-          var result1 = result6;
-        } else {
-          var result5 = parse_ArrayType();
-          if (result5 !== null) {
-            var result1 = result5;
-          } else {
-            var result4 = parse_SimpleType();
-            if (result4 !== null) {
-              var result1 = result4;
-            } else {
-              var result3 = parse_UnionType();
-              if (result3 !== null) {
-                var result1 = result3;
-              } else {
-                var result1 = null;;
-              };
-            };
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(type) { return type; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_Sequence();
+        if (result0 === null) {
+          result0 = parse_ArrayType();
+          if (result0 === null) {
+            result0 = parse_SimpleType();
+            if (result0 === null) {
+              result0 = parse_UnionType();
+            }
+          }
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, type) { return type; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Sequence() {
-        var cacheKey = 'Sequence@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 9) === "sequence<") {
-          var result3 = "sequence<";
+          result0 = "sequence<";
           pos += 9;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"sequence<\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_type();
-          if (result4 !== null) {
-            if (input.substr(pos, 1) === ">") {
-              var result5 = ">";
-              pos += 1;
+        if (result0 !== null) {
+          result1 = parse_type();
+          if (result1 !== null) {
+            if (input.charCodeAt(pos) === 62) {
+              result2 = ">";
+              pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\">\"");
               }
             }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(type) { return { sequence: true, array: false, idlType: type, members: [] }; })(result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, type) { return { sequence: true, array: false, idlType: type, members: [] }; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ArrayType() {
-        var cacheKey = 'ArrayType@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_SimpleType();
-        if (result3 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_SimpleType();
+        if (result0 !== null) {
           if (input.substr(pos, 2) === "[]") {
-            var result4 = "[]";
+            result1 = "[]";
             pos += 2;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\"[]\"");
             }
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(type) {
-                      type.array = true;
-                      return type;
-                  })(result1[0])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, type) {
+                    type.array = true;
+                    return type;
+                })(pos0, result0[0]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_UnionType() {
-        var cacheKey = 'UnionType@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === "(") {
-          var result3 = "(";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 40) {
+          result0 = "(";
+          pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"(\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            var result5 = parse_TypeList();
-            if (result5 !== null) {
-              var result6 = parse_w();
-              if (result6 !== null) {
-                if (input.substr(pos, 1) === ")") {
-                  var result7 = ")";
-                  pos += 1;
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            result2 = parse_TypeList();
+            if (result2 !== null) {
+              result3 = parse_w();
+              if (result3 !== null) {
+                if (input.charCodeAt(pos) === 41) {
+                  result4 = ")";
+                  pos++;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\")\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result1 = [result3, result4, result5, result6, result7];
+                if (result4 !== null) {
+                  result0 = [result0, result1, result2, result3, result4];
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(members) { return { idlType: "union", members: members, sequence: false, array: false }; })(result1[2])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, members) { return { idlType: "union", members: members, sequence: false, array: false }; })(pos0, result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_TypeList() {
-        var cacheKey = 'TypeList@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_type();
-        if (result3 !== null) {
-          var result4 = parse_s();
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_type();
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
             if (input.substr(pos, 2) === "or") {
-              var result5 = "or";
+              result2 = "or";
               pos += 2;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"or\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_type();
-                if (result7 !== null) {
-                  var result8 = [];
-                  var result9 = parse_TypeListRest();
-                  while (result9 !== null) {
-                    result8.push(result9);
-                    var result9 = parse_TypeListRest();
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_type();
+                if (result4 !== null) {
+                  result5 = [];
+                  result6 = parse_TypeListRest();
+                  while (result6 !== null) {
+                    result5.push(result6);
+                    result6 = parse_TypeListRest();
                   }
-                  if (result8 !== null) {
-                    var result1 = [result3, result4, result5, result6, result7, result8];
+                  if (result5 !== null) {
+                    result0 = [result0, result1, result2, result3, result4, result5];
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(first, second, others) {   var ret = [first, second];
-                      for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
-                      return ret; })(result1[0], result1[4], result1[5])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, first, second, others) {   var ret = [first, second];
+                    for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
+                    return ret; })(pos0, result0[0], result0[4], result0[5]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_TypeListRest() {
-        var cacheKey = 'TypeListRest@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_s();
-        if (result3 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_s();
+        if (result0 !== null) {
           if (input.substr(pos, 2) === "or") {
-            var result4 = "or";
+            result1 = "or";
             pos += 2;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\"or\"");
             }
           }
-          if (result4 !== null) {
-            var result5 = parse_s();
-            if (result5 !== null) {
-              var result6 = parse_type();
-              if (result6 !== null) {
-                var result1 = [result3, result4, result5, result6];
+          if (result1 !== null) {
+            result2 = parse_s();
+            if (result2 !== null) {
+              result3 = parse_type();
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(rest) { return rest; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, rest) { return rest; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_SimpleType() {
-        var cacheKey = 'SimpleType@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result6 = parse_PrimitiveType();
-        if (result6 !== null) {
-          var result1 = result6;
-        } else {
-          var result5 = parse_UnsignedIntegerType();
-          if (result5 !== null) {
-            var result1 = result5;
-          } else {
-            var result4 = parse_FloatType();
-            if (result4 !== null) {
-              var result1 = result4;
-            } else {
-              var result3 = parse_ScopedName();
-              if (result3 !== null) {
-                var result1 = result3;
-              } else {
-                var result1 = null;;
-              };
-            };
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(type) { return { sequence: false, array: false, idlType: type, members: [] }; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_PrimitiveType();
+        if (result0 === null) {
+          result0 = parse_UnsignedIntegerType();
+          if (result0 === null) {
+            result0 = parse_FloatType();
+            if (result0 === null) {
+              result0 = parse_ScopedName();
+            }
+          }
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, type) { return { sequence: false, array: false, idlType: type, members: [] }; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_PrimitiveType() {
-        var cacheKey = 'PrimitiveType@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1;
+        var pos0, pos1, pos2;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 3) === "any") {
-          var result10 = "any";
+          result0 = "any";
           pos += 3;
         } else {
-          var result10 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"any\"");
           }
         }
-        if (result10 !== null) {
-          var result3 = result10;
-        } else {
+        if (result0 === null) {
           if (input.substr(pos, 6) === "object") {
-            var result9 = "object";
+            result0 = "object";
             pos += 6;
           } else {
-            var result9 = null;
-            if (reportMatchFailures) {
+            result0 = null;
+            if (reportFailures === 0) {
               matchFailed("\"object\"");
             }
           }
-          if (result9 !== null) {
-            var result3 = result9;
-          } else {
+          if (result0 === null) {
             if (input.substr(pos, 7) === "boolean") {
-              var result8 = "boolean";
+              result0 = "boolean";
               pos += 7;
             } else {
-              var result8 = null;
-              if (reportMatchFailures) {
+              result0 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"boolean\"");
               }
             }
-            if (result8 !== null) {
-              var result3 = result8;
-            } else {
+            if (result0 === null) {
               if (input.substr(pos, 5) === "octet") {
-                var result7 = "octet";
+                result0 = "octet";
                 pos += 5;
               } else {
-                var result7 = null;
-                if (reportMatchFailures) {
+                result0 = null;
+                if (reportFailures === 0) {
                   matchFailed("\"octet\"");
                 }
               }
-              if (result7 !== null) {
-                var result3 = result7;
-              } else {
+              if (result0 === null) {
                 if (input.substr(pos, 9) === "DOMString") {
-                  var result6 = "DOMString";
+                  result0 = "DOMString";
                   pos += 9;
                 } else {
-                  var result6 = null;
-                  if (reportMatchFailures) {
+                  result0 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"DOMString\"");
                   }
                 }
-                if (result6 !== null) {
-                  var result3 = result6;
-                } else {
-                  var result3 = null;;
-                };
-              };
-            };
-          };
-        }
-        if (result3 !== null) {
-          var savedPos2 = pos;
-          var savedReportMatchFailuresVar0 = reportMatchFailures;
-          reportMatchFailures = false;
-          if (input.substr(pos).match(/^[A-Za-z0-9]/) !== null) {
-            var result5 = input.charAt(pos);
+              }
+            }
+          }
+        }
+        if (result0 !== null) {
+          pos2 = pos;
+          reportFailures++;
+          if (/^[A-Za-z0-9]/.test(input.charAt(pos))) {
+            result1 = input.charAt(pos);
             pos++;
           } else {
-            var result5 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("[A-Za-z0-9]");
             }
           }
-          reportMatchFailures = savedReportMatchFailuresVar0;
-          if (result5 === null) {
-            var result4 = '';
+          reportFailures--;
+          if (result1 === null) {
+            result1 = "";
           } else {
-            var result4 = null;
-            pos = savedPos2;
+            result1 = null;
+            pos = pos2;
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(type) { return type; })(result1[0])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, type) { return type; })(pos0, result0[0]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_FloatType() {
-        var cacheKey = 'FloatType@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 12) === "unrestricted") {
-          var result8 = "unrestricted";
+          result0 = "unrestricted";
           pos += 12;
         } else {
-          var result8 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"unrestricted\"");
           }
         }
-        var result3 = result8 !== null ? result8 : '';
-        if (result3 !== null) {
-          var result4 = parse_s();
-          if (result4 !== null) {
+        result0 = result0 !== null ? result0 : "";
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
             if (input.substr(pos, 5) === "float") {
-              var result7 = "float";
+              result2 = "float";
               pos += 5;
             } else {
-              var result7 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"float\"");
               }
             }
-            if (result7 !== null) {
-              var result5 = result7;
-            } else {
+            if (result2 === null) {
               if (input.substr(pos, 6) === "double") {
-                var result6 = "double";
+                result2 = "double";
                 pos += 6;
               } else {
-                var result6 = null;
-                if (reportMatchFailures) {
+                result2 = null;
+                if (reportFailures === 0) {
                   matchFailed("\"double\"");
                 }
               }
-              if (result6 !== null) {
-                var result5 = result6;
-              } else {
-                var result5 = null;;
-              };
             }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(unr, kind) { return (unr ? "unrestricted " : "") + (kind); })(result1[0], result1[2])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, unr, kind) { return (unr ? "unrestricted " : "") + (kind); })(pos0, result0[0], result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_UnsignedIntegerType() {
-        var cacheKey = 'UnsignedIntegerType@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3, result4;
+        var pos0, pos1, pos2;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 8) === "unsigned") {
-          var result13 = "unsigned";
+          result0 = "unsigned";
           pos += 8;
         } else {
-          var result13 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"unsigned\"");
           }
         }
-        var result3 = result13 !== null ? result13 : '';
-        if (result3 !== null) {
-          var result4 = parse_s();
-          if (result4 !== null) {
-            var savedPos2 = pos;
+        result0 = result0 !== null ? result0 : "";
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
+            pos2 = pos;
             if (input.substr(pos, 4) === "long") {
-              var result10 = "long";
+              result2 = "long";
               pos += 4;
             } else {
-              var result10 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"long\"");
               }
             }
-            if (result10 !== null) {
-              var result11 = parse_s();
-              if (result11 !== null) {
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
                 if (input.substr(pos, 4) === "long") {
-                  var result12 = "long";
+                  result4 = "long";
                   pos += 4;
                 } else {
-                  var result12 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"long\"");
                   }
                 }
-                if (result12 !== null) {
-                  var result9 = [result10, result11, result12];
+                if (result4 !== null) {
+                  result2 = [result2, result3, result4];
                 } else {
-                  var result9 = null;
-                  pos = savedPos2;
+                  result2 = null;
+                  pos = pos2;
                 }
               } else {
-                var result9 = null;
-                pos = savedPos2;
+                result2 = null;
+                pos = pos2;
               }
             } else {
-              var result9 = null;
-              pos = savedPos2;
+              result2 = null;
+              pos = pos2;
             }
-            if (result9 !== null) {
-              var result5 = result9;
-            } else {
+            if (result2 === null) {
               if (input.substr(pos, 4) === "long") {
-                var result8 = "long";
+                result2 = "long";
                 pos += 4;
               } else {
-                var result8 = null;
-                if (reportMatchFailures) {
+                result2 = null;
+                if (reportFailures === 0) {
                   matchFailed("\"long\"");
                 }
               }
-              if (result8 !== null) {
-                var result5 = result8;
-              } else {
+              if (result2 === null) {
                 if (input.substr(pos, 5) === "short") {
-                  var result7 = "short";
+                  result2 = "short";
                   pos += 5;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result2 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"short\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result5 = result7;
-                } else {
+                if (result2 === null) {
                   if (input.substr(pos, 4) === "byte") {
-                    var result6 = "byte";
+                    result2 = "byte";
                     pos += 4;
                   } else {
-                    var result6 = null;
-                    if (reportMatchFailures) {
+                    result2 = null;
+                    if (reportFailures === 0) {
                       matchFailed("\"byte\"");
                     }
                   }
-                  if (result6 !== null) {
-                    var result5 = result6;
-                  } else {
-                    var result5 = null;;
-                  };
-                };
-              };
+                }
+              }
             }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(uns, kind) { return (uns ? "unsigned " : "") + (kind.join ? kind.join("") : kind); })(result1[0], result1[2])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, uns, kind) { return (uns ? "unsigned " : "") + (kind.join ? kind.join("") : kind); })(pos0, result0[0], result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ScopedNameList() {
-        var cacheKey = 'ScopedNameList@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_ScopedName();
-        if (result3 !== null) {
-          var result4 = [];
-          var result5 = parse_ScopedNameListRest();
-          while (result5 !== null) {
-            result4.push(result5);
-            var result5 = parse_ScopedNameListRest();
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ScopedName();
+        if (result0 !== null) {
+          result1 = [];
+          result2 = parse_ScopedNameListRest();
+          while (result2 !== null) {
+            result1.push(result2);
+            result2 = parse_ScopedNameListRest();
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(first, others) {   var ret = [first];
-                      for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
-                      return ret; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, first, others) {   var ret = [first];
+                    for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
+                    return ret; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ScopedNameListRest() {
-        var cacheKey = 'ScopedNameListRest@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
-          if (input.substr(pos, 1) === ",") {
-            var result4 = ",";
-            pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 44) {
+            result1 = ",";
+            pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\",\"");
             }
           }
-          if (result4 !== null) {
-            var result5 = parse_w();
-            if (result5 !== null) {
-              var result6 = parse_ScopedName();
-              if (result6 !== null) {
-                var result1 = [result3, result4, result5, result6];
+          if (result1 !== null) {
+            result2 = parse_w();
+            if (result2 !== null) {
+              result3 = parse_ScopedName();
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(rest) { return rest; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, rest) { return rest; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ScopedName() {
-        var cacheKey = 'ScopedName@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result4 = parse_AbsoluteScopedName();
-        if (result4 !== null) {
-          var result1 = result4;
-        } else {
-          var result3 = parse_RelativeScopedName();
-          if (result3 !== null) {
-            var result1 = result3;
-          } else {
-            var result1 = null;;
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(name) { return name; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_AbsoluteScopedName();
+        if (result0 === null) {
+          result0 = parse_RelativeScopedName();
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, name) { return name; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_AbsoluteScopedName() {
-        var cacheKey = 'AbsoluteScopedName@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 2) === "::") {
-          var result3 = "::";
+          result0 = "::";
           pos += 2;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"::\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_RelativeScopedName();
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+        if (result0 !== null) {
+          result1 = parse_RelativeScopedName();
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(rel) { return "::" + rel; })(result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, rel) { return "::" + rel; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_RelativeScopedName() {
-        var cacheKey = 'RelativeScopedName@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_identifier();
-        if (result3 !== null) {
-          var result4 = [];
-          var result5 = parse_ScopedNameRest();
-          while (result5 !== null) {
-            result4.push(result5);
-            var result5 = parse_ScopedNameRest();
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_identifier();
+        if (result0 !== null) {
+          result1 = [];
+          result2 = parse_ScopedNameRest();
+          while (result2 !== null) {
+            result1.push(result2);
+            result2 = parse_ScopedNameRest();
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(name, rest) { return name + rest.join(""); })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, name, rest) { return name + rest.join(""); })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ScopedNameRest() {
-        var cacheKey = 'ScopedNameRest@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 2) === "::") {
-          var result3 = "::";
+          result0 = "::";
           pos += 2;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"::\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_identifier();
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+        if (result0 !== null) {
+          result1 = parse_identifier();
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(name) { return name.join(""); })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, name) { return name.join(""); })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_BooleanLiteral() {
-        var cacheKey = 'BooleanLiteral@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0;
+        var pos0;
         
-        
-        var savedPos0 = pos;
+        pos0 = pos;
         if (input.substr(pos, 4) === "true") {
-          var result4 = "true";
+          result0 = "true";
           pos += 4;
         } else {
-          var result4 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"true\"");
           }
         }
-        if (result4 !== null) {
-          var result1 = result4;
-        } else {
+        if (result0 === null) {
           if (input.substr(pos, 5) === "false") {
-            var result3 = "false";
+            result0 = "false";
             pos += 5;
           } else {
-            var result3 = null;
-            if (reportMatchFailures) {
+            result0 = null;
+            if (reportFailures === 0) {
               matchFailed("\"false\"");
             }
           }
-          if (result3 !== null) {
-            var result1 = result3;
-          } else {
-            var result1 = null;;
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(value) { return value; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, value) { return value; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Nullable() {
-        var cacheKey = 'Nullable@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        if (input.substr(pos, 1) === "?") {
-          var result3 = "?";
-          pos += 1;
+        pos0 = pos;
+        if (input.charCodeAt(pos) === 63) {
+          result0 = "?";
+          pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"?\"");
           }
         }
-        var result1 = result3 !== null ? result3 : '';
-        var result2 = result1 !== null
-          ? (function(nullable) { return nullable ? true : false; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        result0 = result0 !== null ? result0 : "";
+        if (result0 !== null) {
+          result0 = (function(offset, nullable) { return nullable ? true : false; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ReturnType() {
-        var cacheKey = 'ReturnType@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0;
+        var pos0;
         
-        
-        var savedPos0 = pos;
+        pos0 = pos;
         if (input.substr(pos, 4) === "void") {
-          var result4 = "void";
+          result0 = "void";
           pos += 4;
         } else {
-          var result4 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"void\"");
           }
         }
-        if (result4 !== null) {
-          var result1 = result4;
-        } else {
-          var result3 = parse_type();
-          if (result3 !== null) {
-            var result1 = result3;
-          } else {
-            var result1 = null;;
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(ret) { return ret; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        if (result0 === null) {
+          result0 = parse_type();
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, ret) { return ret; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_definitions() {
-        var cacheKey = 'definitions@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
-          var result4 = [];
-          var result5 = parse_definition();
-          while (result5 !== null) {
-            result4.push(result5);
-            var result5 = parse_definition();
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
+          result1 = [];
+          result2 = parse_definition();
+          while (result2 !== null) {
+            result1.push(result2);
+            result2 = parse_definition();
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(defs) { return defs; })(result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, defs) { return defs; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_definition() {
-        var cacheKey = 'definition@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result12 = parse_partialinterface();
-        if (result12 !== null) {
-          var result1 = result12;
-        } else {
-          var result11 = parse_callbackinterface();
-          if (result11 !== null) {
-            var result1 = result11;
-          } else {
-            var result10 = parse_module();
-            if (result10 !== null) {
-              var result1 = result10;
-            } else {
-              var result9 = parse_interface();
-              if (result9 !== null) {
-                var result1 = result9;
-              } else {
-                var result8 = parse_dictionary();
-                if (result8 !== null) {
-                  var result1 = result8;
-                } else {
-                  var result7 = parse_typedef();
-                  if (result7 !== null) {
-                    var result1 = result7;
-                  } else {
-                    var result6 = parse_exception();
-                    if (result6 !== null) {
-                      var result1 = result6;
-                    } else {
-                      var result5 = parse_implements();
-                      if (result5 !== null) {
-                        var result1 = result5;
-                      } else {
-                        var result4 = parse_enum();
-                        if (result4 !== null) {
-                          var result1 = result4;
-                        } else {
-                          var result3 = parse_callback();
-                          if (result3 !== null) {
-                            var result1 = result3;
-                          } else {
-                            var result1 = null;;
-                          };
-                        };
-                      };
-                    };
-                  };
-                };
-              };
-            };
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(def) { return def; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_partialdictionary();
+        if (result0 === null) {
+          result0 = parse_partialinterface();
+          if (result0 === null) {
+            result0 = parse_callbackinterface();
+            if (result0 === null) {
+              result0 = parse_module();
+              if (result0 === null) {
+                result0 = parse_interface();
+                if (result0 === null) {
+                  result0 = parse_dictionary();
+                  if (result0 === null) {
+                    result0 = parse_typedef();
+                    if (result0 === null) {
+                      result0 = parse_exception();
+                      if (result0 === null) {
+                        result0 = parse_implements();
+                        if (result0 === null) {
+                          result0 = parse_enum();
+                          if (result0 === null) {
+                            result0 = parse_callback();
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, def) { return def; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_partialinterface() {
-        var cacheKey = 'partialinterface@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result21 = parse_extendedAttributeList();
-        var result3 = result21 !== null ? result21 : '';
-        if (result3 !== null) {
-          var result20 = parse_s();
-          var result4 = result20 !== null ? result20 : '';
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
             if (input.substr(pos, 7) === "partial") {
-              var result5 = "partial";
+              result2 = "partial";
               pos += 7;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"partial\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
                 if (input.substr(pos, 9) === "interface") {
-                  var result7 = "interface";
+                  result4 = "interface";
                   pos += 9;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"interface\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result8 = parse_s();
-                  if (result8 !== null) {
-                    var result9 = parse_identifier();
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        if (input.substr(pos, 1) === "{") {
-                          var result11 = "{";
-                          pos += 1;
+                if (result4 !== null) {
+                  result5 = parse_s();
+                  if (result5 !== null) {
+                    result6 = parse_identifier();
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 123) {
+                          result8 = "{";
+                          pos++;
                         } else {
-                          var result11 = null;
-                          if (reportMatchFailures) {
+                          result8 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\"{\"");
                           }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            var result13 = [];
-                            var result19 = parse_ifMember();
-                            while (result19 !== null) {
-                              result13.push(result19);
-                              var result19 = parse_ifMember();
-                            }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === "}") {
-                                  var result15 = "}";
-                                  pos += 1;
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result10 = parse_InterfaceMemberList();
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 125) {
+                                  result12 = "}";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
                                     matchFailed("\"}\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    if (input.substr(pos, 1) === ";") {
-                                      var result17 = ";";
-                                      pos += 1;
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    if (input.charCodeAt(pos) === 59) {
+                                      result14 = ";";
+                                      pos++;
                                     } else {
-                                      var result17 = null;
-                                      if (reportMatchFailures) {
+                                      result14 = null;
+                                      if (reportFailures === 0) {
                                         matchFailed("\";\"");
                                       }
                                     }
-                                    if (result17 !== null) {
-                                      var result18 = parse_w();
-                                      if (result18 !== null) {
-                                        var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16, result17, result18];
+                                    if (result14 !== null) {
+                                      result15 = parse_w();
+                                      if (result15 !== null) {
+                                        result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15];
                                       } else {
-                                        var result1 = null;
-                                        pos = savedPos1;
+                                        result0 = null;
+                                        pos = pos1;
                                       }
                                     } else {
-                                      var result1 = null;
-                                      pos = savedPos1;
+                                      result0 = null;
+                                      pos = pos1;
                                     }
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, name, mem) { return { type: "partialinterface", name: name, members: mem, extAttrs: extAttrs }; })(result1[0], result1[6], result1[10])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, name, mem) { return { type: "partialinterface", name: name, members: mem, extAttrs: extAttrs }; })(pos0, result0[0], result0[6], result0[10]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_partialdictionary() {
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13;
+        var pos0, pos1;
+        
+        pos0 = pos;
+        pos1 = pos;
+        if (input.substr(pos, 7) === "partial") {
+          result0 = "partial";
+          pos += 7;
         } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          if (reportFailures === 0) {
+            matchFailed("\"partial\"");
+          }
+        }
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
+            if (input.substr(pos, 10) === "dictionary") {
+              result2 = "dictionary";
+              pos += 10;
+            } else {
+              result2 = null;
+              if (reportFailures === 0) {
+                matchFailed("\"dictionary\"");
+              }
+            }
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 123) {
+                      result6 = "{";
+                      pos++;
+                    } else {
+                      result6 = null;
+                      if (reportFailures === 0) {
+                        matchFailed("\"{\"");
+                      }
+                    }
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        result8 = parse_DictionaryMemberList();
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            if (input.charCodeAt(pos) === 125) {
+                              result10 = "}";
+                              pos++;
+                            } else {
+                              result10 = null;
+                              if (reportFailures === 0) {
+                                matchFailed("\"}\"");
+                              }
+                            }
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 59) {
+                                  result12 = ";";
+                                  pos++;
+                                } else {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
+                                    matchFailed("\";\"");
+                                  }
+                                }
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13];
+                                  } else {
+                                    result0 = null;
+                                    pos = pos1;
+                                  }
+                                } else {
+                                  result0 = null;
+                                  pos = pos1;
+                                }
+                              } else {
+                                result0 = null;
+                                pos = pos1;
+                              }
+                            } else {
+                              result0 = null;
+                              pos = pos1;
+                            }
+                          } else {
+                            result0 = null;
+                            pos = pos1;
+                          }
+                        } else {
+                          result0 = null;
+                          pos = pos1;
+                        }
+                      } else {
+                        result0 = null;
+                        pos = pos1;
+                      }
+                    } else {
+                      result0 = null;
+                      pos = pos1;
+                    }
+                  } else {
+                    result0 = null;
+                    pos = pos1;
+                  }
+                } else {
+                  result0 = null;
+                  pos = pos1;
+                }
+              } else {
+                result0 = null;
+                pos = pos1;
+              }
+            } else {
+              result0 = null;
+              pos = pos1;
+            }
+          } else {
+            result0 = null;
+            pos = pos1;
+          }
+        } else {
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, name, members) {
+                    return {
+                        type: "partialdictionary",
+                        name: name,
+                        members: members
+                    };
+                })(pos0, result0[4], result0[8]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_callbackinterface() {
-        var cacheKey = 'callbackinterface@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result21 = parse_extendedAttributeList();
-        var result3 = result21 !== null ? result21 : '';
-        if (result3 !== null) {
-          var result20 = parse_s();
-          var result4 = result20 !== null ? result20 : '';
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
             if (input.substr(pos, 8) === "callback") {
-              var result5 = "callback";
+              result2 = "callback";
               pos += 8;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"callback\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
                 if (input.substr(pos, 9) === "interface") {
-                  var result7 = "interface";
+                  result4 = "interface";
                   pos += 9;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"interface\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result8 = parse_s();
-                  if (result8 !== null) {
-                    var result9 = parse_identifier();
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        if (input.substr(pos, 1) === "{") {
-                          var result11 = "{";
-                          pos += 1;
+                if (result4 !== null) {
+                  result5 = parse_s();
+                  if (result5 !== null) {
+                    result6 = parse_identifier();
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 123) {
+                          result8 = "{";
+                          pos++;
                         } else {
-                          var result11 = null;
-                          if (reportMatchFailures) {
+                          result8 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\"{\"");
                           }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            var result13 = [];
-                            var result19 = parse_ifMember();
-                            while (result19 !== null) {
-                              result13.push(result19);
-                              var result19 = parse_ifMember();
-                            }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === "}") {
-                                  var result15 = "}";
-                                  pos += 1;
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result10 = parse_InterfaceMemberList();
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 125) {
+                                  result12 = "}";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
                                     matchFailed("\"}\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    if (input.substr(pos, 1) === ";") {
-                                      var result17 = ";";
-                                      pos += 1;
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    if (input.charCodeAt(pos) === 59) {
+                                      result14 = ";";
+                                      pos++;
                                     } else {
-                                      var result17 = null;
-                                      if (reportMatchFailures) {
+                                      result14 = null;
+                                      if (reportFailures === 0) {
                                         matchFailed("\";\"");
                                       }
                                     }
-                                    if (result17 !== null) {
-                                      var result18 = parse_w();
-                                      if (result18 !== null) {
-                                        var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16, result17, result18];
+                                    if (result14 !== null) {
+                                      result15 = parse_w();
+                                      if (result15 !== null) {
+                                        result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15];
                                       } else {
-                                        var result1 = null;
-                                        pos = savedPos1;
+                                        result0 = null;
+                                        pos = pos1;
                                       }
                                     } else {
-                                      var result1 = null;
-                                      pos = savedPos1;
+                                      result0 = null;
+                                      pos = pos1;
                                     }
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, name, mem) { return { type: "callbackinterface", name: name, members: mem, extAttrs: extAttrs }; })(result1[0], result1[6], result1[10])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, name, mem) { return { type: "callbackinterface", name: name, members: mem, extAttrs: extAttrs }; })(pos0, result0[0], result0[6], result0[10]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_module() {
-        var cacheKey = 'module@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result18 = parse_extendedAttributeList();
-        var result3 = result18 !== null ? result18 : '';
-        if (result3 !== null) {
-          var result17 = parse_s();
-          var result4 = result17 !== null ? result17 : '';
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
             if (input.substr(pos, 6) === "module") {
-              var result5 = "module";
+              result2 = "module";
               pos += 6;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"module\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === "{") {
-                      var result9 = "{";
-                      pos += 1;
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 123) {
+                      result6 = "{";
+                      pos++;
                     } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
+                      result6 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\"{\"");
                       }
                     }
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        var result11 = parse_definitions();
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            if (input.substr(pos, 1) === "}") {
-                              var result13 = "}";
-                              pos += 1;
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        result8 = parse_definitions();
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            if (input.charCodeAt(pos) === 125) {
+                              result10 = "}";
+                              pos++;
                             } else {
-                              var result13 = null;
-                              if (reportMatchFailures) {
+                              result10 = null;
+                              if (reportFailures === 0) {
                                 matchFailed("\"}\"");
                               }
                             }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === ";") {
-                                  var result15 = ";";
-                                  pos += 1;
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 59) {
+                                  result12 = ";";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
                                     matchFailed("\";\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16];
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13];
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, name, defs) { return { type: "module", name: name, definitions: defs, extAttrs: extAttrs }; })(result1[0], result1[4], result1[8])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, name, defs) { return { type: "module", name: name, definitions: defs, extAttrs: extAttrs }; })(pos0, result0[0], result0[4], result0[8]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_implements() {
-        var cacheKey = 'implements@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result14 = parse_extendedAttributeList();
-        var result3 = result14 !== null ? result14 : '';
-        if (result3 !== null) {
-          var result13 = parse_s();
-          var result4 = result13 !== null ? result13 : '';
-          if (result4 !== null) {
-            var result5 = parse_ScopedName();
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
+            result2 = parse_ScopedName();
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
                 if (input.substr(pos, 10) === "implements") {
-                  var result7 = "implements";
+                  result4 = "implements";
                   pos += 10;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"implements\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result8 = parse_s();
-                  if (result8 !== null) {
-                    var result9 = parse_ScopedName();
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        if (input.substr(pos, 1) === ";") {
-                          var result11 = ";";
-                          pos += 1;
+                if (result4 !== null) {
+                  result5 = parse_s();
+                  if (result5 !== null) {
+                    result6 = parse_ScopedName();
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 59) {
+                          result8 = ";";
+                          pos++;
                         } else {
-                          var result11 = null;
-                          if (reportMatchFailures) {
+                          result8 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\";\"");
                           }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12];
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9];
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, target, impl) { return { type: 'implements', target: target, 'implements': impl, extAttrs: extAttrs }; })(result1[0], result1[2], result1[6])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, target, impl) { return { type: 'implements', target: target, 'implements': impl, extAttrs: extAttrs }; })(pos0, result0[0], result0[2], result0[6]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_interface() {
-        var cacheKey = 'interface@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result22 = parse_extendedAttributeList();
-        var result3 = result22 !== null ? result22 : '';
-        if (result3 !== null) {
-          var result21 = parse_s();
-          var result4 = result21 !== null ? result21 : '';
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
             if (input.substr(pos, 9) === "interface") {
-              var result5 = "interface";
+              result2 = "interface";
               pos += 9;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"interface\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    var result20 = parse_ifInheritance();
-                    var result9 = result20 !== null ? result20 : '';
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        if (input.substr(pos, 1) === "{") {
-                          var result11 = "{";
-                          pos += 1;
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    result6 = parse_Inheritance();
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 123) {
+                          result8 = "{";
+                          pos++;
                         } else {
-                          var result11 = null;
-                          if (reportMatchFailures) {
+                          result8 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\"{\"");
                           }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            var result13 = [];
-                            var result19 = parse_ifMember();
-                            while (result19 !== null) {
-                              result13.push(result19);
-                              var result19 = parse_ifMember();
-                            }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === "}") {
-                                  var result15 = "}";
-                                  pos += 1;
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result10 = parse_InterfaceMemberList();
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 125) {
+                                  result12 = "}";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
                                     matchFailed("\"}\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    if (input.substr(pos, 1) === ";") {
-                                      var result17 = ";";
-                                      pos += 1;
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    if (input.charCodeAt(pos) === 59) {
+                                      result14 = ";";
+                                      pos++;
                                     } else {
-                                      var result17 = null;
-                                      if (reportMatchFailures) {
+                                      result14 = null;
+                                      if (reportFailures === 0) {
                                         matchFailed("\";\"");
                                       }
                                     }
-                                    if (result17 !== null) {
-                                      var result18 = parse_w();
-                                      if (result18 !== null) {
-                                        var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16, result17, result18];
+                                    if (result14 !== null) {
+                                      result15 = parse_w();
+                                      if (result15 !== null) {
+                                        result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15];
                                       } else {
-                                        var result1 = null;
-                                        pos = savedPos1;
+                                        result0 = null;
+                                        pos = pos1;
                                       }
                                     } else {
-                                      var result1 = null;
-                                      pos = savedPos1;
+                                      result0 = null;
+                                      pos = pos1;
                                     }
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, name, herit, mem) { return { type: "interface", name: name, inheritance: herit, members: mem, extAttrs: extAttrs }; })(result1[0], result1[4], result1[6], result1[10])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, name, herit, mem) { return { type: "interface", name: name, inheritance: herit, members: mem, extAttrs: extAttrs }; })(pos0, result0[0], result0[4], result0[6], result0[10]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_enum() {
-        var cacheKey = 'enum@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result18 = parse_extendedAttributeList();
-        var result3 = result18 !== null ? result18 : '';
-        if (result3 !== null) {
-          var result17 = parse_s();
-          var result4 = result17 !== null ? result17 : '';
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
             if (input.substr(pos, 4) === "enum") {
-              var result5 = "enum";
+              result2 = "enum";
               pos += 4;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"enum\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === "{") {
-                      var result9 = "{";
-                      pos += 1;
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 123) {
+                      result6 = "{";
+                      pos++;
                     } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
+                      result6 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\"{\"");
                       }
                     }
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        var result11 = parse_EnumValues();
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            if (input.substr(pos, 1) === "}") {
-                              var result13 = "}";
-                              pos += 1;
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        result8 = parse_EnumValues();
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          result9 = result9 !== null ? result9 : "";
+                          if (result9 !== null) {
+                            if (input.charCodeAt(pos) === 44) {
+                              result10 = ",";
+                              pos++;
                             } else {
-                              var result13 = null;
-                              if (reportMatchFailures) {
-                                matchFailed("\"}\"");
+                              result10 = null;
+                              if (reportFailures === 0) {
+                                matchFailed("\",\"");
                               }
                             }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === ";") {
-                                  var result15 = ";";
-                                  pos += 1;
+                            result10 = result10 !== null ? result10 : "";
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 125) {
+                                  result12 = "}";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
-                                    matchFailed("\";\"");
+                                  result12 = null;
+                                  if (reportFailures === 0) {
+                                    matchFailed("\"}\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16];
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    if (input.charCodeAt(pos) === 59) {
+                                      result14 = ";";
+                                      pos++;
+                                    } else {
+                                      result14 = null;
+                                      if (reportFailures === 0) {
+                                        matchFailed("\";\"");
+                                      }
+                                    }
+                                    if (result14 !== null) {
+                                      result15 = parse_w();
+                                      if (result15 !== null) {
+                                        result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15];
+                                      } else {
+                                        result0 = null;
+                                        pos = pos1;
+                                      }
+                                    } else {
+                                      result0 = null;
+                                      pos = pos1;
+                                    }
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, name, values) { return { type: "enum", name: name, values: values, extAttrs: extAttrs }; })(result1[0], result1[4], result1[8])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, name, values) { return { type: "enum", name: name, values: values, extAttrs: extAttrs }; })(pos0, result0[0], result0[4], result0[8]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_callback() {
-        var cacheKey = 'callback@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16, result17;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result22 = parse_extendedAttributeList();
-        var result3 = result22 !== null ? result22 : '';
-        if (result3 !== null) {
-          var result21 = parse_s();
-          var result4 = result21 !== null ? result21 : '';
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
             if (input.substr(pos, 8) === "callback") {
-              var result5 = "callback";
+              result2 = "callback";
               pos += 8;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"callback\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === "=") {
-                      var result9 = "=";
-                      pos += 1;
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 61) {
+                      result6 = "=";
+                      pos++;
                     } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
+                      result6 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\"=\"");
                       }
                     }
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        var result11 = parse_ReturnType();
-                        if (result11 !== null) {
-                          var result12 = parse_s();
-                          if (result12 !== null) {
-                            if (input.substr(pos, 1) === "(") {
-                              var result13 = "(";
-                              pos += 1;
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        result8 = parse_ReturnType();
+                        if (result8 !== null) {
+                          result9 = parse_s();
+                          if (result9 !== null) {
+                            if (input.charCodeAt(pos) === 40) {
+                              result10 = "(";
+                              pos++;
                             } else {
-                              var result13 = null;
-                              if (reportMatchFailures) {
+                              result10 = null;
+                              if (reportFailures === 0) {
                                 matchFailed("\"(\"");
                               }
                             }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                var result15 = parse_Arguments();
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    if (input.substr(pos, 1) === ")") {
-                                      var result17 = ")";
-                                      pos += 1;
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                result12 = parse_Arguments();
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    if (input.charCodeAt(pos) === 41) {
+                                      result14 = ")";
+                                      pos++;
                                     } else {
-                                      var result17 = null;
-                                      if (reportMatchFailures) {
+                                      result14 = null;
+                                      if (reportFailures === 0) {
                                         matchFailed("\")\"");
                                       }
                                     }
-                                    if (result17 !== null) {
-                                      var result18 = parse_w();
-                                      if (result18 !== null) {
-                                        if (input.substr(pos, 1) === ";") {
-                                          var result19 = ";";
-                                          pos += 1;
+                                    if (result14 !== null) {
+                                      result15 = parse_w();
+                                      if (result15 !== null) {
+                                        if (input.charCodeAt(pos) === 59) {
+                                          result16 = ";";
+                                          pos++;
                                         } else {
-                                          var result19 = null;
-                                          if (reportMatchFailures) {
+                                          result16 = null;
+                                          if (reportFailures === 0) {
                                             matchFailed("\";\"");
                                           }
                                         }
-                                        if (result19 !== null) {
-                                          var result20 = parse_w();
-                                          if (result20 !== null) {
-                                            var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16, result17, result18, result19, result20];
+                                        if (result16 !== null) {
+                                          result17 = parse_w();
+                                          if (result17 !== null) {
+                                            result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16, result17];
                                           } else {
-                                            var result1 = null;
-                                            pos = savedPos1;
+                                            result0 = null;
+                                            pos = pos1;
                                           }
                                         } else {
-                                          var result1 = null;
-                                          pos = savedPos1;
+                                          result0 = null;
+                                          pos = pos1;
                                         }
                                       } else {
-                                        var result1 = null;
-                                        pos = savedPos1;
+                                        result0 = null;
+                                        pos = pos1;
                                       }
                                     } else {
-                                      var result1 = null;
-                                      pos = savedPos1;
+                                      result0 = null;
+                                      pos = pos1;
                                     }
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, name, ret, args) { return { type: "callback", idlType: ret, name: name, args: args, extAttrs: extAttrs }; })(result1[0], result1[4], result1[8], result1[12])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, name, ret, args) { return { type: "callback", idlType: ret, name: name, args: args, extAttrs: extAttrs }; })(pos0, result0[0], result0[4], result0[8], result0[12]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_EnumValues() {
-        var cacheKey = 'EnumValues@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_string();
-        if (result3 !== null) {
-          var result4 = [];
-          var result5 = parse_EnumValuesRest();
-          while (result5 !== null) {
-            result4.push(result5);
-            var result5 = parse_EnumValuesRest();
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_string();
+        if (result0 !== null) {
+          result1 = [];
+          result2 = parse_EnumValuesRest();
+          while (result2 !== null) {
+            result1.push(result2);
+            result2 = parse_EnumValuesRest();
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(first, others) {   var ret = [first];
-                      for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
-                      return ret; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, first, others) {   var ret = [first];
+                    for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
+                    return ret; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_EnumValuesRest() {
-        var cacheKey = 'EnumValuesRest@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
-          if (input.substr(pos, 1) === ",") {
-            var result4 = ",";
-            pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 44) {
+            result1 = ",";
+            pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\",\"");
             }
           }
-          if (result4 !== null) {
-            var result5 = parse_w();
-            if (result5 !== null) {
-              var result6 = parse_string();
-              if (result6 !== null) {
-                var result1 = [result3, result4, result5, result6];
+          if (result1 !== null) {
+            result2 = parse_w();
+            if (result2 !== null) {
+              result3 = parse_string();
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(rest) { return rest; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, rest) { return rest; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_Inheritance() {
+        var result0;
+        var pos0;
         
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_InheritanceInner();
+        result0 = result0 !== null ? result0 : "";
+        if (result0 !== null) {
+          result0 = (function(offset, herit) { return herit ? herit : []; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
-      function parse_ifInheritance() {
-        var cacheKey = 'ifInheritance@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+      function parse_InheritanceInner() {
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === ":") {
-          var result3 = ":";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 58) {
+          result0 = ":";
+          pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\":\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            var result5 = parse_ScopedNameList();
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            result2 = parse_ScopedNameList();
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(herit) { return herit; })(result1[2])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, herit) { return herit; })(pos0, result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
-      function parse_ifMember() {
-        var cacheKey = 'ifMember@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+      function parse_InterfaceMemberList() {
+        var result0, result1;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result4 = parse_const();
-        if (result4 !== null) {
-          var result1 = result4;
-        } else {
-          var result3 = parse_attrOrOp();
-          if (result3 !== null) {
-            var result1 = result3;
-          } else {
-            var result1 = null;;
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(mem) { return mem; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
+        pos0 = pos;
+        result0 = [];
+        result1 = parse_InterfaceMember();
+        while (result1 !== null) {
+          result0.push(result1);
+          result1 = parse_InterfaceMember();
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, mem) { return mem ? mem : []; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_InterfaceMember() {
+        var result0;
+        var pos0;
         
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_const();
+        if (result0 === null) {
+          result0 = parse_attrOrOp();
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, mem) { return mem; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_const() {
-        var cacheKey = 'const@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result18 = parse_extendedAttributeList();
-        var result3 = result18 !== null ? result18 : '';
-        if (result3 !== null) {
-          var result17 = parse_s();
-          var result4 = result17 !== null ? result17 : '';
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
             if (input.substr(pos, 5) === "const") {
-              var result5 = "const";
+              result2 = "const";
               pos += 5;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"const\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_type();
-                if (result7 !== null) {
-                  var result8 = parse_s();
-                  if (result8 !== null) {
-                    var result9 = parse_identifier();
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        if (input.substr(pos, 1) === "=") {
-                          var result11 = "=";
-                          pos += 1;
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_type();
+                if (result4 !== null) {
+                  result5 = parse_s();
+                  if (result5 !== null) {
+                    result6 = parse_identifier();
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 61) {
+                          result8 = "=";
+                          pos++;
                         } else {
-                          var result11 = null;
-                          if (reportMatchFailures) {
+                          result8 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\"=\"");
                           }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            var result13 = parse_constExpr();
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === ";") {
-                                  var result15 = ";";
-                                  pos += 1;
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result10 = parse_constExpr();
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 59) {
+                                  result12 = ";";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
                                     matchFailed("\";\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16];
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13];
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, type, name, value) { return { type: "const", extAttrs: extAttrs, idlType: type, name: name, value: value }; })(result1[0], result1[4], result1[6], result1[10])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, type, name, value) { return { type: "const", extAttrs: extAttrs, idlType: type, name: name, value: value }; })(pos0, result0[0], result0[4], result0[6], result0[10]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_constExpr() {
-        var cacheKey = 'constExpr@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result6 = parse_BooleanLiteral();
-        if (result6 !== null) {
-          var result1 = result6;
-        } else {
-          var result5 = parse_float();
-          if (result5 !== null) {
-            var result1 = result5;
-          } else {
-            var result4 = parse_integer();
-            if (result4 !== null) {
-              var result1 = result4;
-            } else {
+        pos0 = pos;
+        result0 = parse_BooleanLiteral();
+        if (result0 === null) {
+          result0 = parse_float();
+          if (result0 === null) {
+            result0 = parse_integer();
+            if (result0 === null) {
               if (input.substr(pos, 3) === "NaN") {
-                var result3 = "NaN";
+                result0 = "NaN";
                 pos += 3;
               } else {
-                var result3 = null;
-                if (reportMatchFailures) {
+                result0 = null;
+                if (reportFailures === 0) {
                   matchFailed("\"NaN\"");
                 }
               }
-              if (result3 !== null) {
-                var result1 = result3;
-              } else {
-                var result1 = null;;
-              };
-            };
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(value) { return value; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+              if (result0 === null) {
+                if (input.substr(pos, 4) === "null") {
+                  result0 = "null";
+                  pos += 4;
+                } else {
+                  result0 = null;
+                  if (reportFailures === 0) {
+                    matchFailed("\"null\"");
+                  }
+                }
+                if (result0 === null) {
+                  if (input.charCodeAt(pos) === 39) {
+                    result0 = "'";
+                    pos++;
+                  } else {
+                    result0 = null;
+                    if (reportFailures === 0) {
+                      matchFailed("\"'\"");
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, value) { return value; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_attrOrOp() {
-        var cacheKey = 'attrOrOp@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result5 = parse_Stringifier();
-        if (result5 !== null) {
-          var result1 = result5;
-        } else {
-          var result4 = parse_Attribute();
-          if (result4 !== null) {
-            var result1 = result4;
-          } else {
-            var result3 = parse_Operation();
-            if (result3 !== null) {
-              var result1 = result3;
-            } else {
-              var result1 = null;;
-            };
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(ao) { return ao; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_Stringifier();
+        if (result0 === null) {
+          result0 = parse_Attribute();
+          if (result0 === null) {
+            result0 = parse_Operation();
+          }
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, ao) { return ao; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Stringifier() {
-        var cacheKey = 'Stringifier@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 11) === "stringifier") {
-          var result3 = "stringifier";
+          result0 = "stringifier";
           pos += 11;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"stringifier\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            var result8 = parse_Attribute();
-            if (result8 !== null) {
-              var result5 = result8;
-            } else {
-              var result7 = parse_OperationRest();
-              if (result7 !== null) {
-                var result5 = result7;
-              } else {
-                if (input.substr(pos, 1) === ";") {
-                  var result6 = ";";
-                  pos += 1;
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            result2 = parse_Attribute();
+            if (result2 === null) {
+              result2 = parse_OperationRest();
+              if (result2 === null) {
+                if (input.charCodeAt(pos) === 59) {
+                  result2 = ";";
+                  pos++;
                 } else {
-                  var result6 = null;
-                  if (reportMatchFailures) {
+                  result2 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\";\"");
                   }
                 }
-                if (result6 !== null) {
-                  var result5 = result6;
-                } else {
-                  var result5 = null;;
-                };
-              };
+              }
             }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(rest) {
-                      if (rest === ";") return { type: "stringifier" };
-                      else {
-                          rest.stringifier = true;
-                          return rest;
-                      }
-                  })(result1[2])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, rest) {
+                    if (rest === ";") return { type: "stringifier", stringifier: true };
+                    else {
+                        rest.stringifier = true;
+                        return rest;
+                    }
+                })(pos0, result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Attribute() {
-        var cacheKey = 'Attribute@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14;
+        var pos0, pos1, pos2;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result23 = parse_extendedAttributeList();
-        var result3 = result23 !== null ? result23 : '';
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            var savedPos2 = pos;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            pos2 = pos;
             if (input.substr(pos, 8) === "readonly") {
-              var result21 = "readonly";
+              result2 = "readonly";
               pos += 8;
             } else {
-              var result21 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"readonly\"");
               }
             }
-            if (result21 !== null) {
-              var result22 = parse_s();
-              if (result22 !== null) {
-                var result20 = [result21, result22];
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result2 = [result2, result3];
               } else {
-                var result20 = null;
-                pos = savedPos2;
+                result2 = null;
+                pos = pos2;
               }
             } else {
-              var result20 = null;
-              pos = savedPos2;
+              result2 = null;
+              pos = pos2;
             }
-            var result5 = result20 !== null ? result20 : '';
-            if (result5 !== null) {
+            result2 = result2 !== null ? result2 : "";
+            if (result2 !== null) {
               if (input.substr(pos, 9) === "attribute") {
-                var result6 = "attribute";
+                result3 = "attribute";
                 pos += 9;
               } else {
-                var result6 = null;
-                if (reportMatchFailures) {
+                result3 = null;
+                if (reportFailures === 0) {
                   matchFailed("\"attribute\"");
                 }
               }
-              if (result6 !== null) {
-                var result7 = parse_s();
-                if (result7 !== null) {
-                  var result8 = parse_type();
-                  if (result8 !== null) {
-                    var result9 = parse_s();
-                    if (result9 !== null) {
-                      var result10 = parse_identifier();
-                      if (result10 !== null) {
-                        var result11 = parse_w();
-                        if (result11 !== null) {
-                          var result19 = parse_GetRaises();
-                          var result12 = result19 !== null ? result19 : '';
-                          if (result12 !== null) {
-                            var result13 = parse_w();
-                            if (result13 !== null) {
-                              var result18 = parse_SetRaises();
-                              var result14 = result18 !== null ? result18 : '';
-                              if (result14 !== null) {
-                                var result15 = parse_w();
-                                if (result15 !== null) {
-                                  if (input.substr(pos, 1) === ";") {
-                                    var result16 = ";";
-                                    pos += 1;
+              if (result3 !== null) {
+                result4 = parse_s();
+                if (result4 !== null) {
+                  result5 = parse_type();
+                  if (result5 !== null) {
+                    result6 = parse_s();
+                    if (result6 !== null) {
+                      result7 = parse_identifier();
+                      if (result7 !== null) {
+                        result8 = parse_w();
+                        if (result8 !== null) {
+                          result9 = parse_GetRaises();
+                          result9 = result9 !== null ? result9 : "";
+                          if (result9 !== null) {
+                            result10 = parse_w();
+                            if (result10 !== null) {
+                              result11 = parse_SetRaises();
+                              result11 = result11 !== null ? result11 : "";
+                              if (result11 !== null) {
+                                result12 = parse_w();
+                                if (result12 !== null) {
+                                  if (input.charCodeAt(pos) === 59) {
+                                    result13 = ";";
+                                    pos++;
                                   } else {
-                                    var result16 = null;
-                                    if (reportMatchFailures) {
+                                    result13 = null;
+                                    if (reportFailures === 0) {
                                       matchFailed("\";\"");
                                     }
                                   }
-                                  if (result16 !== null) {
-                                    var result17 = parse_w();
-                                    if (result17 !== null) {
-                                      var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16, result17];
+                                  if (result13 !== null) {
+                                    result14 = parse_w();
+                                    if (result14 !== null) {
+                                      result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14];
                                     } else {
-                                      var result1 = null;
-                                      pos = savedPos1;
+                                      result0 = null;
+                                      pos = pos1;
                                     }
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, ro, type, name, gr, sr) { return { type: "attribute", extAttrs: extAttrs, idlType: type, name: name, readonly: (ro ? true : false), getraises: gr, setraises: sr }; })(result1[0], result1[2], result1[5], result1[7], result1[9], result1[11])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, ro, type, name, gr, sr) { return { type: "attribute", extAttrs: extAttrs, idlType: type, name: name, readonly: (ro ? true : false), getraises: gr, setraises: sr }; })(pos0, result0[0], result0[2], result0[5], result0[7], result0[9], result0[11]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_GetRaises() {
-        var cacheKey = 'GetRaises@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3, result4;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 9) === "getraises") {
-          var result3 = "getraises";
+          result0 = "getraises";
           pos += 9;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"getraises\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            if (input.substr(pos, 1) === "(") {
-              var result5 = "(";
-              pos += 1;
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            if (input.charCodeAt(pos) === 40) {
+              result2 = "(";
+              pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"(\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_ScopedNameList();
-              if (result6 !== null) {
-                if (input.substr(pos, 1) === ")") {
-                  var result7 = ")";
-                  pos += 1;
+            if (result2 !== null) {
+              result3 = parse_ScopedNameList();
+              if (result3 !== null) {
+                if (input.charCodeAt(pos) === 41) {
+                  result4 = ")";
+                  pos++;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\")\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result1 = [result3, result4, result5, result6, result7];
+                if (result4 !== null) {
+                  result0 = [result0, result1, result2, result3, result4];
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(list) { return list; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, list) { return list; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_SetRaises() {
-        var cacheKey = 'SetRaises@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3, result4;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 9) === "setraises") {
-          var result3 = "setraises";
+          result0 = "setraises";
           pos += 9;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"setraises\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            if (input.substr(pos, 1) === "(") {
-              var result5 = "(";
-              pos += 1;
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            if (input.charCodeAt(pos) === 40) {
+              result2 = "(";
+              pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"(\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_ScopedNameList();
-              if (result6 !== null) {
-                if (input.substr(pos, 1) === ")") {
-                  var result7 = ")";
-                  pos += 1;
+            if (result2 !== null) {
+              result3 = parse_ScopedNameList();
+              if (result3 !== null) {
+                if (input.charCodeAt(pos) === 41) {
+                  result4 = ")";
+                  pos++;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\")\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result1 = [result3, result4, result5, result6, result7];
+                if (result4 !== null) {
+                  result0 = [result0, result1, result2, result3, result4];
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(list) { return list; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, list) { return list; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Operation() {
-        var cacheKey = 'Operation@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result8 = parse_extendedAttributeList();
-        var result3 = result8 !== null ? result8 : '';
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            var result5 = parse_Qualifiers();
-            if (result5 !== null) {
-              var result6 = parse_w();
-              if (result6 !== null) {
-                var result7 = parse_OperationRest();
-                if (result7 !== null) {
-                  var result1 = [result3, result4, result5, result6, result7];
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            result2 = parse_Qualifiers();
+            if (result2 !== null) {
+              result3 = parse_w();
+              if (result3 !== null) {
+                result4 = parse_OperationRest();
+                if (result4 !== null) {
+                  result0 = [result0, result1, result2, result3, result4];
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, quals, rest) {
-                      for (var k in quals) rest[k] = quals[k];
-                      if (extAttrs) rest.extAttrs = extAttrs;
-                      return rest;
-                  })(result1[0], result1[2], result1[4])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, quals, rest) {
+                    for (var k in quals) rest[k] = quals[k];
+                    if (extAttrs) rest.extAttrs = extAttrs;
+                    return rest;
+                })(pos0, result0[0], result0[2], result0[4]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Qualifiers() {
-        var cacheKey = 'Qualifiers@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
           if (input.substr(pos, 6) === "static") {
-            var result7 = "static";
+            result1 = "static";
             pos += 6;
           } else {
-            var result7 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\"static\"");
             }
           }
-          if (result7 !== null) {
-            var result4 = result7;
-          } else {
-            var result5 = [];
-            var result6 = parse_Special();
-            while (result6 !== null) {
-              result5.push(result6);
-              var result6 = parse_Special();
+          if (result1 === null) {
+            result1 = [];
+            result2 = parse_Special();
+            while (result2 !== null) {
+              result1.push(result2);
+              result2 = parse_Special();
             }
-            if (result5 !== null) {
-              var result4 = result5;
-            } else {
-              var result4 = null;;
-            };
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(quals) {   if (typeof quals == "string") return [quals];
-          		    return quals; })(result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, quals) {   if (typeof quals == "string") return [quals];
+        		    return quals; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Special() {
-        var cacheKey = 'Special@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
           if (input.substr(pos, 6) === "getter") {
-            var result10 = "getter";
+            result1 = "getter";
             pos += 6;
           } else {
-            var result10 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\"getter\"");
             }
           }
-          if (result10 !== null) {
-            var result4 = result10;
-          } else {
+          if (result1 === null) {
             if (input.substr(pos, 6) === "setter") {
-              var result9 = "setter";
+              result1 = "setter";
               pos += 6;
             } else {
-              var result9 = null;
-              if (reportMatchFailures) {
+              result1 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"setter\"");
               }
             }
-            if (result9 !== null) {
-              var result4 = result9;
-            } else {
+            if (result1 === null) {
               if (input.substr(pos, 7) === "creator") {
-                var result8 = "creator";
+                result1 = "creator";
                 pos += 7;
               } else {
-                var result8 = null;
-                if (reportMatchFailures) {
+                result1 = null;
+                if (reportFailures === 0) {
                   matchFailed("\"creator\"");
                 }
               }
-              if (result8 !== null) {
-                var result4 = result8;
-              } else {
+              if (result1 === null) {
                 if (input.substr(pos, 7) === "deleter") {
-                  var result7 = "deleter";
+                  result1 = "deleter";
                   pos += 7;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result1 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"deleter\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result4 = result7;
-                } else {
+                if (result1 === null) {
                   if (input.substr(pos, 12) === "legacycaller") {
-                    var result6 = "legacycaller";
+                    result1 = "legacycaller";
                     pos += 12;
                   } else {
-                    var result6 = null;
-                    if (reportMatchFailures) {
+                    result1 = null;
+                    if (reportFailures === 0) {
                       matchFailed("\"legacycaller\"");
                     }
                   }
-                  if (result6 !== null) {
-                    var result4 = result6;
-                  } else {
-                    var result4 = null;;
-                  };
-                };
-              };
-            };
+                }
+              }
+            }
           }
-          if (result4 !== null) {
-            var result5 = parse_w();
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
+          if (result1 !== null) {
+            result2 = parse_w();
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(spe) { return spe; })(result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, spe) { return spe; })(pos0, result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_OperationRest() {
-        var cacheKey = 'OperationRest@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_ReturnType();
-        if (result3 !== null) {
-          var result4 = parse_s();
-          if (result4 !== null) {
-            var result19 = parse_identifier();
-            var result5 = result19 !== null ? result19 : '';
-            if (result5 !== null) {
-              var result6 = parse_w();
-              if (result6 !== null) {
-                if (input.substr(pos, 1) === "(") {
-                  var result7 = "(";
-                  pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ReturnType();
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
+            result2 = parse_identifier();
+            result2 = result2 !== null ? result2 : "";
+            if (result2 !== null) {
+              result3 = parse_w();
+              if (result3 !== null) {
+                if (input.charCodeAt(pos) === 40) {
+                  result4 = "(";
+                  pos++;
                 } else {
-                  var result7 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"(\"");
                   }
                 }
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    var result18 = parse_Arguments();
-                    var result9 = result18 !== null ? result18 : '';
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        if (input.substr(pos, 1) === ")") {
-                          var result11 = ")";
-                          pos += 1;
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    result6 = parse_Arguments();
+                    result6 = result6 !== null ? result6 : "";
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 41) {
+                          result8 = ")";
+                          pos++;
                         } else {
-                          var result11 = null;
-                          if (reportMatchFailures) {
+                          result8 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\")\"");
                           }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            var result17 = parse_Raises();
-                            var result13 = result17 !== null ? result17 : '';
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === ";") {
-                                  var result15 = ";";
-                                  pos += 1;
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result10 = parse_Raises();
+                            result10 = result10 !== null ? result10 : "";
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 59) {
+                                  result12 = ";";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
                                     matchFailed("\";\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16];
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13];
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(ret, name, args, exc) { return { type: "operation", idlType: ret, name: name, arguments: (args ? args : []), raises: exc }; })(result1[0], result1[2], result1[6], result1[10])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, ret, name, args, exc) { return { type: "operation", idlType: ret, name: name, arguments: (args ? args : []), raises: exc }; })(pos0, result0[0], result0[2], result0[6], result0[10]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Arguments() {
-        var cacheKey = 'Arguments@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_Argument();
-        if (result3 !== null) {
-          var result4 = [];
-          var result5 = parse_ArgumentsRest();
-          while (result5 !== null) {
-            result4.push(result5);
-            var result5 = parse_ArgumentsRest();
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_Argument();
+        if (result0 !== null) {
+          result1 = [];
+          result2 = parse_ArgumentsRest();
+          while (result2 !== null) {
+            result1.push(result2);
+            result2 = parse_ArgumentsRest();
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(first, others) {   var ret = [first];
-                      for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
-                      return ret; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, first, others) {   var ret = [first];
+                    for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
+                    return ret; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ArgumentsRest() {
-        var cacheKey = 'ArgumentsRest@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
-          if (input.substr(pos, 1) === ",") {
-            var result4 = ",";
-            pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 44) {
+            result1 = ",";
+            pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\",\"");
             }
           }
-          if (result4 !== null) {
-            var result5 = parse_w();
-            if (result5 !== null) {
-              var result6 = parse_Argument();
-              if (result6 !== null) {
-                var result1 = [result3, result4, result5, result6];
+          if (result1 !== null) {
+            result2 = parse_w();
+            if (result2 !== null) {
+              result3 = parse_Argument();
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(rest) { return rest; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, rest) { return rest; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Argument() {
-        var cacheKey = 'Argument@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result16 = parse_extendedAttributeList();
-        var result3 = result16 !== null ? result16 : '';
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
             if (input.substr(pos, 2) === "in") {
-              var result15 = "in";
+              result2 = "in";
               pos += 2;
             } else {
-              var result15 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"in\"");
               }
             }
-            var result5 = result15 !== null ? result15 : '';
-            if (result5 !== null) {
-              var result6 = parse_w();
-              if (result6 !== null) {
+            result2 = result2 !== null ? result2 : "";
+            if (result2 !== null) {
+              result3 = parse_w();
+              if (result3 !== null) {
                 if (input.substr(pos, 8) === "optional") {
-                  var result14 = "optional";
+                  result4 = "optional";
                   pos += 8;
                 } else {
-                  var result14 = null;
-                  if (reportMatchFailures) {
+                  result4 = null;
+                  if (reportFailures === 0) {
                     matchFailed("\"optional\"");
                   }
                 }
-                var result7 = result14 !== null ? result14 : '';
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    var result9 = parse_type();
-                    if (result9 !== null) {
+                result4 = result4 !== null ? result4 : "";
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    result6 = parse_type();
+                    if (result6 !== null) {
                       if (input.substr(pos, 3) === "...") {
-                        var result13 = "...";
+                        result7 = "...";
                         pos += 3;
                       } else {
-                        var result13 = null;
-                        if (reportMatchFailures) {
+                        result7 = null;
+                        if (reportFailures === 0) {
                           matchFailed("\"...\"");
                         }
                       }
-                      var result10 = result13 !== null ? result13 : '';
-                      if (result10 !== null) {
-                        var result11 = parse_s();
-                        if (result11 !== null) {
-                          var result12 = parse_identifier();
-                          if (result12 !== null) {
-                            var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12];
+                      result7 = result7 !== null ? result7 : "";
+                      if (result7 !== null) {
+                        result8 = parse_s();
+                        if (result8 !== null) {
+                          result9 = parse_identifier();
+                          if (result9 !== null) {
+                            result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9];
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, opt, type, ell, name) { return { name: name, type: type, variadic: (ell ? true : false), optional: (opt ? true : false), extAttrs: extAttrs }; })(result1[0], result1[4], result1[6], result1[7], result1[9])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, opt, type, ell, name) { return { name: name, type: type, variadic: (ell ? true : false), optional: (opt ? true : false), extAttrs: extAttrs }; })(pos0, result0[0], result0[4], result0[6], result0[7], result0[9]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_Raises() {
-        var cacheKey = 'Raises@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3, result4, result5, result6;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 6) === "raises") {
-          var result3 = "raises";
+          result0 = "raises";
           pos += 6;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"raises\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_s();
-          if (result4 !== null) {
-            if (input.substr(pos, 1) === "(") {
-              var result5 = "(";
-              pos += 1;
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
+            if (input.charCodeAt(pos) === 40) {
+              result2 = "(";
+              pos++;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"(\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_w();
-              if (result6 !== null) {
-                var result7 = parse_ScopedNameList();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === ")") {
-                      var result9 = ")";
-                      pos += 1;
+            if (result2 !== null) {
+              result3 = parse_w();
+              if (result3 !== null) {
+                result4 = parse_ScopedNameList();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 41) {
+                      result6 = ")";
+                      pos++;
                     } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
+                      result6 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\")\"");
                       }
                     }
-                    if (result9 !== null) {
-                      var result1 = [result3, result4, result5, result6, result7, result8, result9];
+                    if (result6 !== null) {
+                      result0 = [result0, result1, result2, result3, result4, result5, result6];
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(list) { return list; })(result1[4])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, list) { return list; })(pos0, result0[4]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_dictionary() {
-        var cacheKey = 'dictionary@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 10) === "dictionary") {
-          var result3 = "dictionary";
+          result0 = "dictionary";
           pos += 10;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"dictionary\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_s();
-          if (result4 !== null) {
-            var result5 = parse_identifier();
-            if (result5 !== null) {
-              var result6 = parse_w();
-              if (result6 !== null) {
-                var result18 = parse_ifInheritance();
-                var result7 = result18 !== null ? result18 : '';
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === "{") {
-                      var result9 = "{";
-                      pos += 1;
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
+            result2 = parse_identifier();
+            if (result2 !== null) {
+              result3 = parse_w();
+              if (result3 !== null) {
+                result4 = parse_Inheritance();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 123) {
+                      result6 = "{";
+                      pos++;
                     } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
+                      result6 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\"{\"");
                       }
                     }
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        var result11 = [];
-                        var result17 = parse_dictionaryMember();
-                        while (result17 !== null) {
-                          result11.push(result17);
-                          var result17 = parse_dictionaryMember();
-                        }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            if (input.substr(pos, 1) === "}") {
-                              var result13 = "}";
-                              pos += 1;
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        result8 = parse_DictionaryMemberList();
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            if (input.charCodeAt(pos) === 125) {
+                              result10 = "}";
+                              pos++;
                             } else {
-                              var result13 = null;
-                              if (reportMatchFailures) {
+                              result10 = null;
+                              if (reportFailures === 0) {
                                 matchFailed("\"}\"");
                               }
                             }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === ";") {
-                                  var result15 = ";";
-                                  pos += 1;
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 59) {
+                                  result12 = ";";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
+                                  result12 = null;
+                                  if (reportFailures === 0) {
                                     matchFailed("\";\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16];
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13];
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(name, superclass, members) {
-                          return { 
-                              type: "dictionary",
-                              name: name,
-                              inheritance: superclass,
-                              members: members
-                          };
-                      })(result1[2], result1[4], result1[8])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, name, superclass, members) {
+                        return {
+                            type: "dictionary",
+                            name: name,
+                            inheritance: superclass,
+                            members: members
+                        };
+                    })(pos0, result0[2], result0[4], result0[8]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
-      function parse_dictionaryMember() {
-        var cacheKey = 'dictionaryMember@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+      function parse_DictionaryMemberList() {
+        var result0, result1;
+        var pos0;
         
+        pos0 = pos;
+        result0 = [];
+        result1 = parse_DictionaryMember();
+        while (result1 !== null) {
+          result0.push(result1);
+          result1 = parse_DictionaryMember();
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, mem) { return mem ? mem : []; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_DictionaryMember() {
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result14 = parse_extendedAttributeList();
-        var result3 = result14 !== null ? result14 : '';
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            var result5 = parse_type();
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    var result13 = parse_defaultValue();
-                    var result9 = result13 !== null ? result13 : '';
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        if (input.substr(pos, 1) === ";") {
-                          var result11 = ";";
-                          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            result2 = parse_type();
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    result6 = parse_defaultValue();
+                    result6 = result6 !== null ? result6 : "";
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 59) {
+                          result8 = ";";
+                          pos++;
                         } else {
-                          var result11 = null;
-                          if (reportMatchFailures) {
+                          result8 = null;
+                          if (reportFailures === 0) {
                             matchFailed("\";\"");
                           }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12];
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9];
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, type, name, defaultValue) {
-                       return {
-                           type: type,
-                           name: name,
-                           defaultValue: defaultValue
-                       };
-                   })(result1[0], result1[2], result1[4], result1[6])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, type, name, defaultValue) {
+                     return {
+                         type: type,
+                         name: name,
+                         defaultValue: defaultValue
+                     };
+                 })(pos0, result0[0], result0[2], result0[4], result0[6]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_defaultValue() {
-        var cacheKey = 'defaultValue@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        if (input.substr(pos, 1) === "=") {
-          var result3 = "=";
-          pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        if (input.charCodeAt(pos) === 61) {
+          result0 = "=";
+          pos++;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"=\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
-            var result7 = parse_constExpr();
-            if (result7 !== null) {
-              var result5 = result7;
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
+            result2 = parse_constExpr();
+            if (result2 === null) {
+              result2 = parse_string();
+            }
+            if (result2 !== null) {
+              result0 = [result0, result1, result2];
             } else {
-              var result6 = parse_string();
-              if (result6 !== null) {
-                var result5 = result6;
-              } else {
-                var result5 = null;;
-              };
-            }
-            if (result5 !== null) {
-              var result1 = [result3, result4, result5];
-            } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function() { return value; })()
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, value) { return value; })(pos0, result0[2]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_typedef() {
-        var cacheKey = 'typedef@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
+        var result0, result1, result2, result3, result4, result5, result6, result7;
+        var pos0, pos1;
         
-        
-        var savedPos0 = pos;
-        var savedPos1 = pos;
+        pos0 = pos;
+        pos1 = pos;
         if (input.substr(pos, 7) === "typedef") {
-          var result3 = "typedef";
+          result0 = "typedef";
           pos += 7;
         } else {
-          var result3 = null;
-          if (reportMatchFailures) {
+          result0 = null;
+          if (reportFailures === 0) {
             matchFailed("\"typedef\"");
           }
         }
-        if (result3 !== null) {
-          var result4 = parse_s();
-          if (result4 !== null) {
-            var result5 = parse_type();
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === ";") {
-                      var result9 = ";";
-                      pos += 1;
+        if (result0 !== null) {
+          result1 = parse_s();
+          if (result1 !== null) {
+            result2 = parse_type();
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 59) {
+                      result6 = ";";
+                      pos++;
                     } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
+                      result6 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\";\"");
                       }
                     }
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        var result1 = [result3, result4, result5, result6, result7, result8, result9, result10];
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(type, name) { return { type: 'typedef', name: name, idlType: type }; })(result1[2], result1[4])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, type, name) { return { type: 'typedef', name: name, idlType: type }; })(pos0, result0[2], result0[4]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_exception() {
-        var cacheKey = 'exception@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result18 = parse_extendedAttributeList();
-        var result3 = result18 !== null ? result18 : '';
-        if (result3 !== null) {
-          var result4 = parse_w();
-          if (result4 !== null) {
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_w();
+          if (result1 !== null) {
             if (input.substr(pos, 9) === "exception") {
-              var result5 = "exception";
+              result2 = "exception";
               pos += 9;
             } else {
-              var result5 = null;
-              if (reportMatchFailures) {
+              result2 = null;
+              if (reportFailures === 0) {
                 matchFailed("\"exception\"");
               }
             }
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === "{") {
-                      var result9 = "{";
-                      pos += 1;
-                    } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
-                        matchFailed("\"{\"");
-                      }
-                    }
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        var result11 = [];
-                        var result17 = parse_exMember();
-                        while (result17 !== null) {
-                          result11.push(result17);
-                          var result17 = parse_exMember();
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    result6 = parse_Inheritance();
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        if (input.charCodeAt(pos) === 123) {
+                          result8 = "{";
+                          pos++;
+                        } else {
+                          result8 = null;
+                          if (reportFailures === 0) {
+                            matchFailed("\"{\"");
+                          }
                         }
-                        if (result11 !== null) {
-                          var result12 = parse_w();
-                          if (result12 !== null) {
-                            if (input.substr(pos, 1) === "}") {
-                              var result13 = "}";
-                              pos += 1;
-                            } else {
-                              var result13 = null;
-                              if (reportMatchFailures) {
-                                matchFailed("\"}\"");
-                              }
-                            }
-                            if (result13 !== null) {
-                              var result14 = parse_w();
-                              if (result14 !== null) {
-                                if (input.substr(pos, 1) === ";") {
-                                  var result15 = ";";
-                                  pos += 1;
+                        if (result8 !== null) {
+                          result9 = parse_w();
+                          if (result9 !== null) {
+                            result10 = parse_ExceptionMembers();
+                            if (result10 !== null) {
+                              result11 = parse_w();
+                              if (result11 !== null) {
+                                if (input.charCodeAt(pos) === 125) {
+                                  result12 = "}";
+                                  pos++;
                                 } else {
-                                  var result15 = null;
-                                  if (reportMatchFailures) {
-                                    matchFailed("\";\"");
+                                  result12 = null;
+                                  if (reportFailures === 0) {
+                                    matchFailed("\"}\"");
                                   }
                                 }
-                                if (result15 !== null) {
-                                  var result16 = parse_w();
-                                  if (result16 !== null) {
-                                    var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15, result16];
+                                if (result12 !== null) {
+                                  result13 = parse_w();
+                                  if (result13 !== null) {
+                                    if (input.charCodeAt(pos) === 59) {
+                                      result14 = ";";
+                                      pos++;
+                                    } else {
+                                      result14 = null;
+                                      if (reportFailures === 0) {
+                                        matchFailed("\";\"");
+                                      }
+                                    }
+                                    if (result14 !== null) {
+                                      result15 = parse_w();
+                                      if (result15 !== null) {
+                                        result0 = [result0, result1, result2, result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13, result14, result15];
+                                      } else {
+                                        result0 = null;
+                                        pos = pos1;
+                                      }
+                                    } else {
+                                      result0 = null;
+                                      pos = pos1;
+                                    }
                                   } else {
-                                    var result1 = null;
-                                    pos = savedPos1;
+                                    result0 = null;
+                                    pos = pos1;
                                   }
                                 } else {
-                                  var result1 = null;
-                                  pos = savedPos1;
+                                  result0 = null;
+                                  pos = pos1;
                                 }
                               } else {
-                                var result1 = null;
-                                pos = savedPos1;
+                                result0 = null;
+                                pos = pos1;
                               }
                             } else {
-                              var result1 = null;
-                              pos = savedPos1;
+                              result0 = null;
+                              pos = pos1;
                             }
                           } else {
-                            var result1 = null;
-                            pos = savedPos1;
+                            result0 = null;
+                            pos = pos1;
                           }
                         } else {
-                          var result1 = null;
-                          pos = savedPos1;
+                          result0 = null;
+                          pos = pos1;
                         }
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, name, mem) { return { type: 'exception', name: name, members: mem, extAttrs: extAttrs }; })(result1[0], result1[4], result1[8])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, name, herit, mem) {
+                    return {
+                        type: 'exception',
+                        name: name,
+                        inheritance: herit,
+                        members: mem,
+                        extAttrs: extAttrs,
+                    };
+                })(pos0, result0[0], result0[4], result0[6], result0[10]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
-      function parse_exMember() {
-        var cacheKey = 'exMember@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+      function parse_ExceptionMembers() {
+        var result0, result1;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result4 = parse_const();
-        if (result4 !== null) {
-          var result1 = result4;
-        } else {
-          var result3 = parse_field();
-          if (result3 !== null) {
-            var result1 = result3;
-          } else {
-            var result1 = null;;
-          };
-        }
-        var result2 = result1 !== null
-          ? (function(mem) { return mem; })(result1)
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
+        pos0 = pos;
+        result0 = [];
+        result1 = parse_ExceptionMember();
+        while (result1 !== null) {
+          result0.push(result1);
+          result1 = parse_ExceptionMember();
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, mem) { return mem ? mem : []; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_ExceptionMember() {
+        var result0;
+        var pos0;
         
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_const();
+        if (result0 === null) {
+          result0 = parse_field();
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, mem) { return mem; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_field() {
-        var cacheKey = 'field@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3, result4, result5, result6, result7;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result12 = parse_extendedAttributeList();
-        var result3 = result12 !== null ? result12 : '';
-        if (result3 !== null) {
-          var result11 = parse_s();
-          var result4 = result11 !== null ? result11 : '';
-          if (result4 !== null) {
-            var result5 = parse_type();
-            if (result5 !== null) {
-              var result6 = parse_s();
-              if (result6 !== null) {
-                var result7 = parse_identifier();
-                if (result7 !== null) {
-                  var result8 = parse_w();
-                  if (result8 !== null) {
-                    if (input.substr(pos, 1) === ";") {
-                      var result9 = ";";
-                      pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtendedAttributeList();
+        if (result0 !== null) {
+          result1 = parse_s();
+          result1 = result1 !== null ? result1 : "";
+          if (result1 !== null) {
+            result2 = parse_type();
+            if (result2 !== null) {
+              result3 = parse_s();
+              if (result3 !== null) {
+                result4 = parse_identifier();
+                if (result4 !== null) {
+                  result5 = parse_w();
+                  if (result5 !== null) {
+                    if (input.charCodeAt(pos) === 59) {
+                      result6 = ";";
+                      pos++;
                     } else {
-                      var result9 = null;
-                      if (reportMatchFailures) {
+                      result6 = null;
+                      if (reportFailures === 0) {
                         matchFailed("\";\"");
                       }
                     }
-                    if (result9 !== null) {
-                      var result10 = parse_w();
-                      if (result10 !== null) {
-                        var result1 = [result3, result4, result5, result6, result7, result8, result9, result10];
+                    if (result6 !== null) {
+                      result7 = parse_w();
+                      if (result7 !== null) {
+                        result0 = [result0, result1, result2, result3, result4, result5, result6, result7];
                       } else {
-                        var result1 = null;
-                        pos = savedPos1;
+                        result0 = null;
+                        pos = pos1;
                       }
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(extAttrs, type, name) { return { type: "field", extAttrs: extAttrs, idlType: type, name: name }; })(result1[0], result1[2], result1[4])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, extAttrs, type, name) { return { type: "field", extAttrs: extAttrs, idlType: type, name: name }; })(pos0, result0[0], result0[2], result0[4]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
+        return result0;
+      }
+      
+      function parse_ExtendedAttributeList() {
+        var result0;
+        var pos0;
         
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+        pos0 = pos;
+        result0 = parse_ExtendedAttributeListInner();
+        result0 = result0 !== null ? result0 : "";
+        if (result0 !== null) {
+          result0 = (function(offset, ea) { return ea ? ea : []; })(pos0, result0);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
-      function parse_extendedAttributeList() {
-        var cacheKey = 'extendedAttributeList@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+      function parse_ExtendedAttributeListInner() {
+        var result0, result1, result2, result3, result4, result5, result6;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
-          if (input.substr(pos, 1) === "[") {
-            var result4 = "[";
-            pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 91) {
+            result1 = "[";
+            pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\"[\"");
             }
           }
-          if (result4 !== null) {
-            var result5 = parse_w();
-            if (result5 !== null) {
-              var result6 = parse_ExtAttrs();
-              if (result6 !== null) {
-                var result7 = parse_w();
-                if (result7 !== null) {
-                  if (input.substr(pos, 1) === "]") {
-                    var result8 = "]";
-                    pos += 1;
+          if (result1 !== null) {
+            result2 = parse_w();
+            if (result2 !== null) {
+              result3 = parse_ExtAttrs();
+              if (result3 !== null) {
+                result4 = parse_w();
+                if (result4 !== null) {
+                  if (input.charCodeAt(pos) === 93) {
+                    result5 = "]";
+                    pos++;
                   } else {
-                    var result8 = null;
-                    if (reportMatchFailures) {
+                    result5 = null;
+                    if (reportFailures === 0) {
                       matchFailed("\"]\"");
                     }
                   }
-                  if (result8 !== null) {
-                    var result9 = parse_w();
-                    if (result9 !== null) {
-                      var result1 = [result3, result4, result5, result6, result7, result8, result9];
+                  if (result5 !== null) {
+                    result6 = parse_w();
+                    if (result6 !== null) {
+                      result0 = [result0, result1, result2, result3, result4, result5, result6];
                     } else {
-                      var result1 = null;
-                      pos = savedPos1;
+                      result0 = null;
+                      pos = pos1;
                     }
                   } else {
-                    var result1 = null;
-                    pos = savedPos1;
+                    result0 = null;
+                    pos = pos1;
                   }
                 } else {
-                  var result1 = null;
-                  pos = savedPos1;
+                  result0 = null;
+                  pos = pos1;
                 }
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(ea) { return ea; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, ea) { return ea; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ExtAttrs() {
-        var cacheKey = 'ExtAttrs@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_ExtAttr();
-        if (result3 !== null) {
-          var result4 = [];
-          var result5 = parse_ExtAttrsRest();
-          while (result5 !== null) {
-            result4.push(result5);
-            var result5 = parse_ExtAttrsRest();
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_ExtAttr();
+        if (result0 !== null) {
+          result1 = [];
+          result2 = parse_ExtAttrsRest();
+          while (result2 !== null) {
+            result1.push(result2);
+            result2 = parse_ExtAttrsRest();
           }
-          if (result4 !== null) {
-            var result1 = [result3, result4];
+          if (result1 !== null) {
+            result0 = [result0, result1];
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(first, others) {   var ret = [first];
-                      for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
-                      return ret; })(result1[0], result1[1])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, first, others) {   var ret = [first];
+                    for (var i = 0, n = others.length; i < n; i++) { ret.push(others[i]); }
+                    return ret; })(pos0, result0[0], result0[1]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ExtAttrsRest() {
-        var cacheKey = 'ExtAttrsRest@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0, result1, result2, result3;
+        var pos0, pos1;
         
-        var savedPos0 = pos;
-        var savedPos1 = pos;
-        var result3 = parse_w();
-        if (result3 !== null) {
-          if (input.substr(pos, 1) === ",") {
-            var result4 = ",";
-            pos += 1;
+        pos0 = pos;
+        pos1 = pos;
+        result0 = parse_w();
+        if (result0 !== null) {
+          if (input.charCodeAt(pos) === 44) {
+            result1 = ",";
+            pos++;
           } else {
-            var result4 = null;
-            if (reportMatchFailures) {
+            result1 = null;
+            if (reportFailures === 0) {
               matchFailed("\",\"");
             }
           }
-          if (result4 !== null) {
-            var result5 = parse_w();
-            if (result5 !== null) {
-              var result6 = parse_ExtAttr();
-              if (result6 !== null) {
-                var result1 = [result3, result4, result5, result6];
+          if (result1 !== null) {
+            result2 = parse_w();
+            if (result2 !== null) {
+              result3 = parse_ExtAttr();
+              if (result3 !== null) {
+                result0 = [result0, result1, result2, result3];
               } else {
-                var result1 = null;
-                pos = savedPos1;
+                result0 = null;
+                pos = pos1;
               }
             } else {
-              var result1 = null;
-              pos = savedPos1;
+              result0 = null;
+              pos = pos1;
             }
           } else {
-            var result1 = null;
-            pos = savedPos1;
+            result0 = null;
+            pos = pos1;
           }
         } else {
-          var result1 = null;
-          pos = savedPos1;
-        }
-        var result2 = result1 !== null
-          ? (function(rest) { return rest; })(result1[3])
-          : null;
-        if (result2 !== null) {
-          var result0 = result2;
-        } else {
-          var result0 = null;
-          pos = savedPos0;
-        }
-        
-        
-        
-        cache[cacheKey] = {
-          nextPos: pos,
-          result:  result0
-        };
+          result0 = null;
+          pos = pos1;
+        }
+        if (result0 !== null) {
+          result0 = (function(offset, rest) { return rest; })(pos0, result0[3]);
+        }
+        if (result0 === null) {
+          pos = pos0;
+        }
         return result0;
       }
       
       function parse_ExtAttr() {
-        var cacheKey = 'ExtAttr@' + pos;
-        var cachedResult = cache[cacheKey];
-        if (cachedResult) {
-          pos = cachedResult.nextPos;
-          return cachedResult.result;
-        }
-        
+        var result0;
+        var pos0;
         
-        var savedPos0 = pos;
-        var result6 = parse_ExtAttrArgList();
-        if (result6 !== null) {
-          var result1 = result6;
-        } else {
-          var result5 = parse_ExtAttrNamedArgList();
-          if (result5 !== null) {
-            var result1 = result5;
-          } else {
-            var result4 = parse_ExtAttrNameValue();
-            if (result4 !== null) {
-              var result1 = result4;
-            } else {
-              var result3 = parse_ExtAttrNoArg();
-              if (result3 !== null) {
-                var result1 = result3;
-              } else {
-                var result1 = null;;
-              }