{"_id":"reghex","_rev":"27-8c3d2e821becfba3584681ecf2672b44","time":{"0.1.0":"2020-05-19T19:07:14.014Z","created":"2020-05-20T13:19:36.490Z","0.0.1-security":"2020-05-20T13:19:36.640Z","modified":"2022-05-15T17:04:39.311Z","1.0.0":"2020-05-20T13:24:46.519Z","1.0.1":"2020-05-23T18:20:24.809Z","1.0.2":"2020-05-26T01:32:02.970Z","2.0.0-alpha.0":"2020-12-05T06:51:05.488Z","2.0.0-alpha.1":"2020-12-05T07:03:04.633Z","2.0.0-alpha.2":"2020-12-05T07:18:37.375Z","2.0.0-alpha.3":"2020-12-05T07:32:55.094Z","2.0.0-beta.0":"2020-12-05T07:41:04.135Z","2.0.0-beta.1":"2020-12-05T08:45:56.617Z","2.0.0-beta.2":"2020-12-05T09:38:57.161Z","2.0.0-beta.3":"2020-12-05T10:24:17.880Z","2.0.0":"2020-12-05T10:51:56.655Z","2.0.1":"2020-12-05T11:03:50.320Z","2.0.2":"2020-12-05T22:28:22.834Z","2.0.3":"2020-12-07T17:42:13.923Z","3.0.0-beta.0":"2021-01-09T03:13:35.153Z","3.0.0-beta.1":"2021-01-09T19:37:37.624Z","3.0.0":"2021-02-23T10:35:52.347Z","3.0.1":"2021-08-28T15:57:59.284Z","3.0.2":"2021-08-28T16:38:47.943Z"},"name":"reghex","dist-tags":{"latest":"3.0.2","beta":"3.0.0-beta.1"},"versions":{"0.0.1-security":{"name":"reghex","version":"0.0.1-security","description":"security holding package","repository":{"type":"git","url":"git+https://github.com/npm/security-holder.git"},"dependencies":{},"bugs":{"url":"https://github.com/npm/security-holder/issues"},"homepage":"https://github.com/npm/security-holder#readme","_id":"reghex@0.0.1-security","_npmVersion":"6.4.1","_nodeVersion":"11.3.0","_npmUser":{"name":"evafengel","email":"eva@npmjs.com"},"dist":{"integrity":"sha512-gpmMhh3ZDJK1wzhJT1fe3EvVzfPCww3PsxC21emfUD0SRu34mHO2sQd0G6rAFEeNLkW4ZqU0POYRFouWfdyE/g==","shasum":"0d6290abd2511aeba24b25ee78143f53c02b618d","tarball":"https://registry.npmjs.org/reghex/-/reghex-0.0.1-security.tgz","fileCount":4,"unpackedSize":1837,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexS5oCRA9TVsSAnZWagAA9+QQAIdFqaEzYnzSB3CUlBjw\nYT2Jt4Q98fHyTReahRc60nbA23GNl/8GY2frBjXQJXYPdnwbNfrN5QQJbKDT\nsp5gvtUJp+14R7tYafgrgrYXz9Yf+SqGdZiWQ8RLSYN3mwlKt4boimemy6E4\nSq9DmrQHFfG/BQJia/p2dkpVbGNUvZXGhz8h9+m8UlGk1hD9JZvEk9kFHrlW\ncL6iEZveO6ixo2SOqtNoUts1AlAiSlVPVMx+QHG3uBxgu5O77zb84xbONNjH\n0mCvcYPZaFdetdv5m95hMfHhak+yWOpU3uRrhQK6eWc+FVKE63xjOh5ELzS9\nUgEqLVwhPCgabYFPiwhjmKdSjcyJx89QUoYYxkgVAJOKei2jEPAPdexdXlkJ\nPBGVdd8aJHIMSwrJET6+W1C7rrGHtTDW1rk4R6hzunDB5h2LF8itL9LLERWU\n44Y9GRrHAXX0QUKZLUyQ7tRnkmEFvkjjkCELdkNaCLCJIAnV7FAxSAtD1MD7\nHjR51Rz+3GVy22ZJexXARMES+7F5/lOmFBEVoZCbJbi2Pcr6KDhxceghulMG\nRNIsbhEQn8gohuBxlWCe4suLxRk4n4QVTHhTeItsBbOkVNH8OMOKBRckWYPf\n5zj3xYqN999jwQFHLW6sYnpnOG6OWdg2pLQYkxgpgeq7+7/o+QpQM/RKaiJv\nPiW9\r\n=K6UA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD4D4iYezoccsvXiG9w8EOLFmRWTo/4KKsC/eeY0LFCSwIgcmxS716tvh0ZZlnE/iKhkn2ONbcw8er8wlzOBouDtK8="}]},"maintainers":[{"name":"evafengel","email":"eva@npmjs.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_0.0.1-security_1589980776491_0.6195132177794758"},"_hasShrinkwrap":false},"1.0.0":{"name":"reghex","version":"1.0.0","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-object-assign":"^7.8.3","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@1.0.0","dist":{"shasum":"bb7bcc4d60c28de1703396a0a7c638286afc4257","integrity":"sha512-SbzFpY0ECY4IovldA12PpTVtndf2BJqcYQYPJF9EEDSrVRq2YLpadJUusFQ0wQ4V5wbFKwVljOQmB22euq+yOA==","tarball":"https://registry.npmjs.org/reghex/-/reghex-1.0.0.tgz","fileCount":38,"unpackedSize":230535,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJexS+eCRA9TVsSAnZWagAAs6cP/Rl90rS0tRpisuZnAUyl\nEbMkxVLM0mwGHyJJVDukf8ztW6Y2/Dnv2iCnUNmntWT8NZAxtLxxaAPGShUw\n4l2hL85w4hK4mNFpxyi1oO0uX0NdZuLKHAJRXjgPaxJm6Z1hT9wu6CtOLiIx\nCZ/KVUKIsI+7DJc7qyAD/lJ/B3u2mvPEpDE1cEm+kZv+oXrnOA2gRvd71WzC\nWQ2fE2TjEmfzRaqrcLsEFxFsd/i8zRCTfP2JDJf2yQS4u4pPameRWlyJZ/Oy\nlnq0BUYGCx2p26L4/faXOmOESvjPE17ywHv1Ka6IPpIzFW74dw1hf0BQWaCV\nf4Mvogb8tf7PQgVLWlSPvm9J53DKlusPcj8XM4/hUXQthQe+ckPeWTXLNiR9\nn1fun7NGt55b9EPN8qem+4ZdVJ1JH5GqbJgmA6luDAL08WG2J/ftcAfRWt+j\npUqKA1Fx1GOUnrw3MzWbQotuCH+/CiSTWZyIC5lk/qGy3y+/HPSdLOMklQl1\njGe2caa8vWrx91R0PD5ZCG3AL2g0fGLYukXCineZl1p7sC3QTcoTvMHiUUE8\nDItZjCMClhBqb9xuL98FFA9fHsLnYACnzzhqyrEyvCYelyFglUBwlsO/5GnC\nBYCXUxBVM7frtKrgijnkreXGV3qNER0AaVPLQimIoFSXnrtpdIGY0gZ/BiJE\nmHP4\r\n=PqNF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIACQYrrb+4+AmogLIFkMJ8XgrbAavv3r/0Q0n3EFJWMNAiEA0/q2BRawYVCEC8xNwdfRHyJu7H1sf65GA7veaR3uQks="}]},"maintainers":[{"email":"phil@kitten.sh","name":"philpl"}],"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_1.0.0_1589981086400_0.8130651856678008"},"_hasShrinkwrap":false},"1.0.1":{"name":"reghex","version":"1.0.1","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-object-assign":"^7.8.3","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@1.0.1","dist":{"shasum":"ec82f5e336f8aacee17eb02f3fd7f76c06aba984","integrity":"sha512-Ho/yfbXn0FRjV4KQvg7fGHu1XIOl3++qgCTBlM/0B5w7E/QZ79OV8mCRmF9pVQzmBKWIAU1jtbdvsLvJRNGScQ==","tarball":"https://registry.npmjs.org/reghex/-/reghex-1.0.1.tgz","fileCount":38,"unpackedSize":223102,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeyWlpCRA9TVsSAnZWagAAxCIP/0+4ilkthLpPi+Rqv6EA\netb9K8G1Km7qg6QgAlTEQXoNZZ9U7fWZTqeLe3y55IeDPy+iz+/kf7Q6kSaO\nmZ5pEZKdAw6JOL6Ig0wyAMxWdtQ/et1TzJrT6zcyrlzut8a+I039GL/Sne2b\nuYuhEl7GqzczmIJaPHixK75qil3xOr5jf8z9D/NFOn/jGyRMaZxsPMIOchX3\nf3V9pj7ofsf5D1YtJTvs6QaC9LXqBeLscc0cbGEsfMcpv3XAO0FzCIAtP/QR\nB2OGjtaWr+TC/3TPXPSHaNHfVfgdRxMG09a0X8p+PGSR0dKsm4lVf7xY+FED\nsSBsdyKqCL3+5hAa1UfZruJ5rtHEdrhGUwxFm1p4QtiJnsZrkQHO1xB+N+Vp\nvxqrIW2d6zDz+Q2iI9AdSWPydt+JvAM5cQc2Zwlr221Hbmuob+6VWJ2Ga0EN\nWJL2nSYgrwNKtXDe5LQj1a2t9eWMq6RpmhZ/ClcsOwCBBisWR9KjRIJbOsTE\nOusg3aVcsg5fFcmyqnpG6wifgoMjCb+E6V0680iEo9Q+n+ph2pvKc3XQsNKn\nblfrgAR01SBsDjbBKgH1NVY6vFcR2Dr2/eUBTCK2SlWkX8p8rUPB/VqwEtfJ\niyiatCizUjcKCDGRhR+6sqERIXx81C2P3WuuVY+TAgkbYC+O7QFAH+qBV6CC\n9LnF\r\n=BJQa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCwhtqEDW3GflSG/ExqXG+wyrzOJaOlwcXrvZRgYej9WQIhAK/GNiVrpy0NhzX9fBmXDR4suGblgjiOuPGlnjDq9smG"}]},"maintainers":[{"email":"phil@kitten.sh","name":"philpl"}],"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_1.0.1_1590258024683_0.1847786585486726"},"_hasShrinkwrap":false},"1.0.2":{"name":"reghex","version":"1.0.2","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-object-assign":"^7.8.3","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@1.0.2","dist":{"shasum":"0a871f43d92da10f05ab5f953951c169e4ff0f15","integrity":"sha512-bYtyDmFGHxn1Y4gxIs12+AUQ1WRDNvaIhn6ZuKc5KUbSVcmm6U6vx/RA66s26xGhTWBErKKDKK7lorkvvIBB5g==","tarball":"https://registry.npmjs.org/reghex/-/reghex-1.0.2.tgz","fileCount":38,"unpackedSize":232866,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJezHGTCRA9TVsSAnZWagAAgcMP/19TKo65jVGB2vtC3m3Q\nSUDAtFHAcYSq1exgn04JbfvTcbwegzxdnt81Z9PWAQDInip1XN0OE91Q9f1S\nv6Eks6aNB0RdLDwGg+qtWzuKo8vwzjz95w1rREf1FyFd7AzU6auiKbqGb74B\nq1dmsSRZFEPBf7VF0V1Bi9w1tTDRRkoBHx9YGJ3QegfHmsc+EzE3vaSdhwIY\nAtT8VgNuSRFwaI2UDY/R7SGD6JRSiJ3P1WeMHoxvZYqm/6HAd/UEtgMtOz9e\nQT1DGvCHIDMWb9KtcN8FlCXvq8pQLYwjh8bsRyE0ezqav7e1taeqPoTkjSPL\nEq9FfOQ3PHM8w1aB7FXCKl52AfOOmpg4Dqwla6azYhjXo553PRp0ke4qIff8\nuRcHsItkL7wAjFD+aNnh3ZwNx9BBVJYyVlrNlUlcleJSH3Nc35W9ug18qkd2\ns+FcvgEURdwsg/4KDPN/cmgNzoV9A64HWP7rPRL2FBOIrSH3Z7ZlfRn0i/bL\noS0YDf11W/SjM+NoBiW5WchEoIZtaTUDOUZgTtY8GPthPg84T+OMkQABkdhu\ne0yw6gAk0I3nXQxA6qLVF01JueL0I7qHEeaT95cUDgCmid6SutI8qFRSTKWZ\n82b0krChtsdIA5W/VrDZ/zY0m3d3YfTt4qGvjoI28gMMYRhbJQtgxVjflo3h\na1cM\r\n=xDHN\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDjJt4xssl9kpfEvKSnntZonfI0Carw1WkbTMPMF4dLZAiAOu8JZ4ulZm24Fq1fNmv+wnRahwPpCGJDUubbSSTyFiQ=="}]},"maintainers":[{"email":"phil@kitten.sh","name":"philpl"}],"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_1.0.2_1590456722816_0.28749684565774003"},"_hasShrinkwrap":false},"2.0.0-alpha.0":{"name":"reghex","version":"2.0.0-alpha.0","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-object-assign":"^7.8.3","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime only!\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport match from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport match, { parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-alpha.0","dist":{"shasum":"a1a07442eabb26b7c8e97656cf82670cef9fc5ac","integrity":"sha512-Q1TNHEEo3ir/Rof1pnHDgWtfdAIL8Ozf5iOY1cUwh92UclJxlyz8l7F8IWVqMAjti3zqy7uVfNUktnM3y9jRlw==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-alpha.0.tgz","fileCount":37,"unpackedSize":170853,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfyy3ZCRA9TVsSAnZWagAAv0IQAI9rpwipJ1o9iHeY0tna\nzs1WBt+OlrdLkMEgD+RrBiotl9aHdIRYmrb9SskkxujEV61RumrrvpPw0W8p\n0T+nQGjQ6tU7ODpl1nLRVuOtotipiQCnumRk+wodPEyjEY4pzYP9m8KTtdYO\nkkfsGm9vJRj6KISANVjtmxSau7Tpq2Euf684t+wSfdu0poxsMD449MBXRFnG\nPBZ9E+rThOwgCIpH4mfLx4OP7VhD5950NLC8VDqpkaNa6YnH5/ZUaqlV83dw\nrGtGXHyvz1HLHFTR9OO9EZ5swMUwXtrvDVzNu3cFb0qLfNIMuVesZBnw3et0\ntXgBkrRmSyL849/hSw4fo4362NhIgBxH5Pmtpwnr7oZyfxenr8F5GyD0APE4\nrE49SUdzP4127je3uAQzoShDE4EPfoqKTOU7UC60p4HVKKtLIBvnmi60LEzB\n5LqtPVkobyOXqVrTBtjhBtSIz/LOvGEcp5D6gk8XstgJzgCopOyqbfUo6FzT\nR0K8AH9NkFr505R2ocDmhma0eotDE9EhmOW2FocQ2ne5dr1YkCTmYw6kOhg3\nlonTP3hCzzmWKfj/3Ur/u870F7078MS2CZp4Li8GrAzEC5x1qWUYRFWbdJg/\nWFbguqS2vrfhTDnONTcrwLyCtJXPNefMoUCEkIo/6WOeCbsAK+OiYyv3uSLj\n35Qv\r\n=QZqc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD62azycLcHAbIjiej1hsKlHwE7sdF3HQd5sy4WyXCxkQIgVmRRpZG35r4JaiIo/11+ZNZUfyqANoJFhtl2oNYv/+0="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-alpha.0_1607151065308_0.9846566794351432"},"_hasShrinkwrap":false},"2.0.0-alpha.1":{"name":"reghex","version":"2.0.0-alpha.1","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-object-assign":"^7.8.3","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime only!\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport match from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport match, { parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-alpha.1","dist":{"shasum":"b2bef9772487b437bde15ed053cad3085cd007fc","integrity":"sha512-R2JgQbINjN3TKnYncyKqvVaMIOApeJU/QQIi3uomOqGcdyjYvIrKLklqZddOo3hm7pORm0kfAuM/SZ9EMrZ6nA==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-alpha.1.tgz","fileCount":37,"unpackedSize":171672,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfyzCpCRA9TVsSAnZWagAAcmwP/RmU1YY/TFIV1+gP2nKJ\na9pPvHn6ZYQF8aB6jspc2oLv98sYNkTK2vR6TsfhOzUQYuvCIizSKwCSbl6C\nSNx3eq+qKzmhJUQ6/wosV+tQMYKGHCTYmu3mdffIklcU4WTk2vvp0Bv//pHP\nTISLz8kZOE40vcAdFVwgUu1KvzPXG5jzFoUMSVaipoQVVJXZ67oRmwZR4vor\nD+LBVnv0YxYoICGOGu7OPL2a82XYxM0ClY1lUhaJfZD4rm9kLivRWLTXtlOy\nTwvnnwRqFC4INphvZ4/+lWSEHokSNxCN06GgEjpK6MM/3hARsuyEMKGcQ6To\nZm1mFn8HfqDJdOLuhwNJNriF3vZq/SzmTRTgRaIwdR1nKmIDMNrFiKF3GTUB\nVkcHSo1E+zqagga6UMc80XkiuHBWZUq5RaWIPfQpnWBuZDJklkYJ0qrgwCJj\ndRO4jfLhGPjkBIlBfoNQhC7ok+NIXSgY/SitK8TPjHHdFGBYBrKYaOnFfZVq\nG/BFWUaoCdnwzfkL2jRXRd/f/LaQla/QVw4hsKAeZrZDzyr2/LNcIg2zVvqO\nlztkugoGqPs7MQU5rod4yF1I6VLKTx+4tV2KUcK3YHTyDlTGp4UmAk8qUJsh\nwJ+0uBEchvIBGKFx6tp9YFJe30Ue02nLLZhKAFI+UYGx6SMRec49Mg+QsVH6\nyfot\r\n=V2pH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCpDS5aIkmE0CgsElgJnwP/xhOP9EoehPCePWsuaEJDLgIhAIguDTnzZwjX4HLhZULIMGFBlEd3tHhiZoE0L+wPJ/nM"}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-alpha.1_1607151784431_0.8443909745871545"},"_hasShrinkwrap":false},"2.0.0-alpha.2":{"name":"reghex","version":"2.0.0-alpha.2","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime only!\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport match from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport match, { parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-alpha.2","dist":{"shasum":"4fd6d26b8c434879ab58ccd9f53bce306941db7f","integrity":"sha512-Q3DKMftNHqVuBZS7NnNLS4Aq2BTWkuYkHVvcSdlLlF9+BLDnx2ozcwJ7Z0ZPz/kqkVVPHcF6oE3q9RviV1XBgA==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-alpha.2.tgz","fileCount":37,"unpackedSize":175212,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfyzRNCRA9TVsSAnZWagAAc4oP/i1izUFERVKf669NP0n+\nGqduG4E1hQQKyFr6+NLA4PTYsIRE3FBvy6O9T+P5bTbrxXdhwddpBvXdiBea\nRcbLduhqgUOBKOmBaakW0m/+v1+3n6BkhIXidF2Z2Ularko/OJD1D3lJINhp\nBak/wppmRpeglQPSpbeJQUeKYhnPYsydqT1qmzDt4yZcBHoxL0EUUqF7sWMM\nmIxPCMEqDbxrFrBYiMOsL3OiJs542IViheY7ZuA10rO+HENOKf76POIo1VZA\nJ9pXrAo8BaSfSkqhjeFIBBviiQIY6gQMRPUqxBrzhtguky/ZGO4Ys3E9Cbab\nmoxqupJO+FI4WkuREYl9grgq7bhDTRWY3ryeu4lT4ua4SsoBdmQu9FPoczhI\n/kaNSn0rVCBe1/NtM3KXHl9TGLLwHBUtCUogoBz9yaHqJMA5+e7HvZRe5gV/\nZN2UqGxMAxnMdCbw6WcWQIuQexrXPa8vLuUA9MhjRcJ/IpcSWCZNZv9Pg17b\nM8UfwEfvpAWdzP3GfcEr1/Ht9y67rsmlKUBXT7b+MC4oJ+rqp5hbU9iHkNvx\nmdG2COHy5BU6fXGV+z9rpiN1p/pKT05IRSe8jbwZC92tDuVelhOkF5iW3BDt\nGWhTMmaLOLbbSIYdwL7ZxmezkMnaeYjyoWZPMWOFZ4Sb6YL79//4/304vuJe\nwkrj\r\n=BYRg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDVEFkzASDMFlJ/oNWO5VBAoV21lOGZTDlR5X+GXT+lvQIgAm9HYUjNea/Fxxdx7fQ0Ei8RDSqlAck98pIK6BSoGQ4="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-alpha.2_1607152717242_0.04450818330412187"},"_hasShrinkwrap":false},"2.0.0-alpha.3":{"name":"reghex","version":"2.0.0-alpha.3","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime only!\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport match from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport match, { parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-alpha.3","dist":{"shasum":"2a5bd1b11eebadba8284a68f53fa7564a086674b","integrity":"sha512-lKYR3AtbKT/QB8jbnFHtI0yzyGeUf/hxi5cnUcublu7vljFFT4/CqjWaWVBmKLEbn10C1XloyOKXGoyTW4Bxuw==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-alpha.3.tgz","fileCount":37,"unpackedSize":171619,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfyzenCRA9TVsSAnZWagAAVbQQAKJncx/W/Y8TGOhCqixw\nlbl7ZkfrTGFqQYL5PT59g3zprzCrx5S2hlN9ENCBWyZwyPlF83MgFAeycYhD\nupALaCoawWLSUc7A6oePKjmEGgsYoyX7jPl5FVlOAlrzg4thjTWd29QUfzwN\n4rl6Vo95HPeSVN1y70EvKHBGRY+/65jncn6e4Ev708vDMedpzQ2uLIzDYR52\nBdYw3NjzrdARd8/diFSFRi0BWU0aDwxe1IEdAVMSOblK5YSTbGIb76XGKz8t\nC86/RnbE5+1IpekHG/ujCxnri/C9l2aNKNIhw9Dg6HMOHPzNQSlElYnWA7ki\n5WeZS1052QBtaGO5qiL9V1kupqOQp8kvZdTVG/uDEgaBa1x8DU3Q+JWQ36GO\nIxqnRozTRjil6dfozsh5mYYSYIV8VpB7MBevUaE5m5E+sU00qyivnnm3hjwg\nskiU72qrMTVLp2zR4/YrrOHWdT68KEc1IKvFcI8ys5TFZDgtfX8A3JVdayoU\nP4un4outA+8yi/cVJKFPP+D16G6MN7J8rwx1dUxYWtejSEJBcYeEZL2Se6zY\nlAs2qNn6OjwlsHzRibk7uJs73Qz9rcJcv8jrZ+rgv+cLAQ+F8e7drzun9yMP\nB9RtMiqx7hNwx+kFSMzUKCF09aWImD+oG8expApxVS3raevpaltLyvY67P51\nBZyH\r\n=2NEs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBiizpTlrxcF4ZwXfaxdFQyaOXNBFZ2YBXPml4xkGRLwIgPL6IohAGk/1faF5AUOKkudEydoPJZYIR3oPLXg1+xfk="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-alpha.3_1607153574973_0.6474589896839604"},"_hasShrinkwrap":false},"2.0.0-beta.0":{"name":"reghex","version":"2.0.0-beta.0","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime only!\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport match from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport match, { parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-beta.0","dist":{"shasum":"4e6cbd5b0e88577ab2306066a4dc55316b03dde8","integrity":"sha512-3C/t+/Y83ajNZ6Q86T2yQ+5Fe+2sCbOrLmNK3mwPGeiIeqDgryongYZzP+5OYUdu38KYoY1IXATB3u2SsRNauw==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-beta.0.tgz","fileCount":37,"unpackedSize":172038,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfyzmQCRA9TVsSAnZWagAAZscP/172752mc71anZj6ceuD\nJqllT2mTVrhfAgJSoaHcF1DzwPTCV0ly2PJnwx0geLo4ZPPoCEYy4KJbH52P\nDsYJfVcdXndoIZErUDchPH/b0ULzzcmX+aygTk7juj6lQBe+XCTMZ+a5CBFN\ndsq+hNir9CMSjcu0vb0PNNI3MtNuLQum6eKTYvjax7NQ1lI7FAS6Ku67xb7A\nQehIQo1C8g581oCAj7CQW4UCHkBx5LsWmm4N3sW9AOOrmExpaQWQ+DjXAhA+\nQQjsdt+a9oZo6gfJh8nRws6OWT1a3jGeHrL8wWA4dZ4ZXWUnBX5l7Z7JZUEC\n6yHIu5SjfqjebYwG+jEDC0PQ5b9ekOCoq+qnJW8zfu20CQv1ka7NbgXIASvA\nl5ELWF8JWn7vDPH+2XCaImcle4Xih+YnJC/8GDGw6vKeI5cef/VgZXuVKtR5\n1q6WhCJkmbArh8ydNmj6/5Q2b+5zu0DhyLLzbCsOsujwrz84Q3IWfQINEmAs\n0/0WwHyfZ1Cx8qADVuR43CKqhPIqYYG8DkHCLhAULWSBZGrEARgVQyk7/BqE\nhdxcwjCZVpinm/BoWBsz0I+4mZUbui6gAfD1KDUSE4D6gbbmn84Lp40zCC9N\nTNHTjjACFaP+iyWMZQj9i7CbB1QGJQe5lh0anGZ5jRLHfmEgMOrclHhtI7xJ\nwSV4\r\n=5gzL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF53gIvIQJJ1tUdLhW9K39NYdvDZHcItHqqG0+Oqb4Z0AiAeCK914SoTMN4mVKUAYVFAxHg/ViiVVJo+b0r/YU0+wQ=="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-beta.0_1607154063944_0.0970169998258168"},"_hasShrinkwrap":false},"2.0.0-beta.1":{"name":"reghex","version":"2.0.0-beta.1","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime only!\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport match from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\nFurthermore, interpolations don't have to just be RegHex matchers. They can\nalso be functions returning matchers or completely custom matching functions.\nThis is useful when your DSL becomes _self-referential_, i.e. when one matchers\nstart referencing each other forming a loop. To fix this we can create a\nfunction that returns our root matcher:\n\n```js\nimport match from 'reghex';\n\nconst value = match('value')`\n  (${/\\w+/} | ${() => root})+\n`;\n\nconst root = match('root')`\n  ${/root/}+ ${value}\n`;\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport match, { parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-beta.1","dist":{"shasum":"0d3bb316e162b97cabf3cec96a7d098aec4f2d67","integrity":"sha512-zpznlgT1Gy5613z8Zal8loAISCmGhBCPK6bZDqs/0iEFi2K8mEEpV8mGFQBsGuAioc3ZoeRACzIBjIVTs1AUTQ==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-beta.1.tgz","fileCount":37,"unpackedSize":173637,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfy0jECRA9TVsSAnZWagAAktQP/3jb3FoZ0FYF0JNrJmKl\npM8E7xRdDRe5m59d7Qq2oeo9XNpg3X8j0HvTcnMU8kfcmJ+eg0/sZWZSyuW0\n3XXbUG/w+eH0/vpfcg4fUjIq6hNRxXXpf/Y9RUy2PrwHO1PDWO9krZhrv2f6\nPEJxqE8xNULub0hG9ivTq2xXe21+0nicw7cBv2eoG+ZinslLWK61pM4FSfFc\nHdP017RhCT/5jSmS/7iTVodOcWnnn1TwRxaA6OLFb0DCi/NRlb4CdbpK8OzQ\nRiQAI2UoL5g/sNXAJJFxA8YdhRczD4IVpm964Qr58aOFUVDMhaEnuegTbC6q\n48+rlxbmmJXLu5hYCIJs5IyL3M8HVYd09YAjwIwrMaB8s5kwD13upIr3Joj0\ntiXa8CALiC69MTlX8V/LHeD9CxBtXihxWHm7gbpjG1A12WwDU1vH4wxclyGL\n9T20Oe2RJwAYE6RFbUAWsYgRyCP0ncRhjySP37nQrnX3yNLvcwGau5tOePyV\ncUvc6teNdvTLup01C6r7Uv+OfAetOY8w2HhnxuoHn6juPgxjPbdntWk37Yew\nxGk2GkuGiXr/LUlt3GwkFY6Z7PtnhWZjAaNrLo9wnGtmr2tEF6bRoqyRmnKS\nMqkzA/R5VWxYIY1/S4xgWjU0pPLPVG7JPluxMeMpOh4JorhPDVLi05AQskEN\nfffr\r\n=ZpMp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBbGC65m4lJUEe+t1nAOEFovdCgLnaOKMnw2Yw5VNhBgAiAEtcT2HJyFX4Xd4SPB/eOUaAui0mY1shTYg62jRPuLzA=="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-beta.1_1607157956410_0.8551163522510208"},"_hasShrinkwrap":false},"2.0.0-beta.2":{"name":"reghex","version":"2.0.0-beta.2","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime only!\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\nFurthermore, interpolations don't have to just be RegHex matchers. They can\nalso be functions returning matchers or completely custom matching functions.\nThis is useful when your DSL becomes _self-referential_, i.e. when one matchers\nstart referencing each other forming a loop. To fix this we can create a\nfunction that returns our root matcher:\n\n```js\nimport { match } from 'reghex';\n\nconst value = match('value')`\n  (${/\\w+/} | ${() => root})+\n`;\n\nconst root = match('root')`\n  ${/root/}+ ${value}\n`;\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-beta.2","dist":{"shasum":"5c23bbf32784ea6f19c609d6b76c353b57773cd2","integrity":"sha512-h4WfOL75ZcLIpaKVQ43tmpAih3PO+fsAPcgKir1235COhwaD3RHVZbFD66ndmgh1D3MgNyerwhLWocezSmIZDQ==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-beta.2.tgz","fileCount":37,"unpackedSize":172337,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfy1UxCRA9TVsSAnZWagAAiMgP/2VxmrNRJ3RlJk8MQIpt\nxR/Cw1T+9M73D111Tw2X0cqGFcPcyRSd/z4o03LW0hDhrKGi99yIGyKtLK36\nQp0oZvHxas3HGYMtj8tCLeqj9OR27HzowcRqwvymGiFLaqWbAUpkQ4/Xja/d\nCTW39o//N38H0DQ2nALSPNVgwoxs5/N7eN90K0rm224flwlapBfQqG0ENJMU\ngyRme0Z5HxQR/KPw8wiW64eMumqWYipD6wK2PqZhdLgw76PAc95nd7LFO05M\n3SE0IAH2LvbN3e28kpiWvyuFauX+f8szABZfH3O+iaxC0Qa0yU7VTXjidXdg\nA3MSY/xFeGq9/m/miGz91wAGehi51Q/jcvUQuFf1MsOIqDa9fZzGbngQZ+eF\n+OMSVOZotVD2JVPWviG7Gwckt4C5cxReMAP2B0veJEhaPeHMt++W9atw5ZKA\nb6AuB7LpZbGmFPFBNXFHKRoxzstKU1KXqFdOR2ysYoghQP64FOn2rL6Jr7HL\n8fqMAkSZw36tbAczNe8vAAxw/e2Z/wlDpkbQboE5eut0ppNCZToR5XiUZi9h\nbAo6edx8PjRWdVmz+gGIClGAXuD5zwfRuvQzevBTjsSp75is0cae5Kovh5st\njRGYXsjAShzb5C7yaxS3w4W4u28XgWVKCFjf5x3S3FBTx0qDlPbPkqDzQz8r\nQEoc\r\n=xtRi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICc/UPSUY3zDnikr8FNBG261t1/4v8xb3jeAh5KgTSKwAiEAlMWhVfcSYw7MpttR8Dy2mll0zBvmYEFRYvGn5VqLhVA="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-beta.2_1607161136954_0.0911265302383959"},"_hasShrinkwrap":false},"2.0.0-beta.3":{"name":"reghex","version":"2.0.0-beta.3","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime.\nThis will only incur a tiny parsing cost on initialisation, but due to the JIT of modern\nJS engines there won't be any difference in performance between pre-compiled and compiled\nversions otherwise.\n\nSince the `reghex` runtime is rather small, for larger grammars it may even make sense not\nto precompile the matchers at all. For this case you may pass the `{ \"codegen\": false }`\noption to the Babel plugin, which will minify the `reghex` matcher templates without\nprecompiling them.\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\nFurthermore, interpolations don't have to just be RegHex matchers. They can\nalso be functions returning matchers or completely custom matching functions.\nThis is useful when your DSL becomes _self-referential_, i.e. when one matchers\nstart referencing each other forming a loop. To fix this we can create a\nfunction that returns our root matcher:\n\n```js\nimport { match } from 'reghex';\n\nconst value = match('value')`\n  (${/\\w+/} | ${() => root})+\n`;\n\nconst root = match('root')`\n  ${/root/}+ ${value}\n`;\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0-beta.3","dist":{"shasum":"5fe999d0a4ca07fd56e2fd1546acf071d954b005","integrity":"sha512-uwhaqJrwle6NoHB4QB+LrMk3VfcnOG7zB+BOmhlpiSNhvoSlYW0SZMHW8+lctkEZ5R0FVdfLT8P+a2OIV2yMHg==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0-beta.3.tgz","fileCount":37,"unpackedSize":164345,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfy1/SCRA9TVsSAnZWagAAimcP/0m4JyTiL1GbueZaEhMh\nuKMCY+PEpE4QDf1Ki2FLfQgxemOIFf6xjoo+HFswjCzAW+QLO5htt52XCmw/\neJpYVX4Fk9h+Cy2mJ+DRibRzFCA/6dKQeTI+s2/jU0vbhuCKVMFNosU9+0dI\nB5usyXQtymPDByKP9pHn/N4bcpY0yMAMrHxC1VugNCBQtkNNo/MacuRUA+4b\nYChrNowXaUwsUX7QJJmxck6lZpdKvZQMZD+F/It+nwz5E4Hl4tcNIP9C3p7K\nXw+nF8oPprTnxMcP1Djhx3+t296YxFvXs8b+n9jRtDy/EmILwqV+02Fm+EoO\nnQuOQf/3muDBU5t4JlBrxwRQHG9oH4I8kc6uN2RInwmzEWTkbflgsDNa8U77\nQsGN6jNPPem8EpuZUoEr9dVrSyJ01ibc0C/c4BsOw59N4w/CuH48Sc4nBTrJ\no01tPTKPxAaYpTh/Vi5bxA0BDfkDmH64Oy+jmZNFe5gQOBoypn7BPfGZEZqQ\nelaeQaHI+hbHzvUhdr34NS4I24Ljf8lCqOk+jkQTISicRI+Hw+K3rWF+guzm\nSWtwdK3xEDSHfjza2bs/ejyQ6lOKdQ7kPJB6BxsfSPDAcyz6aARjIBQp9GqC\nx+d4AZC1/IlHiW7E8Rw/HqnBhf2IRSqvlZV8qmehQ3lEB1Hq+lQNvG9udp84\n1LXQ\r\n=GNo1\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBTIgqbjRDvUmSm7mzPIlU9qBMvWTj89rzAPSmjmlZFVAiEA78GkSZ8JaRDPvfSj3jvc+v1ODa1JoTLmAjzcFxm6moc="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0-beta.3_1607163857652_0.00019136766421201656"},"_hasShrinkwrap":false},"2.0.0":{"name":"reghex","version":"2.0.0","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.0","dist":{"shasum":"af23ada03e0a06ffb507062caa4d626a99a4d31c","integrity":"sha512-NulPUuDSRf2sGRoxsXu1YKKBMKvc7jWry/6Jj2X+m8Xup2yCGekNHxJvPhz0/gCf+yJi/KKb4a5xJqZCnwCfFA==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.0.tgz","fileCount":37,"unpackedSize":154675,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfy2ZMCRA9TVsSAnZWagAAMWgP/jp/nkzQw1yPiTBpkje2\nXzhmSEEZOjlLExJDuXLFH0xOXB5vOS+ZZBeNG2hqp+Els4s69rEbRj2Co7ZV\n3hE/U+Kq//QheI0mWvjfbnfhOlJOkI6RK46cXcPKeQ5AKFhn1fJjKVIuXM6y\n7ErOIhmtGb+R0NWdgMHWbjDezAUZMbrQZcU3xOK7A/NqnpIXKxHB03IfS+NJ\nhQgGTJYK/dUcF9r8vZOBRLCi0rI32hmnREQmFayoIhaPHHHg2B19xqtNEYEa\nIyMntl5+5r54XMETgHt1Tr6WiXtmuQA26aaZa9CPauW+Zzz6DLvmzZ/hiGrI\nTOTrmE6NIrfODxnsAZj2fPXZPVxl3E0k1LufvGWCVW0ELsp5GS5DTCX2bxWZ\n0b0hP8nCwLrtWxbAJRgfHJ5vwB3+BCaJDEEMucs8u0T+VdcaDrFBajAV6+IW\nNDQtI4SkJ1Eebtb1VbC8z8qipLwRFurreZLgJkf9RVnpmKEH2tmjrvG7M4ph\nKa0jqKEtEOAfQg9BYZCr9d7vUQsBdwVSrCYwumITTQHwWAQH1Mc2GCaTwqIq\nCUVD4O5Ufwq77Fl6QGZ3HnY/MgbVPibls1DixMWLMFx1doICvU2I6kRxcw4E\neJi6b0CfmtE26iltmSv5QyA+fMEyR0AzRwf9wz7Lac9SnNzq2yGrFfGOxhyv\n5qjU\r\n=fzsg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDx3aeGh3NVAB/vXVqPyvnC8bIyrqb8y5dzC8epM1R80wIhAObu2aBxWNL/adO4nWKzHqzZvpYnMxMASxvxkvzX5EyJ"}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.0_1607165516536_0.228488650027592"},"_hasShrinkwrap":false},"2.0.1":{"name":"reghex","version":"2.0.1","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2","rollup-plugin-babel":"^4.4.0"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.1","dist":{"shasum":"d67298f89450bb6936384703ac019f706f074855","integrity":"sha512-MlebPiC/1sxDQa4ArUyOSXpe66w3pHcKJ+xdhNJ89m0I3IFAILYY+3sWp3g1tCT2BCdjthd0jW0rbgo4LONkNQ==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.1.tgz","fileCount":37,"unpackedSize":154699,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfy2kWCRA9TVsSAnZWagAAMD4P/28Gos4BmVolVYJ+wKPN\nhPQPiTOaL6O+GgLZky5/G9RDs3e18V7Q8yp1qaDdjfos09y7vnTgGqmgslV5\ny5FXWaT215f4SNxj/+B/oSVlUFj2yZxX/IaaT2aJqb3b61HwzCfKVa0oanCR\nzwErZpyBEKe7pGVNlfZqepmgm+2O81oATcdUQ2eVppPIYD9phHpfALxxrONL\nyWgiegqdFDIdanMmjRc54cDbKYVru8ad4NSJIG+4jAgmVBSInHSPHRF3HhYV\nn56+JFy0xj6ntPwX8RuI2RAhRrGZvZKc5/0moodG57v7zS/pbrwCt2Z148Ri\n3mstCAs2gWs3csC1dyMJTl6C3wloKjiYWBktejcmX2Gr9jBqqemQ7O4QfPfK\nGVzZarPqapKgwD0Oey8Mkz728jlaMC5Ov2pVtAYjXekJSOs6BEAWglhy0TZg\nsvyNQO6V6p7Mjg3v1O1nvzUoZXstVIgbkhMv5rv38CNpujRDig3eU0WOT6dd\ntFmaodWrQWDxOHXRcY/r5fC/udinM8mjQs6p6LW9ehNBK1ha+nDwPJmOggzS\n5jdDypD4mQjo2X2B0o3NexvZeUmyy7Bd8b/hPBPiRz3jo/R7Qim1wbw1zCvw\ni040R5BTcyDP+ODlZ88Tm7Ak2zsKBCufpIMscfn+XXVTZMHYVfrImH+oaE+g\nZ0Bl\r\n=jwRb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCsFBaZNggCQMeYzoM/NP1CwlBelj5ueqx0ZoPhpzakLAIhALd+nUTupwSzRap/FxIRdA9DJzs729dW8CE0ZoCSfvu7"}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.1_1607166230183_0.18490496571971593"},"_hasShrinkwrap":false},"2.0.2":{"name":"reghex","version":"2.0.2","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-template-literals":"^7.12.1","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.2","dist":{"shasum":"47a0d46a6cf87db189c0ff9ac6a7225bd032b594","integrity":"sha512-xsOPL5CXgeLLtPQYKhO2skTAfLzPlqgbAHdvP8B6DnfWicnhr++LJ/CwyT+2srdcARx5GVg77isyYON9j5Rozg==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.2.tgz","fileCount":37,"unpackedSize":154841,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzAmHCRA9TVsSAnZWagAA4BIP/jQ0ds3KB7WCKwgcu2Bi\nWlvRnK4tAwoRruM/IGTmJj/g6wvFapF66MMd9fysNK09CdF1B75JHn60mZPi\ndOhs6MMDkAg9kdxUabI73NfXm/VXeGja+0CmMSqdZwgAnscMd6mvRVtB3Mu9\ng8z11n9KK2FNLZAPx228IazPg0aAvh/I3Acc9kkHE40gia6pgjs4Ya6zLG2p\nugf6KwvPq43+9jcfKL12cFg+c9QM0ZnL2oBeTaWDZvy6tOB2kXeAnj8tgx5x\nLIHU2wt0emi1evXHPGDwiaEh/nr5t4XFAig2bVjljA0CBO1TEA/g0EAJS9Re\nsZzUZAaIVhEc5AYYGECV+7J9796a7ShLwW9ypsCJC/pdjLqA0DjcToD23M45\nmHsTvHte72iYrDAIYO6/VGUM4ZIsNdsyJOdn4v8WLl/sjOwK+FfLg37uV1mD\nfSMlK/gu6QmJpbiA3yge0kSJzbxT7qXcAurHqp68iNF15zV+P8FxQaE9CW51\nbIed/cXWvjnYM4l022Ubzs8mabps+9OgXH94bPrWlA1kQVxXHVwAdkZj5LG1\nxIIeThJd8qfqYTjwNeBmfT8FmiHzuTL0E4CQ5wqK9oe+Dlw7/oyvk+KQgikw\nJYO3GrjFd5kl0MwvQQBXt0LNzRkK61ZffM76FcJDBWabIBs9EsNLZ4ZG730w\nI7SG\r\n=F/cr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFQvJk0VZEhrnS+xj+NorR6DFWkDGz4NjAy3ZS8HbpeYAiAWYh89isNPa93/4FQJ/oNegZy9bGOPVORgLJm3SASmEg=="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.2_1607207302643_0.49476814670839464"},"_hasShrinkwrap":false},"2.0.3":{"name":"reghex","version":"2.0.3","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"import":"./dist/reghex-babel.mjs","require":"./dist/reghex-babel.js"},"./macro":{"import":"./dist/reghex-macro.mjs","require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-template-literals":"^7.12.1","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@2.0.3","dist":{"shasum":"a19e7324a8fc09f5e5704242b53d02dcf3db5419","integrity":"sha512-re2Xx1ITU5tz6jEkLwfsvIOtFbfDvuI4EXF2wNOc1zC7iwzet+hu0d+7YvxCViTQ81Qx2gqCdS/pbKepTbK9sA==","tarball":"https://registry.npmjs.org/reghex/-/reghex-2.0.3.tgz","fileCount":37,"unpackedSize":152744,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfzml2CRA9TVsSAnZWagAAnLUQAJfcQzZvyjKlu7Fr3IZ6\nhwnbV9Jw9b3jzZb9w16+4t+NSBaGBt9+BFejVb31sBiGTe91eSMIODPRUfcW\ng2z76meLijduGKXqOLpuDLp4nQsP4TFmrUlw4N8Z971He+671hOot3uLvxpD\nk8sUAf3c48r40ahAUUGu2XavgyavBlEGv0ht7xTKUoyvNDGNtZSSbO9fVl3j\ngbdlN+M6KUkfxpcPWOrH8UBXNVshy4OnsOh6wXWBPxBKUcNzeaotj/zzux8y\nviaEoyRtPNlgbl9m06NOX3nRbDPZWG1+tvu9TN8GpmCIdVUV8+deGQK9rcBm\nivtEm10EynF1qZJxRRt8yleHo3+Wj+SoAzf+vkcCICvR+imvKvimqLOncnV7\nbnDElgn0bHCjetLAAfU6Vv4xwcVqUVNjJLTMLk6MZ3/Jw1EQZS/gfRGitRoG\ngYzEym0xj+PKRVWM+RmnacKn6Umpr3wQlvQXqkmNr798scOkBFdqe8rdk78l\nYl+xpYe6DqMk4H9C8x9prKeNDma20Ia9Sglifh1adKAEXA99Qq/v7D1LyvbT\n9eX8AqFYMnIBKvL8URqp++k67t4A8bMr5HoTj9fyPsptY9Kg9Es4LsQ49z9M\nYnt3E213N2FGJrTEr89Y2OYEiafN/QfwNKZdqKYT7nGis0CU5xXlHOHJwvWh\nplm8\r\n=qtk/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE43GyfVVvPwVmmY8iJMu9N3FYI0+LE3W+RxdYmLwLfmAiAGyvltDgfw6DTFUPn0O4SPRaro28326FHq0apEpuED2Q=="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_2.0.3_1607362933722_0.1257396983739021"},"_hasShrinkwrap":false},"3.0.0-beta.0":{"name":"reghex","version":"3.0.0-beta.0","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"require":"./dist/reghex-babel.js"},"./macro":{"require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-template-literals":"^7.12.1","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@3.0.0-beta.0","dist":{"shasum":"31f29d9e91bba69ec0800a9d6f249cea5bdd75ab","integrity":"sha512-ASztFSqujXAPbdsg/fA4+2LxyHO8aDGmDjUu56EW9gNS1gbBP7ny+eevSS4TlKKnXiHGRF5LVnf4cbdksYbv2w==","tarball":"https://registry.npmjs.org/reghex/-/reghex-3.0.0-beta.0.tgz","fileCount":30,"unpackedSize":131602,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf+R9fCRA9TVsSAnZWagAAnWMQAIkFStbI11fjy0AayhGl\n4ZcbBmV9kZ+TVvgpfLQ+jp7dqspuZKMALF/BBMNkJQB9ZWZe8/K7gr3YapYa\nkTfaESHB8rEaNg0fakbTw8G4WduJVzSo/LqbkSypUJAuoGrfMu/cy1Uq3iKj\nZEFOdg9KtmexC6OeQAB/U4T7ensO1Gd02TMmi1BN5U500gNPiNDBf4Dh1IKN\nyRd+ahznbGKC4Be9pRM3AKs8/hgBqQ1excZdcJ8V8gyiy7mHuxrrfkngq5dX\nl/JXgT6Vxw8phap/ActP/8n/PMkc7AX9RPzFmpmdRs2wdon8j4MvIwqcY35I\nwBR8F89IMlRODmqhoozEKbg/JNmgKdSNuwgq9+gxKQu8RdnvM9KerPFqTfXB\nHoBiulzGs/kUAEcIYOP9/bmvTPrVq8+sLnMld8VbsRQq7mfzRNDNFwCLDisS\n2i6raGeEwB2BcR27U50QeSi9aoBQ2PlXWQuoD1/hk/AvKZy86sgaHSvPzHG/\n8FvTI8M57UD8r9XEairPm1iTslY5J7phukjE9Q5XN9W7/68excdCp+8i8zPq\nYXsEYQADEeo0dSGb1ugdSYVOyVuGdpGSoFUM3EAjWyp4PJQBHGGsQq8tleXU\nnj2G+FhZBzDVX5R4LI6kEqFHeMqrIBIJ6E4CsQ/rg3eSAvTKPM9JZ218M94Z\nHq5+\r\n=8nAj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCmj9fd3y4g9+tXgOCKot2kjxMdyIZmxyu0F8XriHgqUQIgDZJwqowAVDeedTvyUodXpuvM0GOtC1cDHKmR9rTeeQM="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_3.0.0-beta.0_1610162014987_0.7456890124571132"},"_hasShrinkwrap":false},"3.0.0-beta.1":{"name":"reghex","version":"3.0.0-beta.1","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"require":"./dist/reghex-babel.js"},"./macro":{"require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-template-literals":"^7.12.1","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"readmeFilename":"README.md","readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime.\nThis will only incur a tiny parsing cost on initialisation, but due to the JIT of modern\nJS engines there won't be any difference in performance between pre-compiled and compiled\nversions otherwise.\n\nSince the `reghex` runtime is rather small, for larger grammars it may even make sense not\nto precompile the matchers at all. For this case you may pass the `{ \"codegen\": false }`\noption to the Babel plugin, which will minify the `reghex` matcher templates without\nprecompiling them.\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\nFurthermore, interpolations don't have to just be RegHex matchers. They can\nalso be functions returning matchers or completely custom matching functions.\nThis is useful when your DSL becomes _self-referential_, i.e. when one matchers\nstart referencing each other forming a loop. To fix this we can create a\nfunction that returns our root matcher:\n\n```js\nimport { match } from 'reghex';\n\nconst value = match('value')`\n  (${/\\w+/} | ${() => root})+\n`;\n\nconst root = match('root')`\n  ${/root/}+ ${value}\n`;\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy **returning a falsy value** in this matcher, we can also change the matcher to not have\nmatched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n**That's it! May the RegExp be ever in your favor.**\n","licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@3.0.0-beta.1","dist":{"shasum":"8a45730593e785898d08fb9ee85ffbe096488ff8","integrity":"sha512-dLhuUWn0oXhSuBOPf2xZZGyApU47lqUEn9NpSeQ4waXXn103XBQQMiBGFZYqwHqMCMRB+dWiCPSw2KqPvwIAlg==","tarball":"https://registry.npmjs.org/reghex/-/reghex-3.0.0-beta.1.tgz","fileCount":30,"unpackedSize":131873,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf+gYBCRA9TVsSAnZWagAA7dYP/RsFU38ceGs2mb8c/MEE\nn4jC+zhAAyzNsjmmsfDGMpG8fvy85Ze6OKtLpkZMwCRxC4T+cPeSOOnIfgj6\nE0BS5SR6VA6w8gRhAM4fg8lxZozYN8S9IHZJScIQIUHT3vGNb7KBikLyyFGL\nGPdTKGxxpgkdeSLLFXsUVe/q/Y+FP3XvQhloZIpMcJQ7d7TMOq7L19P2ZJ2m\nvw4WR0NOayniIjdR6Rc8vozIJFvulNibt9L6xA4+OnSHzsAYmVEl3PqrgzPg\nNLNVXXP88ldl2ogeeNSaM5Y+fMsNwpJ5WnZ94eYUEOFwXPbOLsHmGi7YWyvf\n5/PmBhZNEC4vwOGAumvL1pwaI3zBqMVMafLTwcq89QeAzRdXI4kOUI5CBiUp\nyDU4F592JJ1isHxIW7o9tRy+2EJVTcKh58nSR4OD1OBawAlq3TFIdIUBz7jP\nVtTCxrBUdmeR6YfQ6oLIuxDGX/NrChJ89ck8anFeGaDKtvH5Tr/GGaTJkxX5\nOwzjCqYspzzOaSAWUVE2fjLjoLDJ2rynxEY/qs5u9u0ze79OjYHgSGP78cNN\nre1Lrjb0vduPVFEFs+1eERcXBXbegIycaNpivkk5qQumV0z69BMcHb4xjDCM\n8V5jJ08b9st/XykNoAGOjWkdlsSFZa4EJ9tNGB+nYx9EN8OlGe1OY32hFclW\nipzV\r\n=kgdw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEtZzY65jvt0F+ch7ugUqLgMQNVnU98BanxC5PG37Po2AiEAssqXUD7QCcxAy2tH6z4PFSmZHth/L3ss9XnAocqu7Bo="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_3.0.0-beta.1_1610221057492_0.7500361823860522"},"_hasShrinkwrap":false},"3.0.0":{"name":"reghex","version":"3.0.0","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"require":"./dist/reghex-babel.js"},"./macro":{"require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.26.0","@babel/core":"7.9.6","@babel/plugin-transform-modules-commonjs":"^7.9.6","@babel/plugin-transform-template-literals":"^7.12.1","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^11.1.0","@rollup/plugin-node-resolve":"^7.1.3","@rollup/pluginutils":"^4.1.0","babel-jest":"^26.0.1","babel-plugin-closure-elimination":"^1.3.1","husky":"^4.2.5","jest":"^26.0.1","lint-staged":"^10.2.2","npm-run-all":"^4.1.5","prettier":"^2.0.5","rimraf":"^3.0.2","rollup":"^2.10.2"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"<rootDir>/scripts/jest-transform-esm.js"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@3.0.0","dist":{"shasum":"8121a96a75c81bd3996e94255760f98db0d7f3c0","integrity":"sha512-CWL9oEFQBq1PF3iT4GjSz7Te/OuLFYYHWS5/lCyxmMFncsr4Cxi/aapgmEF1AiqodEHI16t0cu1A/B/O78NUcA==","tarball":"https://registry.npmjs.org/reghex/-/reghex-3.0.0.tgz","fileCount":30,"unpackedSize":132138,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgNNqICRA9TVsSAnZWagAAfEYP/iprQxLlAB1SVjg0KA12\n8wRtaBOpqSTPY+obKPd6BIkWen2XCyRTIJateugp+nXuH/O7o9jfoORiB4nI\nXrw30WHRwWAlswcOcbmhrUDFTJ7ZYvwEi2BvLWy3/PX9o9oq+WEJ+JX/qL1B\nSafYRfAw7FTL67Orc9qLop5RjbYVr0iQEtpwbmhbXDCqN4omG6e/q5t+rfQV\nXTbieWlO9eEv4o3qj8Tcjp75ZkKabioO7Jwi8S3Wj73iJaJDu3tEu/IMFXRV\ncKnG2vdccoqSbP7fc3BnJ9ynkVmWIb7HHrk32pPkPu+c5VKI1iwQpsT0INs7\nN/4UrouQ8LyjpmMuPE42YibeUImoLdZbXolDVKNDMi+sPRb1iH5wzFLTIAQ5\nnUJq/6nC61xB19WHb9QYLhzUjN5d89Bq5oBU+FE7g9GYXeDSrX/OSh54Vzsl\n6G9SrbmPWQtWP3TDwPTpS8C9FjOBC31nxjoyeR4lk4i4Ed4W//sedntQBfkW\nr1BRY7qJoE1pJstlhLULL0QayTzU+IVJ0xw/VXju5nWOpnDDm/wwgJ36UwTD\n/eepWsIJVV/idtl6rXhOcAcB0AgJdN5bxpTSZp7Jh0lpsDHARIwiHTj0jtu/\n3nBmUdyhxWJu8vCYU3iyfDF6nYryrxkb51vffouR15/bKAdzwYu6ZUktAlyE\nKgIo\r\n=Potb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGqYd4RKhQt876jDqEK9SIPyfaUyrb6zG7YOECjhw2yHAiAqmFthcun50abmpAd24Rp/oq2WTNplaQLOpp5G2Zxh6A=="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_3.0.0_1614076552136_0.5270560908862074"},"_hasShrinkwrap":false},"3.0.1":{"name":"reghex","version":"3.0.1","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"require":"./dist/reghex-babel.js"},"./macro":{"require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@babel/core":"7.15.0","@babel/plugin-transform-modules-commonjs":"^7.15.0","@babel/plugin-transform-template-literals":"^7.14.5","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^20.0.0","@rollup/plugin-node-resolve":"^13.0.4","@rollup/pluginutils":"^4.1.1","@sucrase/jest-plugin":"^2.1.1","babel-jest":"^27.1.0","babel-plugin-closure-elimination":"^1.3.2","husky-v4":"^4.3.8","jest":"^27.1.0","lint-staged":"^11.1.2","npm-run-all":"^4.1.5","prettier":"^2.3.2","rimraf":"^3.0.2","rollup":"^2.56.3"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"@sucrase/jest-plugin"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@3.0.1","dist":{"shasum":"76dd93c0ebef17dfbff0ea6705e9ee764eb36717","integrity":"sha512-4EVlR7D9BMSUcCVtU2LO6iRzcxwgwlQgHa2MBMlHu39SGswa2FueAqVV+LtUNmpm1+eySVeH+04vI4Zaqg9Q2A==","tarball":"https://registry.npmjs.org/reghex/-/reghex-3.0.1.tgz","fileCount":30,"unpackedSize":133661,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhKl0HCRA9TVsSAnZWagAA+LwQAICOZlAUzkKkhQMUGbI4\nJkxQMguiTx2WH83zESfiEuHsZEPwU3UC559yU5x2UfaJ5vjheNEd0mGcCofe\nv+g692Ae0ysrX++pW0upJOCaPlX7WXXPzpR+B5ssfZfAJzBmvih1r/pfM88a\nvLUqcTSC8Mm9UeX1EK4JndoCvGIMOq8btnQ67Y1VpdovmA9/jvqTL8M6A0kw\nF7/FcXIdgIhL+/QHs1+qqZAByQpuelN4PtDP/B97gvdLKD5OOY9pfDEKtsh+\nWvdRTTtylHHdNRj00FUT+d3WCeO4wDmnf8DKkRqppAGkbxf88mS/M52HZyWG\n89EAHkNe8jJ5xz7K+hDQtMVDsDeYy3CLUAS4rgLZTj+lyQraFDVrfK4n5HNQ\njVGboRFBBw3gNiJ56ZB0OmITcxnFMuLldWCrttKLs8zslYP1P08wxdEqo6o6\nBwYQwABsYb/QNywbuK+9L489dzJTTjutQndJiFESbmtrWzwD04iq74d43LaS\n1yVgfH4cBRCGBk2xReE1bGmr4BipHtP26jbNscunIYSExa3450Uox7nlaeY0\nqcKMV685jQ4RCxHoInniw+m8FVDB6HKDY2b/2db1fnSyHDoVeBI/U7T5v+qL\nu3MGLKkV//vVM1vynt06Zc2iL88teb5smv/l5i2qpngLw5Raono347JsbIVa\nbTuX\r\n=d2Yr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDyMSUoiwRT1eZXiULY9xKFuPLDBWWACUqKtLjlfph2lAIgH7EnQV/x+KFAFkkpUpyxzRooPo39UL51Zbn3HsLjlWc="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_3.0.1_1630166279138_0.3462571963001695"},"_hasShrinkwrap":false},"3.0.2":{"name":"reghex","version":"3.0.2","description":"The magical sticky regex-based parser generator 🧙","author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT","main":"dist/reghex-core","module":"dist/reghex-core.mjs","source":"src/core.js","sideEffects":false,"exports":{".":{"import":"./dist/reghex-core.mjs","require":"./dist/reghex-core.js"},"./babel":{"require":"./dist/reghex-babel.js"},"./macro":{"require":"./dist/reghex-macro.js"},"./package.json":"./package.json"},"scripts":{"prepublishOnly":"run-s clean build test","clean":"rimraf dist ./node_modules/.cache","build":"rollup -c rollup.config.js","test":"jest"},"keywords":["regex","sticky regex","parser","parser generator","babel"],"repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"devDependencies":{"@ampproject/rollup-plugin-closure-compiler":"^0.27.0","@babel/core":"7.15.0","@babel/plugin-transform-modules-commonjs":"^7.15.0","@babel/plugin-transform-template-literals":"^7.14.5","@rollup/plugin-buble":"^0.21.3","@rollup/plugin-commonjs":"^20.0.0","@rollup/plugin-node-resolve":"^13.0.4","@rollup/pluginutils":"^4.1.1","@sucrase/jest-plugin":"^2.1.1","babel-jest":"^27.1.0","babel-plugin-closure-elimination":"^1.3.2","husky-v4":"^4.3.8","jest":"^27.1.0","lint-staged":"^11.1.2","npm-run-all":"^4.1.5","prettier":"^2.3.2","rimraf":"^3.0.2","rollup":"^2.56.3"},"prettier":{"singleQuote":true},"lint-staged":{"*.{js,jsx,json,md}":"prettier --write"},"husky":{"hooks":{"pre-commit":"lint-staged --quiet --relative"}},"jest":{"testEnvironment":"node","transform":{"\\.js$":"@sucrase/jest-plugin"}},"licenseText":"MIT License\n\nCopyright (c) 2020 Phil Plückthun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"reghex@3.0.2","dist":{"shasum":"984045126642ee0709c3e10727e7041112281330","integrity":"sha512-Zb9DJ5u6GhgqRSBnxV2QSnLqEwcKxHWFA1N2yUa4ZUAO1P8jlWKYtWZ6/ooV6yylspGXJX0O/uNzEv0xrCtwaA==","tarball":"https://registry.npmjs.org/reghex/-/reghex-3.0.2.tgz","fileCount":30,"unpackedSize":137381,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhKmaXCRA9TVsSAnZWagAA5ZYP/2m1eDfyAC75ceCUIFBq\nF0wkiaugn2SNaay84g5bSTbQ/wPLgALQi6kPmoxQkORK6+lIeeXFGXXODtH0\nbHZfDeJS4nbuGMnptD1H18JXQP0nFDFyod7VrhzUXmNRc5rDHfi2rYpBleRa\nFBKL6g5pfvUXlkvkMAH5zTZsElwPpTMmAeIbQJAOSBojQde8NwHwtm+bPBGs\nMedcsr/xkOaMS2RI0qVDfJL22J0qyQNqGe01q8eYblOyFZhmPKyXQphct5ZA\njrEwgARNSoZ1SHLhho8whZUQ45ncaSgaL9gBa6B+sPmHn1HfbfB/U7Wx7hQh\ndgUFjbrvaaUUsvS3b1k7F748vL9fPY39pOVijBlxfTIqeFVzccye8pG300F6\nsq0/9sX7q9/7/xNfQdN8imfZPc9Wya2EzviVHlSU5/DInQ/IzOZqgl16nj9n\nEaLSODXlVw4cHMZ9b32rPbUpn7mv+Ph/wXCHmQEe6Buorb4M0IxIxzCiuZUq\nHcMP15nwQiFLAj7GiGjjD/qRMgCeO0qfitDQDNAJ00Kqdnphqz66U3sUArnm\nkorfXwBQRFNGh2Fz9KyEEP2ihvXIpIImpjEOnKjc1Ah2ICHJ4BHEVMZiyDjj\nkzDwnWEDeI0q7JdPmDauqrLEnnBl0BI1TgvtS96E1KxpmyC55D8UW6B8R+2u\nd8PS\r\n=c7LC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDi0g5xESuDs7jDOuXt8ltrxjhYGJ4RGKP93r6U0uiZegIgdMODrtxxG/+cOX137H6isLuXUUbosp49OUKkcmx/9hY="}]},"_npmUser":{"name":"philpl","email":"phil@kitten.sh"},"directories":{},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/reghex_3.0.2_1630168727772_0.18083782492924683"},"_hasShrinkwrap":false}},"maintainers":[{"name":"philpl","email":"phil@kitten.sh"}],"description":"The magical sticky regex-based parser generator 🧙","repository":{"type":"git","url":"https://github.com/kitten/reghex"},"bugs":{"url":"https://github.com/kitten/reghex/issues"},"readme":"<div align=\"center\">\n  <img alt=\"reghex\" width=\"250\" src=\"docs/reghex-logo.png\" />\n  <br />\n  <br />\n  <strong>\n    The magical sticky regex-based parser generator\n  </strong>\n  <br />\n  <br />\n  <br />\n</div>\n\nLeveraging the power of sticky regexes and JS code generation, `reghex` allows\nyou to code parsers quickly, by surrounding regular expressions with a regex-like\n[DSL](https://en.wikipedia.org/wiki/Domain-specific_language).\n\nWith `reghex` you can generate a parser from a tagged template literal, which is\nquick to prototype and generates reasonably compact and performant code.\n\n_This project is still in its early stages and is experimental. Its API may still\nchange and some issues may need to be ironed out._\n\n## Quick Start\n\n##### 1. Install with yarn or npm\n\n```sh\nyarn add reghex\n# or\nnpm install --save reghex\n```\n\n##### 2. Add the plugin to your Babel configuration _(optional)_\n\nIn your `.babelrc`, `babel.config.js`, or `package.json:babel` add:\n\n```json\n{\n  \"plugins\": [\"reghex/babel\"]\n}\n```\n\nAlternatively, you can set up [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros) and\nimport `reghex` from `\"reghex/macro\"` instead.\n\nThis step is **optional**. `reghex` can also generate its optimised JS code during runtime.\nThis will only incur a tiny parsing cost on initialisation, but due to the JIT of modern\nJS engines there won't be any difference in performance between pre-compiled and compiled\nversions otherwise.\n\nSince the `reghex` runtime is rather small, for larger grammars it may even make sense not\nto precompile the matchers at all. For this case you may pass the `{ \"codegen\": false }`\noption to the Babel plugin, which will minify the `reghex` matcher templates without\nprecompiling them.\n\n##### 3. Have fun writing parsers!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nparse(name)('hello');\n// [ \"hello\", .tag = \"name\" ]\n```\n\n## Concepts\n\nThe fundamental concept of `reghex` are regexes, specifically\n[sticky regexes](https://www.loganfranken.com/blog/831/es6-everyday-sticky-regex-matches/)!\nThese are regular expressions that don't search a target string, but instead match at the\nspecific position they're at. The flag for sticky regexes is `y` and hence\nthey can be created using `/phrase/y` or `new RegExp('phrase', 'y')`.\n\n**Sticky Regexes** are the perfect foundation for a parsing framework in JavaScript!\nBecause they only match at a single position they can be used to match patterns\ncontinuously, as a parser would. Like global regexes, we can then manipulate where\nthey should be matched by setting `regex.lastIndex = index;` and after matching\nread back their updated `regex.lastIndex`.\n\n> **Note:** Sticky Regexes aren't natively\n> [supported in any versions of Internet Explorer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky#Browser_compatibility). `reghex` works around this by imitating its behaviour, which may decrease performance on IE11.\n\nThis primitive allows us to build up a parser from regexes that you pass when\nauthoring a parser function, also called a \"matcher\" in `reghex`. When `reghex` compiles\nto parser code, this code is just a sequence and combination of sticky regexes that\nare executed in order!\n\n```js\nlet input = 'phrases should be parsed...';\nlet lastIndex = 0;\n\nconst regex = /phrase/y;\nfunction matcher() {\n  let match;\n  // Before matching we set the current index on the RegExp\n  regex.lastIndex = lastIndex;\n  // Then we match and store the result\n  if ((match = regex.exec(input))) {\n    // If the RegExp matches successfully, we update our lastIndex\n    lastIndex = regex.lastIndex;\n  }\n}\n```\n\nThis mechanism is used in all matcher functions that `reghex` generates.\nInternally `reghex` keeps track of the input string and the current index on\nthat string, and the matcher functions execute regexes against this state.\n\n## Authoring Guide\n\nYou can write \"matchers\" by importing the `match` import from `reghex` and\nusing it to write a matcher expression.\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n```\n\nAs can be seen above, the `match` function, is called with a \"node name\" and\nis then called as a tagged template. This template is our **parsing definition**.\n\n`reghex` functions only with its Babel plugin, which will detect `match('name')`\nand replace the entire tag with a parsing function, which may then look like\nthe following in your transpiled code:\n\n```js\nimport { _pattern /* ... */ } from 'reghex';\n\nvar _name_expression = _pattern(/\\w+/);\nvar name = function name() {\n  /* ... */\n};\n```\n\nWe've now successfully created a matcher, which matches a single regex, which\nis a pattern of one or more letters. We can execute this matcher by calling\nit with the curried `parse` utility:\n\n```js\nimport { parse } from 'reghex';\n\nconst result = parse(name)('Tim');\n\nconsole.log(result); // [ \"Tim\", .tag = \"name\" ]\nconsole.log(result.tag); // \"name\"\n```\n\nIf the string (Here: \"Tim\") was parsed successfully by the matcher, it will\nreturn an array that contains the result of the regex. The array is special\nin that it will also have a `tag` property set to the matcher's name, here\n`\"name\"`, which we determined when we defined the matcher as `match('name')`.\n\n```js\nimport { parse } from 'reghex';\nparse(name)('42'); // undefined\n```\n\nSimilarly, if the matcher does not parse an input string successfully, it will\nreturn `undefined` instead.\n\n### Nested matchers\n\nThis on its own is nice, but a parser must be able to traverse a string and\nturn it into an [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree).\nTo introduce nesting to `reghex` matchers, we can refer to one matcher in another!\nLet's extend our original example;\n\n```js\nimport { match } from 'reghex';\n\nconst name = match('name')`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n```\n\nThe new `hello` matcher is set to match `/hello /` and then attempts to match\nthe `name` matcher afterwards. If either of these matchers fail, it will return\n`undefined` as well and roll back its changes. Using this matcher will give us\n**nested abstract output**.\n\nWe can also see in this example that _outside_ of the regex interpolations,\nwhitespace and newlines don't matter.\n\n```js\nimport { parse } from 'reghex';\n\nparse(hello)('hello tim');\n/*\n  [\n    \"hello\",\n    [\"tim\", .tag = \"name\"],\n    .tag = \"hello\"\n  ]\n*/\n```\n\nFurthermore, interpolations don't have to just be RegHex matchers. They can\nalso be functions returning matchers or completely custom matching functions.\nThis is useful when your DSL becomes _self-referential_, i.e. when one matchers\nstart referencing each other forming a loop. To fix this we can create a\nfunction that returns our root matcher:\n\n```js\nimport { match } from 'reghex';\n\nconst value = match('value')`\n  (${/\\w+/} | ${() => root})+\n`;\n\nconst root = match('root')`\n  ${/root/}+ ${value}\n`;\n```\n\n### Regex-like DSL\n\nWe've seen in the previous examples that matchers are authored using tagged\ntemplate literals, where interpolations can either be filled using regexes,\n`${/pattern/}`, or with other matchers `${name}`.\n\nThe tagged template syntax supports more ways to match these interpolations,\nusing a regex-like Domain Specific Language. Unlike in regexes, whitespace\nand newlines don't matter, which makes it easier to format and read matchers.\n\nWe can create **sequences** of matchers by adding multiple expressions in\na row. A matcher using `${/1/} ${/2/}` will attempt to match `1` and then `2`\nin the parsed string. This is just one feature of the regex-like DSL. The\navailable operators are the following:\n\n| Operator | Example            | Description                                                                                                                                                                              |\n| -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `?`      | `${/1/}?`          | An **optional** may be used to make an interpolation optional. This means that the interpolation may or may not match.                                                                   |\n| `*`      | `${/1/}*`          | A **star** can be used to match an arbitrary amount of interpolation or none at all. This means that the interpolation may repeat itself or may not be matched at all.                   |\n| `+`      | `${/1/}+`          | A **plus** is used like `*` and must match one or more times. When the matcher doesn't match, that's considered a failing case, since the match isn't optional.                          |\n| `\\|`     | `${/1/} \\| ${/2/}` | An **alternation** can be used to match either one thing or another, falling back when the first interpolation fails.                                                                    |\n| `()`     | `(${/1/} ${/2/})+` | A **group** can be used to apply one of the other operators to an entire group of interpolations.                                                                                        |\n| `(?: )`  | `(?: ${/1/})`      | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `(?= )`  | `(?= ${/1/})`      | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `(?! )`  | `(?! ${/1/})`      | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nA couple of operators also support \"short hands\" that allow you to write\nlookaheads or non-capturing groups a little quicker.\n\n| Shorthand | Example   | Description                                                                                                                                                                              |\n| --------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `:`       | `:${/1/}` | A **non-capturing group** is like a regular group, but the interpolations matched inside it don't appear in the parser's output.                                                         |\n| `=`       | `=${/1/}` | A **positive lookahead** checks whether interpolations match, and if so continues the matcher without changing the input. If it matches, it's essentially ignored.                       |\n| `!`       | `!${/1/}` | A **negative lookahead** checks whether interpolations _don't_ match, and if so continues the matcher without changing the input. If the interpolations do match the matcher is aborted. |\n\nWe can combine and compose these operators to create more complex matchers.\nFor instance, we can extend the original example to only allow a specific set\nof names by using the `|` operator:\n\n```js\nconst name = match('name')`\n  ${/tim/} | ${/tom/} | ${/tam/}\n`;\n\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tom'); // [ \"tom\", .tag = \"name\" ]\nparse(name)('patrick'); // undefined\n```\n\nThe above will now only match specific name strings. When one pattern in this\nchain of **alternations** does not match, it will try the next one.\n\nWe can also use **groups** to add more matchers around the alternations themselves,\nby surrounding the alternations with `(` and `)`\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim!'); // [ \"tim\", \"!\", .tag = \"name\" ]\nparse(name)('tom!'); // [ \"tom\", \"!\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nMaybe we're also not that interested in the `\"!\"` showing up in the output node.\nIf we want to get rid of it, we can use a **non-capturing group** to hide it,\nwhile still requiring it.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/}) (?: ${/!/})\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // undefined\n```\n\nLastly, like with regexes, `?`, `*`, and `+` may be used as \"quantifiers\". The first two\nmay also be optional and _not_ match their patterns without the matcher failing.\nThe `+` operator is used to match an interpolation _one or more_ times, while the\n`*` operators may match _zero or more_ times. Let's use this to allow the `\"!\"`\nto repeat.\n\n```js\nconst name = match('name')`\n  (${/tim/} | ${/tom/})+ (?: ${/!/})*\n`;\n\nparse(name)('tim!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim!!!!'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('tim'); // [ \"tim\", .tag = \"name\" ]\nparse(name)('timtim'); // [ \"tim\", tim\", .tag = \"name\" ]\n```\n\nAs we can see from the above, like in regexes, quantifiers can be combined with groups,\nnon-capturing groups, or other groups.\n\n### Transforming as we match\n\nIn the previous sections, we've seen that the **nodes** that `reghex` outputs are arrays containing\nmatch strings or other nodes and have a special `tag` property with the node's type.\nWe can **change this output** while we're parsing by passing a function to our matcher definition.\n\n```js\nconst name = match('name', (x) => x[0])`\n  (${/tim/} | ${/tom/}) ${/!/}\n`;\n\nparse(name)('tim'); // \"tim\"\n```\n\nIn the above example, we're passing a small function, `x => x[0]` to the matcher as a\nsecond argument. This will change the matcher's output, which causes the parser to\nnow return a new output for this matcher.\n\nWe can use this function creatively by outputting full AST nodes, maybe even like the\nones that resemble Babel's output:\n\n```js\nconst identifier = match('identifier', (x) => ({\n  type: 'Identifier',\n  name: x[0],\n}))`\n  ${/[\\w_][\\w\\d_]+/}\n`;\n\nparse(name)('var_name'); // { type: \"Identifier\", name: \"var_name\" }\n```\n\nWe've now entirely changed the output of the parser for this matcher. Given that each\nmatcher can change its output, we're free to change the parser's output entirely.\nBy returning `null` or `undefined` in this matcher, we can also change the matcher\nto not have matched, which would cause other matchers to treat it like a mismatch!\n\n```js\nimport { match, parse } from 'reghex';\n\nconst name = match('name')((x) => {\n  return x[0] !== 'tim' ? x : undefined;\n})`\n  ${/\\w+/}\n`;\n\nconst hello = match('hello')`\n  ${/hello /} ${name}\n`;\n\nparse(name)('tom'); // [\"hello\", [\"tom\", .tag = \"name\"], .tag = \"hello\"]\nparse(name)('tim'); // undefined\n```\n\nLastly, if we need to create these special array nodes ourselves, we can use `reghex`'s\n`tag` export for this purpose.\n\n```js\nimport { tag } from 'reghex';\n\ntag(['test'], 'node_name');\n// [\"test\", .tag = \"node_name\"]\n```\n\n### Tagged Template Parsing\n\nAny grammar in RegHex can also be used to parse a tagged template literal.\nA tagged template literal consists of a list of literals alternating with\na list of \"interpolations\".\n\nIn RegHex we can add an `interpolation` matcher to our grammars to allow it\nto parse interpolations in a template literal.\n\n```js\nimport { interpolation } from 'reghex';\n\nconst anyNumber = interpolation((x) => typeof x === 'number');\n\nconst num = match('num')`\n  ${/[+-]?/} ${anyNumber}\n`;\n\nparse(num)`+${42}`;\n// [\"+\", 42, .tag = \"num\"]\n```\n\nThis grammar now allows us to match arbitrary values if they're input into the\nparser. We can now call our grammar using a tagged template literal themselves\nto parse this.\n\n**That's it! May the RegExp be ever in your favor.**\n","readmeFilename":"README.md","keywords":["regex","sticky regex","parser","parser generator","babel"],"author":{"name":"Phil Pluckthun","email":"phil@kitten.sh"},"license":"MIT"}