// From https://github.com/darobin/webidl.js/tree/, under MIT license
// Forked at https://github.com/ayg/webidl.js
window.WebIDLParser = (function(){
  /* Generated by PEG.js 0.6.2 (http://pegjs.majda.cz/). */
  
  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,
        "ArrayType": parse_ArrayType,
        "Attribute": parse_Attribute,
        "BooleanLiteral": parse_BooleanLiteral,
        "ExtAttr": parse_ExtAttr,
        "ExtAttrArgList": parse_ExtAttrArgList,
        "ExtAttrNameValue": parse_ExtAttrNameValue,
        "ExtAttrNamedArgList": parse_ExtAttrNamedArgList,
        "ExtAttrNoArg": parse_ExtAttrNoArg,
        "ExtAttrs": parse_ExtAttrs,
        "ExtAttrsRest": parse_ExtAttrsRest,
        "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,
        "UnsignedIntegerType": parse_UnsignedIntegerType,
        "attrOrOp": parse_attrOrOp,
        "const": parse_const,
        "constExpr": parse_constExpr,
        "decimal": parse_decimal,
        "defaultValue": parse_defaultValue,
        "definition": parse_definition,
        "definitions": parse_definitions,
        "dictionary": parse_dictionary,
        "dictionaryMember": parse_dictionaryMember,
        "dotFloat": parse_dotFloat,
        "exMember": parse_exMember,
        "exception": parse_exception,
        "expFloat": parse_expFloat,
        "extendedAttributeList": parse_extendedAttributeList,
        "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
      };
      
      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 = {};
      
      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);
        
        if (charCode <= 0xFF) {
          var escapeChar = 'x';
          var length = 2;
        } else {
          var escapeChar = 'u';
          var 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) {
          return;
        }
        
        if (pos > rightmostMatchFailuresPos) {
          rightmostMatchFailuresPos = pos;
          rightmostMatchFailuresExpected = [];
        }
        
        rightmostMatchFailuresExpected.push(failure);
      }
      
      function parse_space() {
        var cacheKey = 'space@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        if (input.substr(pos, 1) === " ") {
          var result20 = " ";
          pos += 1;
        } else {
          var result20 = null;
          if (reportMatchFailures) {
            matchFailed("\" \"");
          }
        }
        if (result20 !== null) {
          var result0 = result20;
        } else {
          if (input.substr(pos, 1) === "	") {
            var result19 = "	";
            pos += 1;
          } else {
            var result19 = null;
            if (reportMatchFailures) {
              matchFailed("\"	\"");
            }
          }
          if (result19 !== null) {
            var result0 = result19;
          } else {
            if (input.substr(pos, 1) === "\r") {
              var result18 = "\r";
              pos += 1;
            } else {
              var result18 = null;
              if (reportMatchFailures) {
                matchFailed("\"\\r\"");
              }
            }
            if (result18 !== null) {
              var result0 = result18;
            } else {
              if (input.substr(pos, 1) === "\n") {
                var result17 = "\n";
                pos += 1;
              } else {
                var result17 = null;
                if (reportMatchFailures) {
                  matchFailed("\"\\n\"");
                }
              }
              if (result17 !== null) {
                var result0 = result17;
              } else {
                if (input.substr(pos, 1) === "") {
                  var result16 = "";
                  pos += 1;
                } else {
                  var result16 = null;
                  if (reportMatchFailures) {
                    matchFailed("\"\"");
                  }
                }
                if (result16 !== null) {
                  var result0 = result16;
                } else {
                  var savedPos3 = pos;
                  if (input.substr(pos, 2) === "//") {
                    var result12 = "//";
                    pos += 2;
                  } else {
                    var result12 = null;
                    if (reportMatchFailures) {
                      matchFailed("\"//\"");
                    }
                  }
                  if (result12 !== null) {
                    var result13 = [];
                    if (input.substr(pos).match(/^[^\n]/) !== null) {
                      var result15 = input.charAt(pos);
                      pos++;
                    } else {
                      var result15 = null;
                      if (reportMatchFailures) {
                        matchFailed("[^\\n]");
                      }
                    }
                    while (result15 !== null) {
                      result13.push(result15);
                      if (input.substr(pos).match(/^[^\n]/) !== null) {
                        var result15 = input.charAt(pos);
                        pos++;
                      } else {
                        var result15 = null;
                        if (reportMatchFailures) {
                          matchFailed("[^\\n]");
                        }
                      }
                    }
                    if (result13 !== null) {
                      if (input.substr(pos, 1) === "\n") {
                        var result14 = "\n";
                        pos += 1;
                      } else {
                        var result14 = null;
                        if (reportMatchFailures) {
                          matchFailed("\"\\n\"");
                        }
                      }
                      if (result14 !== null) {
                        var result11 = [result12, result13, result14];
                      } else {
                        var result11 = null;
                        pos = savedPos3;
                      }
                    } else {
                      var result11 = null;
                      pos = savedPos3;
                    }
                  } else {
                    var result11 = null;
                    pos = savedPos3;
                  }
                  if (result11 !== null) {
                    var result0 = result11;
                  } else {
                    var savedPos0 = pos;
                    if (input.substr(pos, 2) === "/*") {
                      var result2 = "/*";
                      pos += 2;
                    } else {
                      var result2 = null;
                      if (reportMatchFailures) {
                        matchFailed("\"/*\"");
                      }
                    }
                    if (result2 !== null) {
                      var result3 = [];
                      if (input.substr(pos).match(/^[^*]/) !== null) {
                        var result10 = input.charAt(pos);
                        pos++;
                      } else {
                        var result10 = null;
                        if (reportMatchFailures) {
                          matchFailed("[^*]");
                        }
                      }
                      if (result10 !== null) {
                        var result5 = result10;
                      } else {
                        var savedPos1 = pos;
                        if (input.substr(pos, 1) === "*") {
                          var result7 = "*";
                          pos += 1;
                        } else {
                          var result7 = null;
                          if (reportMatchFailures) {
                            matchFailed("\"*\"");
                          }
                        }
                        if (result7 !== null) {
                          var savedPos2 = pos;
                          var savedReportMatchFailuresVar0 = reportMatchFailures;
                          reportMatchFailures = false;
                          if (input.substr(pos, 1) === "/") {
                            var result9 = "/";
                            pos += 1;
                          } else {
                            var result9 = null;
                            if (reportMatchFailures) {
                              matchFailed("\"/\"");
                            }
                          }
                          reportMatchFailures = savedReportMatchFailuresVar0;
                          if (result9 === null) {
                            var result8 = '';
                          } else {
                            var result8 = null;
                            pos = savedPos2;
                          }
                          if (result8 !== null) {
                            var result6 = [result7, result8];
                          } else {
                            var result6 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result6 = null;
                          pos = savedPos1;
                        }
                        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);
                          pos++;
                        } else {
                          var result10 = null;
                          if (reportMatchFailures) {
                            matchFailed("[^*]");
                          }
                        }
                        if (result10 !== null) {
                          var result5 = result10;
                        } else {
                          var savedPos1 = pos;
                          if (input.substr(pos, 1) === "*") {
                            var result7 = "*";
                            pos += 1;
                          } else {
                            var result7 = null;
                            if (reportMatchFailures) {
                              matchFailed("\"*\"");
                            }
                          }
                          if (result7 !== null) {
                            var savedPos2 = pos;
                            var savedReportMatchFailuresVar0 = reportMatchFailures;
                            reportMatchFailures = false;
                            if (input.substr(pos, 1) === "/") {
                              var result9 = "/";
                              pos += 1;
                            } else {
                              var result9 = null;
                              if (reportMatchFailures) {
                                matchFailed("\"/\"");
                              }
                            }
                            reportMatchFailures = savedReportMatchFailuresVar0;
                            if (result9 === null) {
                              var result8 = '';
                            } else {
                              var result8 = null;
                              pos = savedPos2;
                            }
                            if (result8 !== null) {
                              var result6 = [result7, result8];
                            } else {
                              var result6 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result6 = null;
                            pos = savedPos1;
                          }
                          if (result6 !== null) {
                            var result5 = result6;
                          } else {
                            var result5 = null;;
                          };
                        }
                      }
                      if (result3 !== null) {
                        if (input.substr(pos, 2) === "*/") {
                          var result4 = "*/";
                          pos += 2;
                        } else {
                          var result4 = null;
                          if (reportMatchFailures) {
                            matchFailed("\"*/\"");
                          }
                        }
                        if (result4 !== null) {
                          var result1 = [result2, result3, result4];
                        } else {
                          var result1 = null;
                          pos = savedPos0;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos0;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos0;
                    }
                    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 result1 = parse_space();
        if (result1 !== null) {
          var result0 = [];
          while (result1 !== null) {
            result0.push(result1);
            var result1 = parse_space();
          }
        } else {
          var result0 = null;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_w() {
        var cacheKey = 'w@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var result1 = parse_s();
        var result0 = result1 !== null ? result1 : '';
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_identifier() {
        var cacheKey = 'identifier@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos).match(/^[A-Z_a-z]/) !== null) {
          var result3 = input.charAt(pos);
          pos++;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            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);
            pos++;
          } else {
            var result5 = null;
            if (reportMatchFailures) {
              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);
              pos++;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("[0-9A-Z_a-z]");
              }
            }
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_octal() {
        var cacheKey = 'octal@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 1) === "0") {
          var result3 = "0";
          pos += 1;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"0\"");
          }
        }
        if (result3 !== null) {
          var result4 = [];
          if (input.substr(pos).match(/^[0-7]/) !== null) {
            var result5 = input.charAt(pos);
            pos++;
          } else {
            var result5 = null;
            if (reportMatchFailures) {
              matchFailed("[0-7]");
            }
          }
          while (result5 !== null) {
            result4.push(result5);
            if (input.substr(pos).match(/^[0-7]/) !== null) {
              var result5 = input.charAt(pos);
              pos++;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("[0-7]");
              }
            }
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_hex() {
        var cacheKey = 'hex@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 1) === "0") {
          var result3 = "0";
          pos += 1;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"0\"");
          }
        }
        if (result3 !== null) {
          if (input.substr(pos).match(/^[Xx]/) !== null) {
            var result4 = input.charAt(pos);
            pos++;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              matchFailed("[Xx]");
            }
          }
          if (result4 !== null) {
            if (input.substr(pos).match(/^[0-9A-Fa-f]/) !== null) {
              var result6 = input.charAt(pos);
              pos++;
            } else {
              var result6 = null;
              if (reportMatchFailures) {
                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);
                  pos++;
                } else {
                  var result6 = null;
                  if (reportMatchFailures) {
                    matchFailed("[0-9A-Fa-f]");
                  }
                }
              }
            } else {
              var result5 = null;
            }
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_decimal() {
        var cacheKey = 'decimal@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos).match(/^[0-9]/) !== null) {
          var result3 = input.charAt(pos);
          pos++;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("[0-9]");
          }
        }
        if (result3 !== null) {
          var result4 = [];
          if (input.substr(pos).match(/^[0-9]/) !== null) {
            var result5 = input.charAt(pos);
            pos++;
          } else {
            var result5 = null;
            if (reportMatchFailures) {
              matchFailed("[0-9]");
            }
          }
          while (result5 !== null) {
            result4.push(result5);
            if (input.substr(pos).match(/^[0-9]/) !== null) {
              var result5 = input.charAt(pos);
              pos++;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("[0-9]");
              }
            }
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_integer() {
        var cacheKey = 'integer@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 1) === "-") {
          var result8 = "-";
          pos += 1;
        } else {
          var result8 = null;
          if (reportMatchFailures) {
            matchFailed("\"-\"");
          }
        }
        var result3 = result8 !== null ? result8 : '';
        if (result3 !== null) {
          var result7 = parse_hex();
          if (result7 !== null) {
            var result4 = result7;
          } 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;
          }
        } 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
        };
        return result0;
      }
      
      function parse_floatEe() {
        var cacheKey = 'floatEe@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos).match(/^[Ee]/) !== null) {
          var result3 = input.charAt(pos);
          pos++;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("[Ee]");
          }
        }
        if (result3 !== null) {
          if (input.substr(pos).match(/^[+\-]/) !== null) {
            var result7 = input.charAt(pos);
            pos++;
          } else {
            var result7 = null;
            if (reportMatchFailures) {
              matchFailed("[+\\-]");
            }
          }
          var result4 = result7 !== null ? result7 : '';
          if (result4 !== null) {
            if (input.substr(pos).match(/^[0-9]/) !== null) {
              var result6 = input.charAt(pos);
              pos++;
            } else {
              var result6 = null;
              if (reportMatchFailures) {
                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);
                  pos++;
                } else {
                  var result6 = null;
                  if (reportMatchFailures) {
                    matchFailed("[0-9]");
                  }
                }
              }
            } else {
              var result5 = null;
            }
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_expFloat() {
        var cacheKey = 'expFloat@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos).match(/^[0-9]/) !== null) {
          var result5 = input.charAt(pos);
          pos++;
        } else {
          var result5 = null;
          if (reportMatchFailures) {
            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);
              pos++;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("[0-9]");
              }
            }
          }
        } else {
          var result3 = null;
        }
        if (result3 !== null) {
          var result4 = parse_floatEe();
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_leadFloat() {
        var cacheKey = 'leadFloat@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos).match(/^[0-9]/) !== null) {
          var result9 = input.charAt(pos);
          pos++;
        } else {
          var result9 = null;
          if (reportMatchFailures) {
            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);
              pos++;
            } else {
              var result9 = null;
              if (reportMatchFailures) {
                matchFailed("[0-9]");
              }
            }
          }
        } else {
          var result3 = null;
        }
        if (result3 !== null) {
          if (input.substr(pos, 1) === ".") {
            var result4 = ".";
            pos += 1;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              matchFailed("\".\"");
            }
          }
          if (result4 !== null) {
            var result5 = [];
            if (input.substr(pos).match(/^[0-9]/) !== null) {
              var result8 = input.charAt(pos);
              pos++;
            } else {
              var result8 = null;
              if (reportMatchFailures) {
                matchFailed("[0-9]");
              }
            }
            while (result8 !== null) {
              result5.push(result8);
              if (input.substr(pos).match(/^[0-9]/) !== null) {
                var result8 = input.charAt(pos);
                pos++;
              } else {
                var result8 = null;
                if (reportMatchFailures) {
                  matchFailed("[0-9]");
                }
              }
            }
            if (result5 !== null) {
              var result7 = parse_floatEe();
              var result6 = result7 !== null ? result7 : '';
              if (result6 !== null) {
                var result1 = [result3, result4, result5, result6];
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_dotFloat() {
        var cacheKey = 'dotFloat@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = [];
        if (input.substr(pos).match(/^[0-9]/) !== null) {
          var result9 = input.charAt(pos);
          pos++;
        } else {
          var result9 = null;
          if (reportMatchFailures) {
            matchFailed("[0-9]");
          }
        }
        while (result9 !== null) {
          result3.push(result9);
          if (input.substr(pos).match(/^[0-9]/) !== null) {
            var result9 = input.charAt(pos);
            pos++;
          } else {
            var result9 = null;
            if (reportMatchFailures) {
              matchFailed("[0-9]");
            }
          }
        }
        if (result3 !== null) {
          if (input.substr(pos, 1) === ".") {
            var result4 = ".";
            pos += 1;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              matchFailed("\".\"");
            }
          }
          if (result4 !== null) {
            if (input.substr(pos).match(/^[0-9]/) !== null) {
              var result8 = input.charAt(pos);
              pos++;
            } else {
              var result8 = null;
              if (reportMatchFailures) {
                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);
                  pos++;
                } else {
                  var result8 = null;
                  if (reportMatchFailures) {
                    matchFailed("[0-9]");
                  }
                }
              }
            } else {
              var result5 = null;
            }
            if (result5 !== null) {
              var result7 = parse_floatEe();
              var result6 = result7 !== null ? result7 : '';
              if (result6 !== null) {
                var result1 = [result3, result4, result5, result6];
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_float() {
        var cacheKey = 'float@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 1) === "-") {
          var result8 = "-";
          pos += 1;
        } else {
          var result8 = null;
          if (reportMatchFailures) {
            matchFailed("\"-\"");
          }
        }
        var result3 = result8 !== null ? result8 : '';
        if (result3 !== null) {
          var result7 = parse_leadFloat();
          if (result7 !== null) {
            var result4 = result7;
          } else {
            var result6 = parse_dotFloat();
            if (result6 !== null) {
              var result4 = result6;
            } else {
              var result5 = parse_expFloat();
              if (result5 !== null) {
                var result4 = result5;
              } else {
                var result4 = null;;
              };
            };
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_string() {
        var cacheKey = 'string@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 1) === "\"") {
          var result3 = "\"";
          pos += 1;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"\\\"\"");
          }
        }
        if (result3 !== null) {
          var result4 = [];
          if (input.substr(pos).match(/^[^""]/) !== null) {
            var result6 = input.charAt(pos);
            pos++;
          } else {
            var result6 = null;
            if (reportMatchFailures) {
              matchFailed("[^\"\"]");
            }
          }
          while (result6 !== null) {
            result4.push(result6);
            if (input.substr(pos).match(/^[^""]/) !== null) {
              var result6 = input.charAt(pos);
              pos++;
            } else {
              var result6 = null;
              if (reportMatchFailures) {
                matchFailed("[^\"\"]");
              }
            }
          }
          if (result4 !== null) {
            if (input.substr(pos, 1) === "\"") {
              var result5 = "\"";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\"\\\"\"");
              }
            }
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_other() {
        var cacheKey = 'other@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        if (input.substr(pos).match(/^[^	\n\r 0-9A-Z_a-z]/) !== null) {
          var result3 = input.charAt(pos);
          pos++;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("[^	\\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);
              pos++;
            } else {
              var result3 = null;
              if (reportMatchFailures) {
                matchFailed("[^	\\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
        };
        return result0;
      }
      
      function parse_type() {
        var cacheKey = 'type@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_TypeDesc();
        if (result3 !== null) {
          var result4 = parse_Nullable();
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_TypeDesc() {
        var cacheKey = 'TypeDesc@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var result5 = parse_Sequence();
        if (result5 !== null) {
          var result1 = result5;
        } else {
          var result4 = parse_ArrayType();
          if (result4 !== null) {
            var result1 = result4;
          } else {
            var result3 = parse_SimpleType();
            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
        };
        return result0;
      }
      
      function parse_Sequence() {
        var cacheKey = 'Sequence@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 9) === "sequence<") {
          var result3 = "sequence<";
          pos += 9;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"sequence<\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_type();
          if (result4 !== null) {
            if (input.substr(pos, 1) === ">") {
              var result5 = ">";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\">\"");
              }
            }
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } else {
          var result1 = null;
          pos = savedPos1;
        }
        var result2 = result1 !== null
          ? (function(type) { return { sequence: true, array: false, idlType: type }; })(result1[1])
          : null;
        if (result2 !== null) {
          var result0 = result2;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_ArrayType() {
        var cacheKey = 'ArrayType@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_SimpleType();
        if (result3 !== null) {
          if (input.substr(pos, 2) === "[]") {
            var result4 = "[]";
            pos += 2;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              matchFailed("\"[]\"");
            }
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_SimpleType() {
        var cacheKey = 'SimpleType@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var result5 = parse_PrimitiveType();
        if (result5 !== null) {
          var result1 = result5;
        } else {
          var result4 = parse_UnsignedIntegerType();
          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 }; })(result1)
          : null;
        if (result2 !== null) {
          var result0 = result2;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_PrimitiveType() {
        var cacheKey = 'PrimitiveType@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 3) === "any") {
          var result12 = "any";
          pos += 3;
        } else {
          var result12 = null;
          if (reportMatchFailures) {
            matchFailed("\"any\"");
          }
        }
        if (result12 !== null) {
          var result3 = result12;
        } else {
          if (input.substr(pos, 6) === "object") {
            var result11 = "object";
            pos += 6;
          } else {
            var result11 = null;
            if (reportMatchFailures) {
              matchFailed("\"object\"");
            }
          }
          if (result11 !== null) {
            var result3 = result11;
          } else {
            if (input.substr(pos, 7) === "boolean") {
              var result10 = "boolean";
              pos += 7;
            } else {
              var result10 = null;
              if (reportMatchFailures) {
                matchFailed("\"boolean\"");
              }
            }
            if (result10 !== null) {
              var result3 = result10;
            } else {
              if (input.substr(pos, 5) === "octet") {
                var result9 = "octet";
                pos += 5;
              } else {
                var result9 = null;
                if (reportMatchFailures) {
                  matchFailed("\"octet\"");
                }
              }
              if (result9 !== null) {
                var result3 = result9;
              } else {
                if (input.substr(pos, 5) === "float") {
                  var result8 = "float";
                  pos += 5;
                } else {
                  var result8 = null;
                  if (reportMatchFailures) {
                    matchFailed("\"float\"");
                  }
                }
                if (result8 !== null) {
                  var result3 = result8;
                } else {
                  if (input.substr(pos, 6) === "double") {
                    var result7 = "double";
                    pos += 6;
                  } else {
                    var result7 = null;
                    if (reportMatchFailures) {
                      matchFailed("\"double\"");
                    }
                  }
                  if (result7 !== null) {
                    var result3 = result7;
                  } else {
                    if (input.substr(pos, 9) === "DOMString") {
                      var result6 = "DOMString";
                      pos += 9;
                    } else {
                      var result6 = null;
                      if (reportMatchFailures) {
                        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);
            pos++;
          } else {
            var result5 = null;
            if (reportMatchFailures) {
              matchFailed("[A-Za-z0-9]");
            }
          }
          reportMatchFailures = savedReportMatchFailuresVar0;
          if (result5 === null) {
            var result4 = '';
          } else {
            var result4 = null;
            pos = savedPos2;
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_UnsignedIntegerType() {
        var cacheKey = 'UnsignedIntegerType@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 8) === "unsigned") {
          var result13 = "unsigned";
          pos += 8;
        } else {
          var result13 = null;
          if (reportMatchFailures) {
            matchFailed("\"unsigned\"");
          }
        }
        var result3 = result13 !== null ? result13 : '';
        if (result3 !== null) {
          var result4 = parse_s();
          if (result4 !== null) {
            var savedPos2 = pos;
            if (input.substr(pos, 4) === "long") {
              var result10 = "long";
              pos += 4;
            } else {
              var result10 = null;
              if (reportMatchFailures) {
                matchFailed("\"long\"");
              }
            }
            if (result10 !== null) {
              var result11 = parse_s();
              if (result11 !== null) {
                if (input.substr(pos, 4) === "long") {
                  var result12 = "long";
                  pos += 4;
                } else {
                  var result12 = null;
                  if (reportMatchFailures) {
                    matchFailed("\"long\"");
                  }
                }
                if (result12 !== null) {
                  var result9 = [result10, result11, result12];
                } else {
                  var result9 = null;
                  pos = savedPos2;
                }
              } else {
                var result9 = null;
                pos = savedPos2;
              }
            } else {
              var result9 = null;
              pos = savedPos2;
            }
            if (result9 !== null) {
              var result5 = result9;
            } else {
              if (input.substr(pos, 4) === "long") {
                var result8 = "long";
                pos += 4;
              } else {
                var result8 = null;
                if (reportMatchFailures) {
                  matchFailed("\"long\"");
                }
              }
              if (result8 !== null) {
                var result5 = result8;
              } else {
                if (input.substr(pos, 5) === "short") {
                  var result7 = "short";
                  pos += 5;
                } else {
                  var result7 = null;
                  if (reportMatchFailures) {
                    matchFailed("\"short\"");
                  }
                }
                if (result7 !== null) {
                  var result5 = result7;
                } else {
                  if (input.substr(pos, 4) === "byte") {
                    var result6 = "byte";
                    pos += 4;
                  } else {
                    var result6 = null;
                    if (reportMatchFailures) {
                      matchFailed("\"byte\"");
                    }
                  }
                  if (result6 !== null) {
                    var result5 = result6;
                  } else {
                    var result5 = null;;
                  };
                };
              };
            }
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ScopedNameList() {
        var cacheKey = 'ScopedNameList@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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();
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ScopedNameListRest() {
        var cacheKey = 'ScopedNameListRest@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_w();
        if (result3 !== null) {
          if (input.substr(pos, 1) === ",") {
            var result4 = ",";
            pos += 1;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              matchFailed("\",\"");
            }
          }
          if (result4 !== null) {
            var result5 = parse_w();
            if (result5 !== null) {
              var result6 = parse_ScopedName();
              if (result6 !== null) {
                var result1 = [result3, result4, result5, result6];
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ScopedName() {
        var cacheKey = 'ScopedName@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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
        };
        return result0;
      }
      
      function parse_AbsoluteScopedName() {
        var cacheKey = 'AbsoluteScopedName@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 2) === "::") {
          var result3 = "::";
          pos += 2;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"::\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_RelativeScopedName();
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_RelativeScopedName() {
        var cacheKey = 'RelativeScopedName@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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();
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ScopedNameRest() {
        var cacheKey = 'ScopedNameRest@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 2) === "::") {
          var result3 = "::";
          pos += 2;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"::\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_identifier();
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_BooleanLiteral() {
        var cacheKey = 'BooleanLiteral@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        if (input.substr(pos, 4) === "true") {
          var result4 = "true";
          pos += 4;
        } else {
          var result4 = null;
          if (reportMatchFailures) {
            matchFailed("\"true\"");
          }
        }
        if (result4 !== null) {
          var result1 = result4;
        } else {
          if (input.substr(pos, 5) === "false") {
            var result3 = "false";
            pos += 5;
          } else {
            var result3 = null;
            if (reportMatchFailures) {
              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
        };
        return result0;
      }
      
      function parse_Nullable() {
        var cacheKey = 'Nullable@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        if (input.substr(pos, 1) === "?") {
          var result3 = "?";
          pos += 1;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            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
        };
        return result0;
      }
      
      function parse_ReturnType() {
        var cacheKey = 'ReturnType@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        if (input.substr(pos, 4) === "void") {
          var result4 = "void";
          pos += 4;
        } else {
          var result4 = null;
          if (reportMatchFailures) {
            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
        };
        return result0;
      }
      
      function parse_definitions() {
        var cacheKey = 'definitions@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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();
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_definition() {
        var cacheKey = 'definition@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var result9 = parse_partialinterface();
        if (result9 !== null) {
          var result1 = result9;
        } else {
          var result8 = parse_module();
          if (result8 !== null) {
            var result1 = result8;
          } else {
            var result7 = parse_interface();
            if (result7 !== null) {
              var result1 = result7;
            } else {
              var result6 = parse_dictionary();
              if (result6 !== null) {
                var result1 = result6;
              } else {
                var result5 = parse_typedef();
                if (result5 !== null) {
                  var result1 = result5;
                } else {
                  var result4 = parse_exception();
                  if (result4 !== null) {
                    var result1 = result4;
                  } else {
                    var result3 = parse_implements();
                    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
        };
        return result0;
      }
      
      function parse_partialinterface() {
        var cacheKey = 'partialinterface@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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) {
            if (input.substr(pos, 7) === "partial") {
              var result5 = "partial";
              pos += 7;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\"partial\"");
              }
            }
            if (result5 !== null) {
              var result6 = parse_s();
              if (result6 !== null) {
                if (input.substr(pos, 9) === "interface") {
                  var result7 = "interface";
                  pos += 9;
                } else {
                  var result7 = null;
                  if (reportMatchFailures) {
                    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;
                        } else {
                          var result11 = null;
                          if (reportMatchFailures) {
                            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;
                                } else {
                                  var result15 = null;
                                  if (reportMatchFailures) {
                                    matchFailed("\"}\"");
                                  }
                                }
                                if (result15 !== null) {
                                  var result16 = parse_w();
                                  if (result16 !== null) {
                                    if (input.substr(pos, 1) === ";") {
                                      var result17 = ";";
                                      pos += 1;
                                    } else {
                                      var result17 = null;
                                      if (reportMatchFailures) {
                                        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];
                                      } else {
                                        var result1 = null;
                                        pos = savedPos1;
                                      }
                                    } else {
                                      var result1 = null;
                                      pos = savedPos1;
                                    }
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_module() {
        var cacheKey = 'module@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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) {
            if (input.substr(pos, 6) === "module") {
              var result5 = "module";
              pos += 6;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                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;
                    } else {
                      var result9 = null;
                      if (reportMatchFailures) {
                        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;
                            } 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;
                                } else {
                                  var result15 = null;
                                  if (reportMatchFailures) {
                                    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];
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_implements() {
        var cacheKey = 'implements@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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) {
                if (input.substr(pos, 10) === "implements") {
                  var result7 = "implements";
                  pos += 10;
                } else {
                  var result7 = null;
                  if (reportMatchFailures) {
                    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;
                        } else {
                          var result11 = null;
                          if (reportMatchFailures) {
                            matchFailed("\";\"");
                          }
                        }
                        if (result11 !== null) {
                          var result12 = parse_w();
                          if (result12 !== null) {
                            var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12];
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_interface() {
        var cacheKey = 'interface@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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) {
            if (input.substr(pos, 9) === "interface") {
              var result5 = "interface";
              pos += 9;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                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;
                        } else {
                          var result11 = null;
                          if (reportMatchFailures) {
                            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;
                                } else {
                                  var result15 = null;
                                  if (reportMatchFailures) {
                                    matchFailed("\"}\"");
                                  }
                                }
                                if (result15 !== null) {
                                  var result16 = parse_w();
                                  if (result16 !== null) {
                                    if (input.substr(pos, 1) === ";") {
                                      var result17 = ";";
                                      pos += 1;
                                    } else {
                                      var result17 = null;
                                      if (reportMatchFailures) {
                                        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];
                                      } else {
                                        var result1 = null;
                                        pos = savedPos1;
                                      }
                                    } else {
                                      var result1 = null;
                                      pos = savedPos1;
                                    }
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ifInheritance() {
        var cacheKey = 'ifInheritance@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 1) === ":") {
          var result3 = ":";
          pos += 1;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\":\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_w();
          if (result4 !== null) {
            var result5 = parse_ScopedNameList();
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ifMember() {
        var cacheKey = 'ifMember@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_const() {
        var cacheKey = 'const@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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) {
            if (input.substr(pos, 5) === "const") {
              var result5 = "const";
              pos += 5;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                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;
                        } else {
                          var result11 = null;
                          if (reportMatchFailures) {
                            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;
                                } else {
                                  var result15 = null;
                                  if (reportMatchFailures) {
                                    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];
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_constExpr() {
        var cacheKey = 'constExpr@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var result5 = parse_BooleanLiteral();
        if (result5 !== null) {
          var result1 = result5;
        } else {
          var result4 = parse_float();
          if (result4 !== null) {
            var result1 = result4;
          } else {
            var result3 = parse_integer();
            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
        };
        return result0;
      }
      
      function parse_attrOrOp() {
        var cacheKey = 'attrOrOp@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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
        };
        return result0;
      }
      
      function parse_Stringifier() {
        var cacheKey = 'Stringifier@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 11) === "stringifier") {
          var result3 = "stringifier";
          pos += 11;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            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;
                } else {
                  var result6 = null;
                  if (reportMatchFailures) {
                    matchFailed("\";\"");
                  }
                }
                if (result6 !== null) {
                  var result5 = result6;
                } else {
                  var result5 = null;;
                };
              };
            }
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_Attribute() {
        var cacheKey = 'Attribute@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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;
            if (input.substr(pos, 8) === "readonly") {
              var result21 = "readonly";
              pos += 8;
            } else {
              var result21 = null;
              if (reportMatchFailures) {
                matchFailed("\"readonly\"");
              }
            }
            if (result21 !== null) {
              var result22 = parse_s();
              if (result22 !== null) {
                var result20 = [result21, result22];
              } else {
                var result20 = null;
                pos = savedPos2;
              }
            } else {
              var result20 = null;
              pos = savedPos2;
            }
            var result5 = result20 !== null ? result20 : '';
            if (result5 !== null) {
              if (input.substr(pos, 9) === "attribute") {
                var result6 = "attribute";
                pos += 9;
              } else {
                var result6 = null;
                if (reportMatchFailures) {
                  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;
                                  } else {
                                    var result16 = null;
                                    if (reportMatchFailures) {
                                      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];
                                    } else {
                                      var result1 = null;
                                      pos = savedPos1;
                                    }
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_GetRaises() {
        var cacheKey = 'GetRaises@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 9) === "getraises") {
          var result3 = "getraises";
          pos += 9;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"getraises\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_w();
          if (result4 !== null) {
            if (input.substr(pos, 1) === "(") {
              var result5 = "(";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\"(\"");
              }
            }
            if (result5 !== null) {
              var result6 = parse_ScopedNameList();
              if (result6 !== null) {
                if (input.substr(pos, 1) === ")") {
                  var result7 = ")";
                  pos += 1;
                } else {
                  var result7 = null;
                  if (reportMatchFailures) {
                    matchFailed("\")\"");
                  }
                }
                if (result7 !== null) {
                  var result1 = [result3, result4, result5, result6, result7];
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_SetRaises() {
        var cacheKey = 'SetRaises@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 9) === "setraises") {
          var result3 = "setraises";
          pos += 9;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"setraises\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_w();
          if (result4 !== null) {
            if (input.substr(pos, 1) === "(") {
              var result5 = "(";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\"(\"");
              }
            }
            if (result5 !== null) {
              var result6 = parse_ScopedNameList();
              if (result6 !== null) {
                if (input.substr(pos, 1) === ")") {
                  var result7 = ")";
                  pos += 1;
                } else {
                  var result7 = null;
                  if (reportMatchFailures) {
                    matchFailed("\")\"");
                  }
                }
                if (result7 !== null) {
                  var result1 = [result3, result4, result5, result6, result7];
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_Operation() {
        var cacheKey = 'Operation@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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];
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_Qualifiers() {
        var cacheKey = 'Qualifiers@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_w();
        if (result3 !== null) {
          if (input.substr(pos, 6) === "static") {
            var result7 = "static";
            pos += 6;
          } else {
            var result7 = null;
            if (reportMatchFailures) {
              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 (result5 !== null) {
              var result4 = result5;
            } else {
              var result4 = null;;
            };
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_Special() {
        var cacheKey = 'Special@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_w();
        if (result3 !== null) {
          if (input.substr(pos, 6) === "getter") {
            var result10 = "getter";
            pos += 6;
          } else {
            var result10 = null;
            if (reportMatchFailures) {
              matchFailed("\"getter\"");
            }
          }
          if (result10 !== null) {
            var result4 = result10;
          } else {
            if (input.substr(pos, 6) === "setter") {
              var result9 = "setter";
              pos += 6;
            } else {
              var result9 = null;
              if (reportMatchFailures) {
                matchFailed("\"setter\"");
              }
            }
            if (result9 !== null) {
              var result4 = result9;
            } else {
              if (input.substr(pos, 7) === "creator") {
                var result8 = "creator";
                pos += 7;
              } else {
                var result8 = null;
                if (reportMatchFailures) {
                  matchFailed("\"creator\"");
                }
              }
              if (result8 !== null) {
                var result4 = result8;
              } else {
                if (input.substr(pos, 7) === "deleter") {
                  var result7 = "deleter";
                  pos += 7;
                } else {
                  var result7 = null;
                  if (reportMatchFailures) {
                    matchFailed("\"deleter\"");
                  }
                }
                if (result7 !== null) {
                  var result4 = result7;
                } else {
                  if (input.substr(pos, 12) === "legacycaller") {
                    var result6 = "legacycaller";
                    pos += 12;
                  } else {
                    var result6 = null;
                    if (reportMatchFailures) {
                      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];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_OperationRest() {
        var cacheKey = 'OperationRest@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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;
                } else {
                  var result7 = null;
                  if (reportMatchFailures) {
                    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;
                        } else {
                          var result11 = null;
                          if (reportMatchFailures) {
                            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;
                                } else {
                                  var result15 = null;
                                  if (reportMatchFailures) {
                                    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];
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_Arguments() {
        var cacheKey = 'Arguments@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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();
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ArgumentsRest() {
        var cacheKey = 'ArgumentsRest@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_w();
        if (result3 !== null) {
          if (input.substr(pos, 1) === ",") {
            var result4 = ",";
            pos += 1;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              matchFailed("\",\"");
            }
          }
          if (result4 !== null) {
            var result5 = parse_w();
            if (result5 !== null) {
              var result6 = parse_Argument();
              if (result6 !== null) {
                var result1 = [result3, result4, result5, result6];
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_Argument() {
        var cacheKey = 'Argument@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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) {
            if (input.substr(pos, 2) === "in") {
              var result15 = "in";
              pos += 2;
            } else {
              var result15 = null;
              if (reportMatchFailures) {
                matchFailed("\"in\"");
              }
            }
            var result5 = result15 !== null ? result15 : '';
            if (result5 !== null) {
              var result6 = parse_w();
              if (result6 !== null) {
                if (input.substr(pos, 8) === "optional") {
                  var result14 = "optional";
                  pos += 8;
                } else {
                  var result14 = null;
                  if (reportMatchFailures) {
                    matchFailed("\"optional\"");
                  }
                }
                var result7 = result14 !== null ? result14 : '';
                if (result7 !== null) {
                  var result8 = parse_w();
                  if (result8 !== null) {
                    var result9 = parse_type();
                    if (result9 !== null) {
                      if (input.substr(pos, 3) === "...") {
                        var result13 = "...";
                        pos += 3;
                      } else {
                        var result13 = null;
                        if (reportMatchFailures) {
                          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];
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_Raises() {
        var cacheKey = 'Raises@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 6) === "raises") {
          var result3 = "raises";
          pos += 6;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"raises\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_s();
          if (result4 !== null) {
            if (input.substr(pos, 1) === "(") {
              var result5 = "(";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                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;
                    } else {
                      var result9 = null;
                      if (reportMatchFailures) {
                        matchFailed("\")\"");
                      }
                    }
                    if (result9 !== null) {
                      var result1 = [result3, result4, result5, result6, result7, result8, result9];
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_dictionary() {
        var cacheKey = 'dictionary@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 10) === "dictionary") {
          var result3 = "dictionary";
          pos += 10;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            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;
                    } else {
                      var result9 = null;
                      if (reportMatchFailures) {
                        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;
                            } 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;
                                } else {
                                  var result15 = null;
                                  if (reportMatchFailures) {
                                    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];
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_dictionaryMember() {
        var cacheKey = 'dictionaryMember@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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;
                        } else {
                          var result11 = null;
                          if (reportMatchFailures) {
                            matchFailed("\";\"");
                          }
                        }
                        if (result11 !== null) {
                          var result12 = parse_w();
                          if (result12 !== null) {
                            var result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12];
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_defaultValue() {
        var cacheKey = 'defaultValue@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 1) === "=") {
          var result3 = "=";
          pos += 1;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            matchFailed("\"=\"");
          }
        }
        if (result3 !== null) {
          var result4 = parse_w();
          if (result4 !== null) {
            var result5 = parse_constExpr();
            if (result5 !== null) {
              var result1 = [result3, result4, result5];
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } else {
          var result1 = null;
          pos = savedPos1;
        }
        var result2 = result1 !== null
          ? (function(value) { return value; })(result1[2])
          : null;
        if (result2 !== null) {
          var result0 = result2;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_typedef() {
        var cacheKey = 'typedef@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        if (input.substr(pos, 7) === "typedef") {
          var result3 = "typedef";
          pos += 7;
        } else {
          var result3 = null;
          if (reportMatchFailures) {
            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;
                    } else {
                      var result9 = null;
                      if (reportMatchFailures) {
                        matchFailed("\";\"");
                      }
                    }
                    if (result9 !== null) {
                      var result10 = parse_w();
                      if (result10 !== null) {
                        var result1 = [result3, result4, result5, result6, result7, result8, result9, result10];
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_exception() {
        var cacheKey = 'exception@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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) {
            if (input.substr(pos, 9) === "exception") {
              var result5 = "exception";
              pos += 9;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                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 (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;
                                } else {
                                  var result15 = null;
                                  if (reportMatchFailures) {
                                    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];
                                  } else {
                                    var result1 = null;
                                    pos = savedPos1;
                                  }
                                } else {
                                  var result1 = null;
                                  pos = savedPos1;
                                }
                              } else {
                                var result1 = null;
                                pos = savedPos1;
                              }
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_exMember() {
        var cacheKey = 'exMember@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_field() {
        var cacheKey = 'field@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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;
                    } else {
                      var result9 = null;
                      if (reportMatchFailures) {
                        matchFailed("\";\"");
                      }
                    }
                    if (result9 !== null) {
                      var result10 = parse_w();
                      if (result10 !== null) {
                        var result1 = [result3, result4, result5, result6, result7, result8, result9, result10];
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_extendedAttributeList() {
        var cacheKey = 'extendedAttributeList@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_w();
        if (result3 !== null) {
          if (input.substr(pos, 1) === "[") {
            var result4 = "[";
            pos += 1;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              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;
                  } else {
                    var result8 = null;
                    if (reportMatchFailures) {
                      matchFailed("\"]\"");
                    }
                  }
                  if (result8 !== null) {
                    var result9 = parse_w();
                    if (result9 !== null) {
                      var result1 = [result3, result4, result5, result6, result7, result8, result9];
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ExtAttrs() {
        var cacheKey = 'ExtAttrs@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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();
          }
          if (result4 !== null) {
            var result1 = [result3, result4];
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ExtAttrsRest() {
        var cacheKey = 'ExtAttrsRest@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_w();
        if (result3 !== null) {
          if (input.substr(pos, 1) === ",") {
            var result4 = ",";
            pos += 1;
          } else {
            var result4 = null;
            if (reportMatchFailures) {
              matchFailed("\",\"");
            }
          }
          if (result4 !== null) {
            var result5 = parse_w();
            if (result5 !== null) {
              var result6 = parse_ExtAttr();
              if (result6 !== null) {
                var result1 = [result3, result4, result5, result6];
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } 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
        };
        return result0;
      }
      
      function parse_ExtAttr() {
        var cacheKey = 'ExtAttr@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        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;;
              };
            };
          };
        }
        var result2 = result1 !== null
          ? (function(ea) { return ea; })(result1)
          : null;
        if (result2 !== null) {
          var result0 = result2;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_ExtAttrNoArg() {
        var cacheKey = 'ExtAttrNoArg@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var result1 = parse_identifier();
        var result2 = result1 !== null
          ? (function(name) {return { name: name }; })(result1)
          : null;
        if (result2 !== null) {
          var result0 = result2;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_ExtAttrNameValue() {
        var cacheKey = 'ExtAttrNameValue@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_identifier();
        if (result3 !== null) {
          var result4 = parse_w();
          if (result4 !== null) {
            if (input.substr(pos, 1) === "=") {
              var result5 = "=";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\"=\"");
              }
            }
            if (result5 !== null) {
              var result6 = parse_w();
              if (result6 !== null) {
                var result7 = parse_ScopedName();
                if (result7 !== null) {
                  var result1 = [result3, result4, result5, result6, result7];
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } else {
          var result1 = null;
          pos = savedPos1;
        }
        var result2 = result1 !== null
          ? (function(name, value) {return { name: name, value: value }; })(result1[0], result1[4])
          : null;
        if (result2 !== null) {
          var result0 = result2;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function parse_ExtAttrNamedArgList() {
        var cacheKey = 'ExtAttrNamedArgList@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_identifier();
        if (result3 !== null) {
          var result4 = parse_w();
          if (result4 !== null) {
            if (input.substr(pos, 1) === "=") {
              var result5 = "=";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\"=\"");
              }
            }
            if (result5 !== null) {
              var result6 = parse_w();
              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 result14 = parse_Arguments();
                        var result11 = result14 !== null ? result14 : '';
                        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 result1 = [result3, result4, result5, result6, result7, result8, result9, result10, result11, result12, result13];
                            } else {
                              var result1 = null;
                              pos = savedPos1;
                            }
                          } else {
                            var result1 = null;
                            pos = savedPos1;
                          }
                        } else {
                          var result1 = null;
                          pos = savedPos1;
                        }
                      } else {
                        var result1 = null;
                        pos = savedPos1;
                      }
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } else {
          var result1 = null;
          pos = savedPos1;
        }
        var result2 = result1 !== null
          ? (function(name, value, args) {return { name: name, value: value, arguments: args }; })(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
        };
        return result0;
      }
      
      function parse_ExtAttrArgList() {
        var cacheKey = 'ExtAttrArgList@' + pos;
        var cachedResult = cache[cacheKey];
        if (cachedResult) {
          pos = cachedResult.nextPos;
          return cachedResult.result;
        }
        
        
        var savedPos0 = pos;
        var savedPos1 = pos;
        var result3 = parse_identifier();
        if (result3 !== null) {
          var result4 = parse_w();
          if (result4 !== null) {
            if (input.substr(pos, 1) === "(") {
              var result5 = "(";
              pos += 1;
            } else {
              var result5 = null;
              if (reportMatchFailures) {
                matchFailed("\"(\"");
              }
            }
            if (result5 !== null) {
              var result6 = parse_w();
              if (result6 !== null) {
                var result10 = parse_Arguments();
                var result7 = result10 !== null ? result10 : '';
                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 result1 = [result3, result4, result5, result6, result7, result8, result9];
                    } else {
                      var result1 = null;
                      pos = savedPos1;
                    }
                  } else {
                    var result1 = null;
                    pos = savedPos1;
                  }
                } else {
                  var result1 = null;
                  pos = savedPos1;
                }
              } else {
                var result1 = null;
                pos = savedPos1;
              }
            } else {
              var result1 = null;
              pos = savedPos1;
            }
          } else {
            var result1 = null;
            pos = savedPos1;
          }
        } else {
          var result1 = null;
          pos = savedPos1;
        }
        var result2 = result1 !== null
          ? (function(name, args) {return { name: name, arguments: args }; })(result1[0], result1[4])
          : null;
        if (result2 !== null) {
          var result0 = result2;
        } else {
          var result0 = null;
          pos = savedPos0;
        }
        
        
        
        cache[cacheKey] = {
          nextPos: pos,
          result:  result0
        };
        return result0;
      }
      
      function buildErrorMessage() {
        function buildExpected(failuresExpected) {
          failuresExpected.sort();
          
          var lastFailure = null;
          var failuresExpectedUnique = [];
          for (var i = 0; i < failuresExpected.length; i++) {
            if (failuresExpected[i] !== lastFailure) {
              failuresExpectedUnique.push(failuresExpected[i]);
              lastFailure = failuresExpected[i];
            }
          }
          
          switch (failuresExpectedUnique.length) {
            case 0:
              return 'end of input';
            case 1:
              return failuresExpectedUnique[0];
            default:
              return failuresExpectedUnique.slice(0, failuresExpectedUnique.length - 1).join(', ')
                + ' or '
                + failuresExpectedUnique[failuresExpectedUnique.length - 1];
          }
        }
        
        var expected = buildExpected(rightmostMatchFailuresExpected);
        var actualPos = Math.max(pos, rightmostMatchFailuresPos);
        var actual = actualPos < input.length
          ? quote(input.charAt(actualPos))
          : 'end of input';
        
        return 'Expected ' + expected + ' but ' + actual + ' found.';
      }
      
      function computeErrorPosition() {
        /*
         * The first idea was to use |String.split| to break the input up to the
         * error position along newlines and derive the line and column from
         * there. However IE's |split| implementation is so broken that it was
         * enough to prevent it.
         */
        
        var line = 1;
        var column = 1;
        var seenCR = false;
        
        for (var i = 0; i <  rightmostMatchFailuresPos; i++) {
          var ch = input.charAt(i);
          if (ch === '\n') {
            if (!seenCR) { line++; }
            column = 1;
            seenCR = false;
          } else if (ch === '\r' | ch === '\u2028' || ch === '\u2029') {
            line++;
            column = 1;
            seenCR = true;
          } else {
            column++;
            seenCR = false;
          }
        }
        
        return { line: line, column: column };
      }
      
      
      
      var result = parseFunctions[startRule]();
      
      /*
       * The parser is now in one of the following three states:
       *
       * 1. The parser successfully parsed the whole input.
       *
       *    - |result !== null|
       *    - |pos === input.length|
       *    - |rightmostMatchFailuresExpected| may or may not contain something
       *
       * 2. The parser successfully parsed only a part of the input.
       *
       *    - |result !== null|
       *    - |pos < input.length|
       *    - |rightmostMatchFailuresExpected| may or may not contain something
       *
       * 3. The parser did not successfully parse any part of the input.
       *
       *   - |result === null|
       *   - |pos === 0|
       *   - |rightmostMatchFailuresExpected| contains at least one failure
       *
       * All code following this comment (including called functions) must
       * handle these states.
       */
      if (result === null || pos !== input.length) {
        var errorPosition = computeErrorPosition();
        throw new this.SyntaxError(
          buildErrorMessage(),
          errorPosition.line,
          errorPosition.column
        );
      }
      
      return result;
    },
    
    /* Returns the parser source code. */
    toSource: function() { return this._source; }
  };
  
  /* Thrown when a parser encounters a syntax error. */
  
  result.SyntaxError = function(message, line, column) {
    this.name = 'SyntaxError';
    this.message = message;
    this.line = line;
    this.column = column;
  };
  
  result.SyntaxError.prototype = Error.prototype;
  
  return result;
})();
