// Generated automatically by nearley, version 2.20.1
// http://github.com/Hardmath123/nearley
(function () {
function id(x) { return x[0]; }


// Because of unquoted strings, parsing can be ambiguous.
// It is more efficient to have the parser extract string
// and post-process it to retrieve numbers
function parseValue (str) {
  if (str === 'true') return { type: 'boolean', value: true }
  if (str === 'false') return { type: 'boolean', value: false }
  const suffixes = "bslfdi"
  const suffixToType = { 'b': 'byte', 's': 'short', 'l': 'long', 'f': 'float', 'd': 'double', 'i': 'int' }
  const lastC = str.charAt(str.length - 1).toLowerCase()
  if (suffixes.indexOf(lastC) !== -1) {
    const v = parseFloat(str.substring(0, str.length - 1))
    if (!isNaN(v)) return { value: v, type: suffixToType[lastC]}
    return { value: str, type: 'string' }
  }
  // When no letter is used and Minecraft can't tell the type from context,
  // it assumes double if there's a decimal point, int if there's no decimal
  // point and the size fits within 32 bits, or string if neither is true.
  // https://minecraft.gamepedia.com/Commands#Data_tags
  const v = parseFloat(str)
  const decimal = str.includes('.')
  const isInt32 = (v >> 0) === v
  if (!isNaN(str) && (decimal || isInt32)) return { value: v, type: decimal ? 'double' : 'int'}
  return { value: str, type: 'string' }
}

function extractPair(kv, output) {
  if (kv[0] !== undefined) {
    output[kv[0]] = kv[1]
  }
}

function extractObject(d) {
  let output = {}
  extractPair(d[2], output)
  for (let i in d[3]) {
    extractPair(d[3][i][3], output)
  }
  return { type: 'compound', value: output }
}

function extractTypedArray (d) {
  let output = [d[6]]
  for (let i in d[7]) {
    output.push(d[7][i][3])
  }
  const type = {'B': 'byteArray', 'I': 'intArray', 'L': 'longArray'}[d[2]]
  return { type, value: { type: output[0].type, value: output.map(x => x.value) } }
}

function extractArray (d) {
  let output = [d[2]]
  for (let i in d[3]) {
    output.push(d[3][i][3])
  }
  return { type: 'list', value: { type: output[0].type, value: output.map(x => x.value) } }
}

function extractArrayPair (d) {
  let output = []
  extractPair(d[2], output)
  for (let i in d[3]) {
    extractPair(d[3][i][3], output)
  }
  return { type: 'list', value: { type: output[0].type, value: output.map(x => x.value) } }
}

var grammar = {
    Lexer: undefined,
    ParserRules: [
    {"name": "_$ebnf$1", "symbols": []},
    {"name": "_$ebnf$1", "symbols": ["_$ebnf$1", "wschar"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "_", "symbols": ["_$ebnf$1"], "postprocess": function(d) {return null;}},
    {"name": "__$ebnf$1", "symbols": ["wschar"]},
    {"name": "__$ebnf$1", "symbols": ["__$ebnf$1", "wschar"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "__", "symbols": ["__$ebnf$1"], "postprocess": function(d) {return null;}},
    {"name": "wschar", "symbols": [/[ \t\n\v\f]/], "postprocess": id},
    {"name": "MAIN", "symbols": ["_", "JVALUE", "_"], "postprocess": (d) => d[1]},
    {"name": "JVALUE", "symbols": ["JOBJECT"], "postprocess": (d) => d[0]},
    {"name": "JVALUE", "symbols": [{"literal":"'"}, "_", "JOBJECT", "_", {"literal":"'"}], "postprocess": (d) => d[2]},
    {"name": "JVALUE", "symbols": ["JARRAY"], "postprocess": (d) => d[0]},
    {"name": "JVALUE", "symbols": ["STRING"], "postprocess": (d) => d[0]},
    {"name": "JVALUE$string$1", "symbols": [{"literal":"n"}, {"literal":"u"}, {"literal":"l"}, {"literal":"l"}], "postprocess": function joiner(d) {return d.join('');}},
    {"name": "JVALUE", "symbols": ["JVALUE$string$1"], "postprocess": (d) => null},
    {"name": "JOBJECT", "symbols": [{"literal":"{"}, "_", {"literal":"}"}], "postprocess": (d) => { return { type: 'compound', value: {} } }},
    {"name": "JOBJECT$ebnf$1", "symbols": []},
    {"name": "JOBJECT$ebnf$1$subexpression$1", "symbols": ["_", {"literal":","}, "_", "PAIR"]},
    {"name": "JOBJECT$ebnf$1", "symbols": ["JOBJECT$ebnf$1", "JOBJECT$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "JOBJECT$ebnf$2$subexpression$1", "symbols": ["_", {"literal":","}]},
    {"name": "JOBJECT$ebnf$2", "symbols": ["JOBJECT$ebnf$2$subexpression$1"], "postprocess": id},
    {"name": "JOBJECT$ebnf$2", "symbols": [], "postprocess": function(d) {return null;}},
    {"name": "JOBJECT", "symbols": [{"literal":"{"}, "_", "PAIR", "JOBJECT$ebnf$1", "JOBJECT$ebnf$2", {"literal":"}"}], "postprocess": extractObject},
    {"name": "JARRAY", "symbols": [{"literal":"["}, "_", {"literal":"]"}], "postprocess": (d) => { return { type: 'list', value: {} } }},
    {"name": "JARRAY$ebnf$1", "symbols": []},
    {"name": "JARRAY$ebnf$1$subexpression$1", "symbols": ["_", {"literal":","}, "_", "JVALUE"]},
    {"name": "JARRAY$ebnf$1", "symbols": ["JARRAY$ebnf$1", "JARRAY$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "JARRAY$ebnf$2$subexpression$1", "symbols": ["_", {"literal":","}]},
    {"name": "JARRAY$ebnf$2", "symbols": ["JARRAY$ebnf$2$subexpression$1"], "postprocess": id},
    {"name": "JARRAY$ebnf$2", "symbols": [], "postprocess": function(d) {return null;}},
    {"name": "JARRAY", "symbols": [{"literal":"["}, "_", /[BIL]/, "_", {"literal":";"}, "_", "JVALUE", "JARRAY$ebnf$1", "JARRAY$ebnf$2", "_", {"literal":"]"}], "postprocess": extractTypedArray},
    {"name": "JARRAY$ebnf$3", "symbols": []},
    {"name": "JARRAY$ebnf$3$subexpression$1", "symbols": ["_", {"literal":","}, "_", "JVALUE"]},
    {"name": "JARRAY$ebnf$3", "symbols": ["JARRAY$ebnf$3", "JARRAY$ebnf$3$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "JARRAY$ebnf$4$subexpression$1", "symbols": ["_", {"literal":","}]},
    {"name": "JARRAY$ebnf$4", "symbols": ["JARRAY$ebnf$4$subexpression$1"], "postprocess": id},
    {"name": "JARRAY$ebnf$4", "symbols": [], "postprocess": function(d) {return null;}},
    {"name": "JARRAY", "symbols": [{"literal":"["}, "_", "JVALUE", "JARRAY$ebnf$3", "JARRAY$ebnf$4", "_", {"literal":"]"}], "postprocess": extractArray},
    {"name": "JARRAY$ebnf$5", "symbols": []},
    {"name": "JARRAY$ebnf$5$subexpression$1", "symbols": ["_", {"literal":","}, "_", "PAIR"]},
    {"name": "JARRAY$ebnf$5", "symbols": ["JARRAY$ebnf$5", "JARRAY$ebnf$5$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "JARRAY$ebnf$6$subexpression$1", "symbols": ["_", {"literal":","}]},
    {"name": "JARRAY$ebnf$6", "symbols": ["JARRAY$ebnf$6$subexpression$1"], "postprocess": id},
    {"name": "JARRAY$ebnf$6", "symbols": [], "postprocess": function(d) {return null;}},
    {"name": "JARRAY", "symbols": [{"literal":"["}, "_", "PAIR", "JARRAY$ebnf$5", "JARRAY$ebnf$6", "_", {"literal":"]"}], "postprocess": extractArrayPair},
    {"name": "PAIR", "symbols": ["STRING", "_", {"literal":":"}, "_", "JVALUE"], "postprocess": (d) => [d[0].value, d[4]]},
    {"name": "STRING$ebnf$1", "symbols": []},
    {"name": "STRING$ebnf$1$subexpression$1", "symbols": [/[^\\"]/]},
    {"name": "STRING$ebnf$1$subexpression$1", "symbols": [{"literal":"\\"}, /["bfnrt\/\\]/]},
    {"name": "STRING$ebnf$1$subexpression$1$string$1", "symbols": [{"literal":"\\"}, {"literal":"u"}], "postprocess": function joiner(d) {return d.join('');}},
    {"name": "STRING$ebnf$1$subexpression$1", "symbols": ["STRING$ebnf$1$subexpression$1$string$1", /[a-fA-F0-9]/, /[a-fA-F0-9]/, /[a-fA-F0-9]/, /[a-fA-F0-9]/]},
    {"name": "STRING$ebnf$1", "symbols": ["STRING$ebnf$1", "STRING$ebnf$1$subexpression$1"], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "STRING", "symbols": [{"literal":"\""}, "STRING$ebnf$1", {"literal":"\""}], "postprocess": (d) => parseValue( JSON.parse(d.flat(3).map(b => b.replace('\n', '\\n')).join('')) )},
    {"name": "STRING$ebnf$2", "symbols": [/[^\"\'}\]:;,\s]/]},
    {"name": "STRING$ebnf$2", "symbols": ["STRING$ebnf$2", /[^\"\'}\]:;,\s]/], "postprocess": function arrpush(d) {return d[0].concat([d[1]]);}},
    {"name": "STRING", "symbols": ["STRING$ebnf$2"], "postprocess": (d) => parseValue(d[0].join(''))}
]
  , ParserStart: "MAIN"
}
if (typeof module !== 'undefined'&& typeof module.exports !== 'undefined') {
   module.exports = grammar;
} else {
   window.grammar = grammar;
}
})();
