/**
 * Here's the main parser for our expression parser. It's a pared down
 * Javascript parser with a whole lot of rules removed, leaving only
 * rules for parsing literals (i.e. string literal,numeric literal,
 * boolean literal, array literal, object literal and null literal),
 * identifiers, and expressions (i.e. call expression, member expression,
 * array expression and object expression).
 *
 * For more information see:
 * https://peggyjs.org/documentation.html
 * https://github.com/peggyjs/peggy/blob/main/examples/javascript.pegjs
 */
export declare const GRAMMAR = "{{\n    var TYPES_TO_PROPERTY_NAMES = {\n      CallExpression:   \"callee\",\n      MemberExpression: \"object\",\n    };\n  \n    function extractOptional(optional, index) {\n      return optional ? optional[index] : null;\n    };\n  \n    function extractList(list, index) {\n      return list.map(function(element) { return element[index]; });\n    };\n  \n    function buildList(head, tail, index) {\n      return [head].concat(extractList(tail, index));\n    };\n  \n    function optionalList(value) {\n      return value !== null ? value : [];\n    };\n  }}\n  \n  Start\n    = __ program:Program __ { return program; };\n  \n  SourceCharacter\n    = .;\n  \n  WhiteSpace\n    = \"\\t\"\n    / \"\\v\"\n    / \"\\f\"\n    / \" \"\n    / \"\\u00A0\"\n    / \"\\uFEFF\";\n  \n  Identifier\n    = !ReservedWord name:IdentifierName { return name; };\n  \n  IdentifierName\n    = head:IdentifierStart tail:IdentifierPart* {\n        return {\n          type: \"Identifier\",\n          name: head + tail.join(\"\")\n        };\n      };\n  \n  IdentifierStart\n    = UnicodeLetter\n    / \"$\"\n    / \"_\";\n  \n  IdentifierPart\n    = IdentifierStart\n    / Nd\n    / \"\\u200C\"\n    / \"\\u200D\";\n  \n  UnicodeLetter\n    = Lu\n    / Ll;\n  \n  ReservedWord\n    = NullToken\n    / TrueToken\n    / FalseToken;\n  \n  Literal\n    = NullLiteral\n    / BooleanLiteral\n    / NumericLiteral\n    / StringLiteral;\n  \n  NullLiteral\n    = NullToken { return { type: \"NullLiteral\", value: null }; };\n  \n  BooleanLiteral\n    = TrueToken { return { type: \"BooleanLiteral\", value: true  }; }\n    / FalseToken { return { type: \"BooleanLiteral\", value: false }; };\n  \n  NumericLiteral\n    = literal:DecimalLiteral !(IdentifierStart / DecimalDigit) {\n        return literal;\n      };\n  \n  DecimalLiteral\n    = DecimalIntegerLiteral \".\" DecimalDigit* {\n        return { type: \"NumericLiteral\", value: parseFloat(text()) };\n      }\n    / \".\" DecimalDigit+ {\n        return { type: \"NumericLiteral\", value: parseFloat(text()) };\n      }\n    / DecimalIntegerLiteral {\n        return { type: \"NumericLiteral\", value: parseFloat(text()) };\n      };\n  \n  DecimalIntegerLiteral\n    = \"0\"\n    / NonZeroDigit DecimalDigit*;\n  \n  DecimalDigit\n    = [0-9];\n  \n  NonZeroDigit\n    = [1-9];\n  \n  StringLiteral\n    = '\"' chars:DoubleStringCharacter* '\"' {\n        return { type: \"StringLiteral\", value: chars.join(\"\") };\n      }\n    / \"'\" chars:SingleStringCharacter* \"'\" {\n        return { type: \"StringLiteral\", value: chars.join(\"\") };\n      };\n  \n  DoubleStringCharacter\n    = !('\"' / \"\\\\\") SourceCharacter { return text(); };\n  \n  SingleStringCharacter\n    = !(\"'\" / \"\\\\\") SourceCharacter { return text(); };\n  \n  SingleEscapeCharacter\n    = \"'\"\n    / '\"';\n  \n  Ll = [a-z];\n  Lu = [A-Z];\n  Nd = [0-9];\n  \n  FalseToken = \"false\" !IdentifierPart;\n  TrueToken = \"true\" !IdentifierPart;\n  NullToken = \"null\" !IdentifierPart;\n  \n  __ = WhiteSpace*;\n  \n  PrimaryExpression\n    = Identifier\n    / Literal\n    / ArrayExpression\n    / ObjectExpression\n    / \"(\" __ expression:Expression __ \")\" { return expression; };\n  \n  ArrayExpression\n    = \"[\" __ \"]\" { return { type: \"ArrayExpression\", elements: [] }; }\n    / \"[\" __ elements:ElementList __ \"]\" {\n        return {\n          type: \"ArrayExpression\",\n          elements: elements\n        };\n      };\n  \n  ElementList\n    = head:(\n        element:Expression {\n          return element;\n        }\n      )\n      tail:(\n        __ \",\" __ element:Expression {\n          return element;\n        }\n      )*\n      { return Array.prototype.concat.apply(head, tail); };\n  \n  ObjectExpression\n    = \"{\" __ \"}\" { return { type: \"ObjectExpression\", properties: [] }; }\n    / \"{\" __ properties:PropertyNameAndValueList __ \"}\" {\n         return { type: \"ObjectExpression\", properties: properties };\n       }\n    / \"{\" __ properties:PropertyNameAndValueList __ \",\" __ \"}\" {\n         return { type: \"ObjectExpression\", properties: properties };\n       };\n  PropertyNameAndValueList\n    = head:PropertyAssignment tail:(__ \",\" __ PropertyAssignment)* {\n        return buildList(head, tail, 3);\n      };\n  \n  PropertyAssignment\n    = key:PropertyName __ \":\" __ value:Expression {\n        return { type: \"PropertyAssignment\", key: key, value: value, kind: \"init\" };\n      };\n  \n  PropertyName\n    = IdentifierName\n    / StringLiteral\n    / NumericLiteral;\n  \n  Node\n    = ArrayExpression \n    / BooleanLiteral \n    / CallExpression \n    / Identifier \n    / MemberExpression \n    / NumericLiteral \n    / ObjectExpression \n    / PropertyAssignment \n    / StringLiteral\n  \n  MemberExpression\n    = head:(PrimaryExpression)\n      tail:(\n          __ \"[\" __ property:Expression __ \"]\" {\n            return { property: property, computed: true };\n          }\n        / __ \".\" __ property:IdentifierName {\n            return { property: property, computed: false };\n          }\n      )*\n      {\n        return tail.reduce(function(result, element) {\n          return {\n            type: \"MemberExpression\",\n            object: result,\n            property: element.property,\n            computed: element.computed\n          };\n        }, head);\n      };\n  \n  CallExpression\n    = head:(\n        callee:MemberExpression __ args:Arguments {\n          return { type: \"CallExpression\", callee: callee, arguments: args };\n        }\n      )\n      tail:(\n          __ args:Arguments {\n            return { type: \"CallExpression\", arguments: args };\n          }\n        / __ \"[\" __ property:Expression __ \"]\" {\n            return {\n              type: \"MemberExpression\",\n              property: property,\n              computed: true\n            };\n          }\n        / __ \".\" __ property:IdentifierName {\n            return {\n              type: \"MemberExpression\",\n              property: property,\n              computed: false\n            };\n          }\n      )*\n      {\n        return tail.reduce(function(result, element) {\n          element[TYPES_TO_PROPERTY_NAMES[element.type]] = result;\n  \n          return element;\n        }, head);\n      };\n  \n  Arguments\n    = \"(\" __ args:(ArgumentList __)? \")\" {\n        return optionalList(extractOptional(args, 0));\n      };\n  \n  ArgumentList\n    = head:Expression tail:(__ \",\" __ Expression)* {\n        return buildList(head, tail, 3);\n      };\n  \n  Expression\n    = CallExpression\n    / MemberExpression;\n  \n  ExpressionStatement\n    = expression:Expression {\n        return {\n          type: \"ExpressionStatement\",\n          expression: expression\n        };\n      };\n  \n  Program\n    = exp:ExpressionStatement {\n        return {\n          type: \"Program\",\n          body: exp\n        };\n      };";
