{"_id":"@atomist/microgrammar","_rev":"107-db9f17c1487bae101a8fe6edf0920bc0","name":"@atomist/microgrammar","description":"Parsing library filling the gap between regular expressions and complete grammars","dist-tags":{"latest":"1.2.1","branch-master":"1.2.1-master.20190720154946","next":"1.2.1-master.20190720154946","branch-grammar":"1.0.3-grammar.20190111181509","branch-nortissej-failure-reporting":"1.0.4-nortissej.failure-reporting.20190130180617","branch-updateStructure":"1.2.0-updateStructure.20190221054155","branch-matchReportIterator":"1.2.0-matchReportIterator.20190222200743"},"versions":{"0.1.0":{"name":"@atomist/microgrammar","version":"0.1.0","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{"lodash":"^4.17.4"},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"f397293812969c2c95f9ddc6d33380000f32aaaa","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.1.0","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-DQ7Uudn3Qeu34wPcZAA5WiXCV8fAqcp/yMlRFUeaKnAHskM6Yb0hWpshPLZyXF0tfoZjDqRKQ3RIkwWIcC6ivA==","shasum":"e09739fcca7405af25194713280bb376aaa0bb2d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.1.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC35/vNAjJd3A7PnnjSnwf/rZXBX6c1iPVi2gaBUTZ/OAiEAjPPML69WzC5ldLid2zbCYZoFnL66XOi3MZY6P9V30R8="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.1.0.tgz_1498016622328_0.035139195388183"}},"0.2.0":{"name":"@atomist/microgrammar","version":"0.2.0","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{"lodash":"^4.17.4"},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"f2bc4f5626ab9a99d07b5a891c2d9f36a3345afa","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.2.0","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-yRTWu8dKa3lWjcJyjapLQle6vtMGafRltBdsEYPyRwcFP7eUZ6GqcPELllzbSbxn5JGqui9xDgCXExX4cNeSaA==","shasum":"19de219bf89778ef3d55970ddb2c512fdb4cac1d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.2.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCc2ejXz/cLc7u+ng0/iUVvBOZWGZBYzjZzG3vmaiOIhAIgESSRuikctHtkTSLJQODkE0a7WIZu13bvU512IujOgEg="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.2.0.tgz_1498102695649_0.3916445269715041"}},"0.3.1":{"name":"@atomist/microgrammar","version":"0.3.1","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"2a1d04b8dce85f3c4f7ada301aa7173f908369aa","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.1","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-/OL2gG4f4EyGCS2vOc2wuJyUNBVValLisbMxcacEmGeg1Nr+1EJbVkw/wIeDZBZ+T+GB0xz3wBsm27TLm+tZ8A==","shasum":"26120677de9a35e9cb858cbf2e86d4ae81178bf5","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHyYwZC7X10KTOT4koVmywBqNe+CCPyWakE/hkNGl43wAiAza1ykMsBKgfq5mD92Ff8CRNObfNcAD1ZOGdNKLdRvjQ=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.1.tgz_1498177772352_0.0639629983343184"}},"0.3.3":{"name":"@atomist/microgrammar","version":"0.3.3","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"27c59bf0fb210293c3d9c482aeb74ddc697c3e96","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.3","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-wnNTQgkDHsUsZbkitafipL8Vft09gdEZW2ZradIp+sYKoUVd9tlEA2VrPz73nx8DBdHCGw4vRqld1AodQ910Ow==","shasum":"e2fdd97bbe285d1d4b1d75be6791fae58bc3a427","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.3.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEXycTgl6lbTlFXnP3of05AZGEPj9kgn4a0nDRusJ+qyAiA/OKHo0qyNgxo2C6yJGRoFQO0inX/D/dLhTai5UsMsig=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.3.tgz_1498179559185_0.7116763072554022"}},"0.3.4":{"name":"@atomist/microgrammar","version":"0.3.4","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"7b4c66d0a7a3c5d4bfdfbd9e095533ced80adb19","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.4","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-+KMmeUpZOPgwTXZ7g8aUdTLAKJqhaleTf8QJT7zCVMcJQrNfHqPljlEhIvtNQ/fTAcd978wA9EHRXJax7vInTA==","shasum":"613db4b8c3e04072f59d04ed12a3a8ef0069b63c","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.4.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDF40OY0YPl7+i7jgkwp12q6cv70DmlNyVNkBd4Lmp4CwIgDSZj0HwHhIAmmW2os2Q2fhXiMj1EkDHGRg9/hwt33pg="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.4.tgz_1498180151839_0.04790087044239044"}},"0.3.5":{"name":"@atomist/microgrammar","version":"0.3.5","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"1c22f8e203d71413d6efb4013e93c2acc52c7fa1","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.5","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-hRBiiM3UzVnfNLxmNBFN3kgFNvGL67SFWVwIIclt8/XSCcgVuLfdD0mMDjG3wSeWTuPQe19EDCj5nZDBoj1x9Q==","shasum":"57dd1dcb98d1418ebd805ecd1e124015d189bfdd","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.5.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICS2p0gLloptInrEM8MsA28L8OFopbLth84uDuShvdTcAiEAz6bgSYKzzUX/V5Gpr1JMBTOTTD51d+ha/b55eZJPJNw="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.5.tgz_1498181864410_0.6538975674193352"}},"0.3.6":{"name":"@atomist/microgrammar","version":"0.3.6","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"ebd8fa4692b6ee9acb489364e9d54207c3742464","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.6","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-rS0pw/727gS/uErBOWEDC7V4imZzybCrLu6pGJxCRQpx2n2NqfKOHEwR/d6XnA9IX0NwAU9VQA0vshvIaDj4Ag==","shasum":"1c64c625c0b837290609a6dc4fd22e9d9a943118","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.6.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHKwq6BOksulGCFArx0XLNZsYiathVWDnnd0PbSgitMgAiBFffs30NQPVeNb5LAs+e6uUZZm28wgdv6Oh9B+62Et2Q=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.6.tgz_1498283329583_0.08630220894701779"}},"0.3.7":{"name":"@atomist/microgrammar","version":"0.3.7","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"234a142dd657bdae9e3706457f14c03c15e87ef9","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.7","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-eekHdaCg33Lc/PWAg3z+hOIeohqhLL8k+XdqnVqDfrMyhAQZp8dLI3lLCWrULMKKz60MAeqtPRV+ypBYl9SfwQ==","shasum":"afb914ea011142c2b65bae68a8b4b65e49a01049","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.7.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFbfKV7WCpAcBrTbqeju91ecaPwgM9XF6MSBUs746OpWAiEAvdAHFEnr8d/Ge+yO1Ey0vZ5FcgQIC69thpd/O+iLznY="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.7.tgz_1498437215400_0.707128808600828"}},"0.3.9":{"name":"@atomist/microgrammar","version":"0.3.9","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"c718ef446c22f22c213fd93310187a5ed33acb3c","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.9","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-dcj7t9VP6iIIU6F3hpf1XnZj3XhiHRF8/+Z79qo8+mjhYM3Ajj6X2R067fZRgXx2kgFcbBuS/1F+fs6PXrpCmg==","shasum":"80d8ebc5ac4a84d1cf48e2b15a48e4bedecaf174","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.9.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC0xzyUWAUm+/6skA4oRp9LLtLbeZli7wgrOpSYrtZtkAIhAIaofeorrvvm/k/h6USV2egOKUGh72IWP10L1z2/AkFs"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.9.tgz_1498464281447_0.37125448836013675"}},"0.3.10":{"name":"@atomist/microgrammar","version":"0.3.10","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/lodash":"^4.14.66","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"401d444cb3192454780a12d8e505f5ffaafa88b6","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.10","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-d7hOX++1bOhHxOnwV4a6DedpS/fJE455wAEvzhemQFSkvy4bJ7TubEYgdc+ACsUB/EgUbV8biO+buv+yC7o9aA==","shasum":"2f89d8643fcc38a552f434c3cbe5081bf6396c7d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.10.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDH/uIMRJRY4rJ2e+1hcSGuRxQukHsLRigZ2MdQFIGSUAIgGLyFeNg6PQxZewwfTlSEQT0Ss+6FJVEL3Ocyqtz22zY="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.10.tgz_1498473181884_0.6472370738629252"}},"0.3.11":{"name":"@atomist/microgrammar","version":"0.3.11","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess 'test/**/*.ts'"},"gitHead":"f77f465703908c94f9ea3069f338676c101853af","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.11","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-tcQQ6+NU/Ou3Epsqv9kiLMg3YpbHTetMXgbVV06nR9lYhlGydxhwfUfsHYrT3nKnsjPiVHkF8qwCejrJIkAeWg==","shasum":"8c8adb1af899825de129c1da168b08f0b666cfaa","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.11.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBGJinhCQR3EbJcTuR0nGU/0XHaoqBAR5b+wLvQdolG/AiA/yEo8lP6eUPuWoqY5YVf7Et7xnlLcRNwXDesFBvGpdw=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.11.tgz_1498748657755_0.3692577325273305"}},"0.3.12":{"name":"@atomist/microgrammar","version":"0.3.12","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\""},"gitHead":"cc7882ea09d3bcd031021f395f83a72289fa0fc0","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.3.12","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-lcIyx0CUOXxEFyoX031JAdG48COdAjS+JWrTvJ1tH+7i8KyihbCyX/fqn/Ls+0sPfBt/juW3n/axYMk2bR70Xw==","shasum":"f81cec5b1bf4b33cabce4342a1b1cd3f3938e3de","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.3.12.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICp+JeD0grJELhc/PvEr8vIVUUKXykVuWKch+TxSfBlUAiBsNIiF98q+yx1u8tg7BdUHFnCvWxH0e9AwOfxreHBcyA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.3.12.tgz_1498784273769_0.630552674876526"}},"0.4.0":{"name":"@atomist/microgrammar","version":"0.4.0","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.0","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\""},"gitHead":"221ec8a44a968a3e705342e5bbf5234019966caf","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.4.0","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-4QR4tgH08nHv10fVmLAR3VDkKJ36HgObBt94TmA60qXFg+bR3DbILdrn8XhA9CK7RZlOrwZ3rNRgLlJYXaldHg==","shasum":"f8b075241f5f6bb7f890cd3d09e434b760bb4f10","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.4.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDNmPvp/V4udrPT7NJ4FZSr79x9Q/tQHoWUkvCERz7S0QIgXk0XHV7dzwdDQQWgtLoFMHs8xHQKVA/eKOQAjBOFRfo="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.4.0.tgz_1499044501574_0.15214548888616264"}},"0.5.0":{"name":"@atomist/microgrammar","version":"0.5.0","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.2","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\""},"gitHead":"6646832d55f6d5d8c19d41a7fc2f28fd11b310c8","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.5.0","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-PAq0D5sZW+xTrPcz24ltTYa7K4KaulbEEZC+2w5gHpckrdzx9moGAx7apS5lM+USRikFRBqMF+IFzGvDO4YI6Q==","shasum":"bf87c8f5978ae5eca102e6960d36c791d17fa834","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.5.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC6loMsYsg32+bWO+MfgusHuf7QghnJpp7q+P6IYSjvSAIgctWEmng47kC5VR0wZ98HonksBT8cfJwTQddAXW2EyeM="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.5.0.tgz_1499587714843_0.8706700408365577"}},"0.5.1":{"name":"@atomist/microgrammar","version":"0.5.1","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.2","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","test":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\""},"gitHead":"a0ac275065a09b9fb0b49fc1ba3c749dc80840ee","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.5.1","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-TyOpR5YIVGISZoEXE4cvAVWEIUv4BLX/voch2MuljslgRvV9EE7F3v83eXY31NxgD3El+BAqaJWAM3VLH06d7Q==","shasum":"ce13d5b5e6dd3a5c8c7f28ae38eb088c74ea1a05","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.5.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCggF8VDxcqHAt/fV23j/TGgjyX7Z/MfrrWolHmP9R49QIhAJjSdE412dW8CQRpaQVUheqK5Akub7suPCP/peNZ7jkK"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.5.1.tgz_1499590586315_0.2431278033182025"}},"0.6.0":{"name":"@atomist/microgrammar","version":"0.6.0","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.2","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -f *-v8.log; rm -f profile.txt; rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","test":"mocha --compilers ts:espower-typescript/guess \"test/**/!(*Benchmark).ts\"","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt"},"gitHead":"f3cf6061296ed1ab2834a210b379f8206494acad","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar) [![Slack Status](https://join.atomist.com/badge.svg)](https://join.atomist.com)","_id":"@atomist/microgrammar@0.6.0","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-VrmXOzOYG/sUJj0Vq/txsOouZQiicDUZuQy2Vsh5wAUhaMsTyHdhCWmNEwOinVzZnjKGHxBT0CBYgsw+bkUA2g==","shasum":"932ed844f31a3f563350fa533b175b38fa55e4b6","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.6.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD9K3y85WL9Q2N/PyxKIyJfzGQtouzWJgncUnFToMExPQIhANcyN1SfoftTwg66jOpC46dyFcdBRzNMfIXpBeWu6Xm9"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.6.0.tgz_1501444217590_0.8085816411767155"}},"0.6.1":{"name":"@atomist/microgrammar","version":"0.6.1","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.2","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -f *-v8.log; rm -f profile.txt; rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","test":"mocha --compilers ts:espower-typescript/guess \"test/**/!(*Benchmark).ts\"","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt"},"gitHead":"0919c288bf9e78b6a5b05627902dfb7df162dc46","description":"[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)","_id":"@atomist/microgrammar@0.6.1","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-+tgiRUFfbFsy958CEUskxHSxSsDN5bYwEQQ7Ey97pbDX9MxQVhHS3zs9BMMHkDWOrDT8FTmz0ZtD/aHgJyCWZw==","shasum":"9d4c551ef3404658a471ea99a6afddc58fa57a9c","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.6.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBhzrzUfqZ5riYqZ3x4LWIPczjkUDpu3P4P/nQRZ7rBoAiEA716hHLZMD9ykqG2TFihdSI+5ftCBUeyPpG6F9DZdLWQ="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.6.1.tgz_1505545670673_0.41046282975003123"}},"0.6.2":{"name":"@atomist/microgrammar","version":"0.6.2","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","rug"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.2","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.4.3","typescript":"2.3.4"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -e ts -x npm -- run test","clean":"rm -f *-v8.log; rm -f profile.txt; rm -rf build ; find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","lint":"tslint '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","fix":"tslint --fix '**/*.ts' --exclude 'node_modules/**' --exclude 'build/**' -t verbose","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","test":"mocha --compilers ts:espower-typescript/guess \"test/**/!(*Benchmark).ts\"","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt"},"gitHead":"619350b12ea3adb46054b6ac265212368ba073c1","_id":"@atomist/microgrammar@0.6.2","_npmVersion":"5.0.3","_nodeVersion":"8.1.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-Sk5zxYcscDTZgct8Pg/z+gFthaLnnNvbA8Y6l5IE+KG9yym6ejvLV+jqFJcHICLqWIOnqrK63UZv3XMnXHcRwg==","shasum":"c5fcf6d3d85e84140997f9a6e6cee509ef80e96b","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.6.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBJFaPvcCMB1G33OtADnp69TpW2N7AsYTKBL2fVbHRw9AiEAyk9pKPEwxUYA7rrOQQzPorlPPv3V88HaqQoQ+Y7Ea0g="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.6.2.tgz_1506240594667_0.5981181643437594"}},"0.7.0":{"name":"@atomist/microgrammar","version":"0.7.0","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.41","@types/power-assert":"^1.4.29","chai":"^4.0.2","espower-typescript":"^8.0.2","mocha":"^3.4.2","power-assert":"^1.4.4","supervisor":"^0.12.0","tslint":"^5.6.0","typedoc":"^0.8.0","typescript":"^2.5.1","typescript-formatter":"^6.0.0"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint-fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"typedoc --mode modules --excludeExternals","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt"},"gitHead":"4302de95baa4b5c620037941b06eceae31eede5a","_id":"@atomist/microgrammar@0.7.0","_npmVersion":"5.3.0","_nodeVersion":"8.4.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-RtdJA8QodmVchEdWDvLOaeYrASU8Y12/pFHqDOXkGyjgmP+svZaHL2YEdGDjy++ArVL3lpCNXG7ZPYPjVKTugQ==","shasum":"372d817e659a284aafa3aa6b7c26a9de1067d44a","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.7.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID1SlEVgXkOsLMwMzL2NFeSKFh3TEyfvUv+N6C+vVC5SAiEA6AKEzwWmmCaRvGCAvTdaS4X9w9GodZHNJHQ+RQXrAiY="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar-0.7.0.tgz_1507074929349_0.3572715297341347"}},"0.8.0-20180803150803":{"name":"@atomist/microgrammar","version":"0.8.0-20180803150803","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{"@types/lodash":"^4.14.112"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.48","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^3.3.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"2.9.*","typescript-formatter":"^6.1.0"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"typedoc --mode modules --excludeExternals"},"gitHead":"73aaa0be00f859aa768dfa303f14c51a0d010799","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.8.0-20180803150803","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-27miwFfoQgdDjL5gDYG15/iPjrgX1bXh61i1aWyzZyjbFUfokwdPg1IMgLMGtWza1viIaewmtxodMqVzSTuvwg==","shasum":"4188f783182042b598045240c9c3cd2e74cb571e","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.0-20180803150803.tgz","fileCount":168,"unpackedSize":282567,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbZHAhCRA9TVsSAnZWagAAb+EP/iU3gjoJ/mHurwh3tHyT\n13ifE3UPFrnC9asp5VbkrWErkUGUIxbhh6jmPnifVVX18tKA3BL6M1qLB+T/\nobDbwlNduNCwM9jj9TIPXAX7/Dm6ZlNMTtOq9mcvkFMtNeE0xhohMOnYIX4f\nHx668JRNj7DXKT4ngXHEo5OhQZpuF4ylaYqRs+MfXj7XUPsXvlFz+waBmUrY\nY28uETvh2Pa7B1s+w/sD9v/PjnlCv0pWwzQRQ7VH/f34UBpqfOs+7cJyrWIC\nzKr/MfDTQlOlC92Wai8uWl5BdUWYGIcSKqvbcX6AeM17F/qjpT6mExt4n6jz\n+4Hs/b7ltElKjU9IILmE4UlUtKnkyKW/1nCrN4XTsLjAZz0N/YHQleOKCOXn\nRCDz+u0pp5zwkuVGC3zB134R7AUdDspO1Gp/owwRzCPZarFKyZIWyK7m76p+\nFg7/UoNW7EqZYtVCfMMprmfjXLBHcNNLBzPEtIGLLpx9un6uHRB5huObz8YQ\ndHKjschljDoBvHAPB2WqQW2LzbXB7mGMDQgTqCRvfPVX87/UzP6n/fT8iWtn\nHdIZH7dEVmECvPqOSg68XkzMuep4XVWknH4BKhz2KQNikge6MkBAFZJbbND8\nzY/O4dSpjgGyMTdQ+WpqXd5hmVjJPdZBLkUuNtzJJ8KkMOubtHPGWBcsMzjg\nAzdz\r\n=h94x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEaYQvrQy+is6/LqDa/tYvBhH8SfI032PQfCkg26Kqx5AiAH8R1eW4riCqEaVK8XuZlUXATPmmCfTcGruDHv+Pqh8Q=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.0-20180803150803_1533308961236_0.8066461790731967"},"_hasShrinkwrap":false},"0.8.0-20180803150932":{"name":"@atomist/microgrammar","version":"0.8.0-20180803150932","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"GPL-3.0","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{"@types/lodash":"^4.14.112"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^2.2.48","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^3.3.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"2.9.*","typescript-formatter":"^6.1.0"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"typedoc --mode modules --excludeExternals"},"gitHead":"018d4671ba30395b9fedc50bc9be91eb36553975","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.8.0-20180803150932","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-NR54MiD6+LjO55UscCeNDBhTgg1g5sfSu+QDkmW/5gaPN1/lo7YUfkiVdMHEIhTF98P/H+wTZdxW964BQIGfhg==","shasum":"cf5728dbbbe5d039f78c00afa7a9f0b09e6f52b2","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.0-20180803150932.tgz","fileCount":168,"unpackedSize":282567,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbZHCACRA9TVsSAnZWagAAJQMP/2Ydh/o//6V10T82e1B/\nY7SbZif0zf7ww0bvNfoS7g0+hatQhBfy2/SoClVrtw/rP0AcFEfCZ9HbqiPr\nynBzSfqv2zRBFROAgB89i3T8aF7iIa95C47rkMUhRolmPdYq+j3/w/8keMrD\nU4nHQdEMt05p1BegX+EukS7W4vk1ALt3E6x4Jl8qK2MArUbUgHXpwVgd4sSL\ne6WzIPCWWApVkFJszp3FwMN/WPuEyik+K7M5cDEgZm8WYXbZi3GyzxBCO7zS\nsP5P3tSL3QAqmaLJfBtrWxYjiDk+4BY4OWSg+JITGXdTms9UaNFwWlFKIDCq\nKk0XsuMmm57Sibh0JOXMmDCNB9S026G9FqEd4CL00Kjj5ZyQZ/V3DF7rELoA\n5X4c6FpzbjepxbBDwnsOZINL6tZHyxj4rF+jD/RyacTqVF+6S4vObLVtgHvo\n0uzxoyiGj4lRndD4qCbk9AM6NJmHahNeiQ/aGrHPQzjga6mXt3e+3wThl0T3\n36wK3OxKKhquK+0Jex4L4oLbAgsCZ50UBn2c1SIuVGoaNjsTyYyPSYfp5tIu\niSwC9b0j9bc/1/Ijk+Bwg2IG6eVOtwRLKZAtN8Wu5kRpSne9uRp3nxaKlj3I\n4rGIrGlBtFPkf5uOAvpRvWbUIc3NrPa6LtekbCGNZ7l1q8B8gSepUprzH0Fg\nSbll\r\n=8mwg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCopsA+aTL6eubfASMyOeReb5asjBbZf6tUgCp1UuF8awIgLIOel3YgGjWKYqRQ2wmDn4K47EYsW0+V2sZgTXRZZaw="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.0-20180803150932_1533309055583_0.37406818295428224"},"_hasShrinkwrap":false},"0.8.0-20180807201900":{"name":"@atomist/microgrammar","version":"0.8.0-20180807201900","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"SEE LICENSE IN LICENSE","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","microgrammar","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2","typescript-formatter":"^7.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"typedoc --mode modules --excludeExternals"},"gitHead":"2f3d4a140e22f64f47ac1742d4d96268b2403394","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.8.0-20180807201900","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-O9wbEaCqOcJ+1OgfBfPQEegYJ3jXrClPsAMjH5p7AqXYf82FVnbNX8LNKbcY7wv3SEvqdHQbcVlbeLUcrOoh6A==","shasum":"83231905f058cac3b8c57766a76c2648e628b305","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.0-20180807201900.tgz","fileCount":168,"unpackedSize":282223,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbagAlCRA9TVsSAnZWagAAwT0P/1capRiur1dkgIto63uJ\nOgjLryuUcq1e5dkywTYMLUEfgQgsmFRU0GlG1SzBtTy2N+bNU3NhXORDPm8q\nLu9SgioBB4SgeQ48/Js4L8viOwtjdGLLhoTET7YuThzpbO8KlmsfwdIRR+Qx\nUgG7e87RmTLaQg29ueq5QhpMh85kCdwKZj69GCliHeYTMByaqMe48HoMSpTf\nbXawn72Uxs8goW+lZumzFYdDnQjTdEEbhzT5oJHuYKlygZ61Z7WOu40tXqxp\nvgaCV42RiMQpoa0pRZw3VGsQB8MsQpIzdpsfw1UaG9JYfRrOg88mXGJA1Pc9\nHF8GbGL/QjwRDGVu+5iCCk8k83RRwjwRgbVBzFVx9JqCrR/EqFSwylcHBRKy\ngNXWekbh2WeRbMY+65AUIPNjz5L9BZcZn5F8+0QIJcdLoPieVRJEoiqPow36\nZeAG6QMiJyLPx5438XS+p1++aWWFFLFj48XWvUeWIt+JJVywyvQ4nDVJSqHd\nYNN1KKSnAIlxjHBnF6l0g5wafC6BwVor5L1KO8dNAYnqzejoz8RfKSrt6+Qp\nV/WcEim1uCSHfT8d1lVxlIqk/gialdNWicSihQpm18AqgUwZ59WEp2jTVv5/\nk/S3bbFo6hXFjtAlRdSLghRgnqwCKFCqoY4ei5lluqsBhGjGDhFg/0pzv5vm\n5fH4\r\n=EVdh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICD2i69KDl0rBsrXGlk8q8mkQZXmioqQWDL70U0Do8CzAiEAxTA8QpcRyOWsttWyqM27EdRCmN31QetDDnOnrS5vYsE="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.0-20180807201900_1533673508956_0.1467341537476683"},"_hasShrinkwrap":false},"0.8.0":{"name":"@atomist/microgrammar","version":"0.8.0","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"SEE LICENSE IN LICENSE","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","microgrammar","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2","typescript-formatter":"^7.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"typedoc --mode modules --excludeExternals"},"gitHead":"2f3d4a140e22f64f47ac1742d4d96268b2403394","_id":"@atomist/microgrammar@0.8.0","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-ZAyQCI1P0xvvxcLiTMW9zc6UkweKoe2GHovJOa0cLmAH/pVLxP27gYNmcMDl+TSKKTE+L7ldFW3D4+WjP9RwVw==","shasum":"c52c59ce916814647716f92045c4a772943893d3","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.0.tgz","fileCount":168,"unpackedSize":282208,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbagBGCRA9TVsSAnZWagAAM9wP/3xEZD4izBfFhJzPj2YA\nWGet2XZUlRmebCM45747fN6BjzGWGqNRJTzcKJ7ydcKuegK+AMpZh0gLluTj\nH9Xj7HxJsvnCdMZsB6rzSWHy5c4RZr/5OWMv4+XIceUYhlCMeyVVykUOH649\ni4N7VWxddzKW65qypCmOKhTrkL0rrIJ3Nnt1QC8irjm0JhhR7u17IScBokyR\n1MaT4S1yWs5L1DxkM8Bupu6A0SW5AhdIbLlqeJLHiW2CNs4XPTxmVtxsz8Xa\nPAzV1NkawN1zwl8y9LytC9hJgObns+cLovaTSPPCqTe8LMmPTUKgZ5HjYV/a\nojrQfFLgvNrg0U41C1cySKoJx1m1cYdeVxfsVaiOadjDdgLOEmFokG4/qd2u\nvsw3ZlgisMfXxmzJJHz6kQz45MboGttRj2GIBrHIt5sQiIOhu3R+JPAcmZbj\ng2SdBWW74B29RhZSsMY5Qn75PVX0OUXm43RznSgHvMQBPa5GwyyvI8mEbwCG\nCw8X8UjV+5s8EaroGxPNJPF/ITDgGE6ssUJfzrCH3FZwG4fkx370W/DpjrD3\nNPbVWJoLXXKensOygHiCLB83g+MYEoOnkJddWDm7vgEir1wP5OmLEGmxr/Mp\nGxjs7NKhxc3ajouHOstxfDkTRxKg/eEXdJcTC+Qh55mQSlUdX7D2SjOtslXg\nN/ut\r\n=54Sz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDJ8rUf1CcntCZIVJ+X/g0QXi9AheuztTpZYRw7AY3mrwIgb204KWdcvE/yaZj+3SrtVSS/KFztb1w+cMBiFEEi4QM="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.0_1533673542034_0.8354828784249919"},"_hasShrinkwrap":false},"0.8.1-20180807205720":{"name":"@atomist/microgrammar","version":"0.8.1-20180807205720","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"SEE LICENSE IN LICENSE","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","microgrammar","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2","typescript-formatter":"^7.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","doc":"typedoc --mode modules --excludeExternals --out build/typedoc src","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"npm run doc"},"gitHead":"a5f7c5127ef79658606219e9d284c60d6ecaec0c","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.8.1-20180807205720","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-Vf3xOepmr9H1Y8CYc0vVL/yWdKZc5c7O6ufn2xTjrRkv3tCpJBwE0gb4pHzZ9ReWWeHCuOjqFLXR3LbE3iL4vw==","shasum":"43ef2f1533e5de523af940915bde81ba927c424d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.1-20180807205720.tgz","fileCount":168,"unpackedSize":282539,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbaggGCRA9TVsSAnZWagAAZ/oP/ibsuswY4ctfY6PBA4AH\nmlCG1mDVwo6SUatAK/ZRak00/nB9UUatHrY7GCf4trtNs4umq1DEViGsEuIt\nkqrvmtzPvwu2NBdIFijziGLb2r8B1+618tw4Lj9TSS1a1dojX5A3TpHMnxtX\nTXSd6XBNcwHG0COnYxZ/zNpcpLICqFuQmaEEVI4gYJG/2E07EuLNU9h9Nlez\n1H8ROVUbv4TiVbLXWWT+AnOyi+L/Aiq1udebJh56KN+msaZ2Vf6uo1SpRIEO\nBEF74VyQeXW3q2iC+wXhml2gY8OWQlBiJOFeBPNwM3E5bS0/N5lHc0/syV3H\nbrlmLq0naJD0GtDnqtJg/+i+1LBVSzdgy5EFUiRYOvdBrDX4aWYrj7FKN/Qm\n6ILNBY9uu1Z9N0AZRFuL8VOLnONR3Npo3Vy8Gr/JUl7FKTIEKf7yfdhd90T4\nW7UlNaIwsW1z8/uDqoiQZReIJF5Jtc75vnLA3CDvJTRjOFTPY0QqagrYFder\nlIpAc/82Q6gZrxNGGjKOtxxOGaqa54oe4GkTuY8UkSXzX0419VGEud0xKcnb\n5X6fvqKlC02Vj6VTuxbpiTtojJYzRXsXwfhLx+T56Z4f2yzK6b/sk0vWPcE7\nCXf4ZamZbcVo5sPYFL80Wue/DlCVi45U4Bv6WBY4hWVGmysptw/dx2nnAImC\nGHli\r\n=eZDE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGgaIG2r9/wHXcHwA2lGDkLbewJ+1cGMnBjjxyXAUbIPAiBHhwQeFYgtREtBaTvjqZanNfBcr3jWob76fawTMqdVqA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.1-20180807205720_1533675524822_0.8488694293714714"},"_hasShrinkwrap":false},"0.8.1-20180812171823":{"name":"@atomist/microgrammar","version":"0.8.1-20180812171823","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"SEE LICENSE IN LICENSE","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","microgrammar","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2","typescript-formatter":"^7.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","doc":"typedoc --mode modules --excludeExternals --out build/typedoc src","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"npm run doc"},"gitHead":"2ff37075a978178e8c66d7984eec6fc452babd3b","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.8.1-20180812171823","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-R2etxuaUBArZZpxAtLO1bbt+YrxIWyPzhk3JIrQFUlcCUMU89ARbXk6w3F4hhyrUk02ZyhrbVUmPVYVwhIUT5A==","shasum":"a4f8171094713afa81062d746f9c36e74c8dba1a","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.1-20180812171823.tgz","fileCount":172,"unpackedSize":284437,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbcGwtCRA9TVsSAnZWagAAecEP/1eP9J6Uu6Ur0TzoZRAG\nCdzON2J7tneI2H0/OJgwJ6tdj9WTrEJ0yPGA3zX2EG2dxVbWnoXHKEH3OTI6\nsZcDxlAF7RFDwS807PU+mbbhJHF8IxF/KM+XQqmmhoUuWYaoTJlXEVXEHcXF\nJqBmqLWqYc5usTLhJO0x2vwKaZ0Dk5qvBaUAg3gLtg3IXsajzt1KWWFMWIkP\nLzsvDVNHt/8iK1USwhA9aoM10uXWAAwVPB/NiZgF7rF6AJFCD/VioYVoRk58\nQcKfvGHnILbVL0pbQWMTbK2fbkXlXljXymrY+SBY9idauzlxOEEu/MF6PQNu\nZDU4OYH7o2bxk1ErjRT+yjDLq4NNo0mnuh/VBbthF9mopZPiM2LlvQ24yc21\n9XOIUN6RrWK0HCN530bfGDlprq5fxjoaY78beAmxVHHJ38AeSFI2HPDmpgTX\nONIAjvlClzVhxDvGJxnBio07ZCGYfFBthEqpsrvpsnLdeOCl0CxwbM7vCjCu\n7aej8VPtdwJcgT5P1GXHP2BZAwUopTTSkZUxc3xd7xtWrRxHx0HOuwrADM0i\nzGq+w44drnwvmeJf6dl8sWky9GhRiZ/Hu8mYRYT/GDX5D5q6rF6CHAMrBctA\n+IdrgaTKVbVyAIac9MG08beTQPWQBQIdoWCMersu9I0l2SX01cmFuDqxyGve\nmx2s\r\n=AxEw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICDhzDfiwzsecpvuYQM/R1SQ2pOZfssQ2KmwtnzkAoAAAiEAw0R8e5DvPbjz+yzsR1H1/ropOjl+ceD5AhqPqGUrIlo="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.1-20180812171823_1534094380759_0.4647190938668657"},"_hasShrinkwrap":false},"0.8.1":{"name":"@atomist/microgrammar","version":"0.8.1","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"SEE LICENSE IN LICENSE","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","microgrammar","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2","typescript-formatter":"^7.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","doc":"typedoc --mode modules --excludeExternals --out build/typedoc src","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"npm run doc"},"gitHead":"2ff37075a978178e8c66d7984eec6fc452babd3b","_id":"@atomist/microgrammar@0.8.1","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-R2kLDQSHegszG3EUWCYwbheVC7vSzYJCvErktGQqvNheVu42YjGvzr0dl2uVRO30up6x5LHM0HNKhdFNIeChlQ==","shasum":"29f6f3d2397d395971ff75f76b700087ee0bd1d3","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.1.tgz","fileCount":172,"unpackedSize":284422,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbcGx7CRA9TVsSAnZWagAAz4EQAKBcdwUmSUbTpCOHWyCJ\nPddu4FDehkqy0l/ZWYziYS7kYt1G2BZNU3ylkYiyy9RHrDv0QbCFDkAd8Gim\nPyCX9Ughmtiue86AFam6nxBzkhGColYPND2xCQb6+McN4I1sZ2/wLWIr5Cei\neuIY4umpK7Q3HtXYtK1UwhKZvxydk7jaUmpawHJckqknyMy2fKqVa5+EybR/\n1ldFH3RcjpXB3LWF1uwFsrXgGM3z3+kRXQpubztWA7NU2IaT3w/u3VDW+hpd\nmx76Ud3xB3BRA1tPJ8joZF0Pv5Om6VEWD6nPI8TkPvyXD5sRvMaBBhMVulhn\n2mey3qJprEgf+fYksIqQLg/Q1AFgSAye5X2mm/dZ4ymwO+4wkIH8tqe86Bo+\nxRpHJ+gwx66P10zfuZtnj3GrbZyfLULXVjlb8FTk4c0KPHz/V6oqPbWfE3zm\ncmb9uUv3hCz/NKcq96iW3PvCGBGMASMtYcZmxm1+0Q8gD02xBi72LyzeS9K2\no0QxH5uqdGnEccWedWlqMvtsBJsGY1Cz7nu4B35hHIBiQ5T0w/fKAj8wNwiU\nyciXEjujUiIAZHkgFmstC8dQBgJof/yRzhTnN/lfFIVGnYL2dKgNIuMunlIt\ngRaF6AYCzETlp70px6bOhKks8IIqYu64lqw6NDmLPRij0fe8GGc3YZ3Jxww4\nYQ44\r\n=wJ6+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCfev57KGcsYUvhUjCPxyDOVUjjtMh1hB8kTkcB+hm+twIgfPINPRcI35Jn3JZi4diPgO19eCOsHYA56v3O6NHUx9w="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.1_1534094458796_0.49357690072009497"},"_hasShrinkwrap":false},"0.8.2-20180812172140":{"name":"@atomist/microgrammar","version":"0.8.2-20180812172140","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"SEE LICENSE IN LICENSE","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","microgrammar","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2","typescript-formatter":"^7.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","doc":"typedoc --mode modules --excludeExternals --out build/typedoc src","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"npm run doc"},"gitHead":"259d7c78d2b08a7896b73c75bfc7e5acc542ff2a","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.8.2-20180812172140","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-9J6IUCC7fzm5n6krvdmRpgEgtGBv0geVfvAZSAr6UDV8p2MgVz61Ct0/tcBeDt9+zVOnPULizelQZXvD0EyvBQ==","shasum":"43c600ba3b6cb92be3078ea3ead526822a9462e6","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.2-20180812172140.tgz","fileCount":172,"unpackedSize":284525,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbcGzyCRA9TVsSAnZWagAAgEUP/iN3sPiQO2erPk0Hp60I\na0CxzVVMmKMBoJ82sCZ2GkUZuAO4GbAebAVLhZ3IVXtuQnk5T/L6nDiMsUZ1\npIGg4wT78vJBPBUkX/TQRuKwUL7i63r5TuGXeQPBPCEXFggfAm4ehgL6qE/I\nwptc0SM7F6+OnjZQwbSdAua2liGKEjo9b4Vp6eccrnF7SMEB314A33pfOigA\nVreSjupInv7utoP6uFLSA7QMkFXcfST9ZCzc7n+E/RZj5N/Q+TUJnEjeITtX\n4SGf9YmC8UXx0o4IuvaP+XnfqNQrBkr+EJrCbKRqoYbSbZJQMv42LjnPpMGE\nAV4PFkV9LQc13E6ljgsz5+uosyQckAy1dsNMFrZJV+CcvqOcEY1F3zNzNWMq\nd3nWNt74QI29heos+CKG42ybgKAfzlQujzJHJm85OQRSY/P3iJpRr9RF/3Gz\n7wZtya97cxLko3wadtsQgU0QIsQwGMtIywRhHlO9Q3H6zptPlAwC6lDdd/K1\nFuzPEqMqv7+5TEsgPLUFSVtfLTIOiO0VX6+UKDQnaj4ETIpljiIZQQ1euCUB\njH2hmWEYmro+VxKmfTUr2WhPAw533ltocJYn+lhptXG7UshM6u2aqOk9N5Nt\nnJ6NHP5Mssq1SOtBNkjFAWeC4uG0pqvX370+rCyCKrbgqGWMHZ2nUFhtj2/d\nksE0\r\n=bEGe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHAOxx3Ya0ddSyywEHFHJVxFo8s5ZYbu2gde4hf9XH6ZAiEA1lMraDKAdAXevDYR5B9R6lOqy9gtGNtQrfhC2b69CGI="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.2-20180812172140_1534094577603_0.6917740674450037"},"_hasShrinkwrap":false},"0.8.2-20180812191723":{"name":"@atomist/microgrammar","version":"0.8.2-20180812191723","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist"},"license":"SEE LICENSE IN LICENSE","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"keywords":["atomist","microgrammar","parser"],"homepage":"https://github.com/atomist/microgrammar#readme","bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^8.1.4","mocha":"^5.2.0","power-assert":"^1.6.0","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2","typescript-formatter":"^7.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor -q -n exit -x npm -- test","benchmark":"mocha --prof --compilers ts:espower-typescript/guess \"test/**/*Benchmark.ts\"; node --prof-process isolate-* > profile.txt","build":"npm run lint && npm run compile && npm test","clean":"npm run clean-js ; rm -rf build *-v8.log profile.txt","clean-js":"find src test -type f -name '*.js' -print0 | xargs -0 rm -f","compile":"tsc -p .","doc":"typedoc --mode modules --excludeExternals --out build/typedoc src","distclean":"npm run clean ; rm -rf node_modules","fmt":"tsfmt --replace","lint":"tslint --format verbose --project . --exclude '{build,node_modules}/**' '**/*.ts'","lint:fix":"npm run lint -- --fix","test":"mocha --compilers ts:espower-typescript/guess 'test/**/!(*Benchmark).ts'","testone":"mocha --compilers ts:espower-typescript/guess \"test/**/${TEST:-*.ts}\"","typedoc":"npm run doc"},"gitHead":"b533fed303b5e5abcef832cce030af5358aa4a39","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.8.2-20180812191723","_npmVersion":"6.3.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-8oxKK8TX6l5DE1lLXe1P4Sr5bz6SXkjqhtTq8I3APPkdW/YDM+uiZyrw9r2bbAEpi4PMkQj0QXfyPXnGtSArZg==","shasum":"4809ecb9acde3c5d649806b46a00182ace2f5568","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.8.2-20180812191723.tgz","fileCount":172,"unpackedSize":284638,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbcIgPCRA9TVsSAnZWagAAXbEP+gKTmMFayGj2uzzODkA4\netSZM2OR3C8eAZAZwq2jFOU9Dymyfh1ldEE3J+NJq8FRNZNkYfMpVrYqmgUD\nw/+1VCA6dGXAZkVnen5QvFKu8tfIBz6M7DkHqI/EPELWOLZ2FLolllqVm5Qi\nExrs8BrbXR6WRi+aQkFUYwyEiKw9OaiaNX1E/VyOqMeq+lvGFcyZo/LuW+6i\n6AyFyuZouUSsBtVWCwDFF1wUcYIFcLlsxNiAAgjXojCjpkKSjidby2Mlk2Yj\nba+L3m3HBPzRQ/KS3TjpZ6O1ghct5AGGpnUG08wRxe5diFpl+cy2kq6hEuIG\n5Mw5ILAfPYvuEZ4OzUlFpFgqAeS/RtZHqRSJhnL5MZ1ZS+av22LSCXrL6u67\nPZZ+knj5XIC3ClirXVobrdJk2pRs+r/XuMtxJyEqTYrTQNJEBrUy1juiAQoM\n6Rzwv4kd/FWWj25JYMxVOKqGUAolFgoT8pXuk5v47qe/ON8JmtAGzQNy4mPR\n+CQ7XyhCoeMtf9jEYn1fqz1po9IHdu5TVVgFtu6ncFWo3zvncFdIyMBWM8wp\nwMRmm8U/uUbATP8meAA0W1985halvhv7R/42Yy5nbqS1MWVrDzD8tLOFMqg5\nvf2p5RJfngsNmBe3VMZ9rsyYw0YoX5AUJNy5toGwuqYHJN6LhKwbAvyA4a76\n2HFQ\r\n=xJPB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCvg3fOviUg6IyBgYMlgIfaltgsjdRY0MCQyuzyLl85HwIhAI7kkB1M/0uXEVAhqooUO6zrIsevmc9V3s5+j2MHXaUT"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.8.2-20180812191723_1534101519077_0.5249122499388927"},"_hasShrinkwrap":false},"0.9.0-20180822184742":{"name":"@atomist/microgrammar","version":"0.9.0-20180822184742","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.0","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"3c83b8a72033df484c2b5c39f7e94aaee293df27","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n[![Build Status](https://travis-ci.org/atomist/microgrammar.svg?branch=master)](https://travis-ci.org/atomist/microgrammar)\n\nParsing library written in TypeScript, filling the large gap between the sweet spots of\nregular expressions and full-blown [BNF][bnf] or equivalent grammars.\nCan parse and cleanly update\nstructured content. `npm` module page [here][npm-mod].\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured\ncontent such as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize\nstructures in a string or stream and extract their content: For\nexample, to recognize a Java method that has a particular annotation\nand to extract particular parameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex cases, although they can be\nbuilt using regex.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n[npm-mod]: https://www.npmjs.com/package/@atomist/microgrammar (node module)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\nThere are two styles of use:\n\n- From definitions: Defining a grammar in JavaScript objects\n- From strings: Defining a grammar in a string that resembles input that will be matched\n\n### From Definitions Style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n- `JavaParenthesizedExpression` is a built-in matcher constant that matches any valid Java content within `(...)`. It uses a state\nmachine. It's easy to write such custom matchers.\n- By default, microgrammars are tolerant of whitespace, treating it as a token separator. This is the behavior we want when\nparsing most languages or configuration formats.\n- Because the other properties have names beginning with `_`, only the class name (`MySpringBootApplication` in our example) is bound to the result. We care about the structure of the rest of the class declaration, but we don't need to extract other values in this particular case.\n\n### From String Style\nThis is a higher level usage model in which a string resembling the desired input but with variable placeholders is used to define the grammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\nIt can be combined with the definitional style through providing optional definitions for the named fields. For example, to constrain the match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\nAs with the object definitional style, whitespace is ignored by default.\n\n\nFurther documentation can be found in\nthe [reference](docs/reference.md).  You can also take a\nlook at the tests in this repository.\n\n## Alternatives and When To Use Microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe `@atomist/microgrammar` module contains both the TypeScript\ntypings and compiled JavaScript.  You can use this project by\nadding the dependency in your `package.json`.\n\n```\n$ npm install @atomist/microgrammar --save\n```\n\n[mg-doc]: http://docs.atomist.com/user-guide/rug/microgrammars/ (Atomist Documentation - Microgrammars)\n\n## Performance considerations\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Development\n\nSee the [contribution guidelines](CONTRIBUTING.md).\n\n### Running tests\n\nRun all the tests in mocha:\n\n`npm test`\n\nRun one test file:\n\n`TEST=MyTestFile.ts npm testone`\n\nRun benchmarks with profiling, leaving a `profile.txt` file to view:\n\n`npm run benchmark`\n\nClean (including deleting any profiling data):\n\n`npm run clean`\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.9.0-20180822184742","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-8jbT5G1q9PZElfMoc7OU27vq9xedNtXgaAzvBvg7ffGXJWkjynyhKhN4mYnEa6lK/FLtb4R0aYMfxb+ehBq10g==","shasum":"6f7e46331489c718d394386642693cc1bbb365c4","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.9.0-20180822184742.tgz","fileCount":137,"unpackedSize":255596,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfbAkCRA9TVsSAnZWagAAbSEP/RN31SfJpcZXyHQodYXC\n6ZPWEMoyuBhDHAgQwmkCEmUJLta10Wm6hf0ixeTEVodjDtpvXCcz+5tyzRY7\n38UXfeGhCnsnR99tiniNIhh5iHRSuFJa//Jyl1EumAGCHWZ2IF9jIaOTtOdX\njgpgCLnP1pIgIMY7lKgJSD4xZOuEqgwkyPdAamMIt2SwTQ8dz0aky0WQPJ9F\nLXstnq2NBVIN0mq7y0lMzp/Gh88ryas6tIYLmdk5aQtZGSNQDsdh9DVC6kyK\nVf9Zpsl6uM7c0AljVAqCa+nGK4CAYN6ROSKZ6CeNzkYUpurU7Kc7lXtP4i0Z\nfcUKRLxt3+UoTx57z7IvPmH5HQ2suC84XQ6jgP0/P28BaXcL8mCactvSc+Z9\nCjRRymmIcN45BtewtM9O3xJ2W6SvzefKLqzYSMpHRR/8PeUztW6IfC6HAaAb\nUacz8WHgVF80no/45nHeHB1UWRX3CrUuJjvHGJQ0rW3khYQMOXtnT+kdSQcu\nmM+N0BmV94Cv/3cLCmH+utAm7llIXBB0uVKcjrnJqZkm9OdWKltGgpY2G8yH\n7eeNdxyXB0nV1s1MYGCEOXuhJHJuePVJK968A0kRLidlxZlKepOEPoQGUXms\n6IhJue6NdelKBvuWoV0Y0LfNndOAPHIhvgaVcPHfX6VaJgVp2wEBZr78ZNSl\nM9Cc\r\n=47BA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIQC8jHyiCP/axNTsTck6YFTnD4aIZu6XXR35UJ9QGXMCowIfbZhgSvc5JI+VghrFSPmk4qDDMSZuL3Y0z2KZhgTRJw=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.9.0-20180822184742_1534963747692_0.15783828038013747"},"_hasShrinkwrap":false},"0.9.0-20180822192508":{"name":"@atomist/microgrammar","version":"0.9.0-20180822192508","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"aa0c93d4429ff5ea0d9f8dbb0e7115dc227c389f","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [node][] to build and test this project.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nUse the following package scripts to build, test, and perform other\ndevelopment tasks.\n\nCommand | Reason\n------- | ------\n`npm install` | install project dependencies\n`npm run build` | compile, test, lint, and generate docs\n`npm start` | start the Atomist API client\n`npm run autostart` | run the client, refreshing when files change\n`npm run lint` | run TSLint against the TypeScript\n`npm run compile` | generate types from GraphQL and compile TypeScript\n`npm test` | run tests\n`npm run autotest` | run tests every time a file changes\n`npm run benchmark` | run benchmarking tests, results in `profile.txt`\n`npm run clean` | remove files generated during the build\n\n### Release\n\nReleases are managed by the [Atomist SDM][atomist-sdm].  Press the\nrelease button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.9.0-20180822192508","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-vSwHeGhMs59kb8WTLlTkT2om+LctI+cWCHkPD8DnCHmYDolo2k+K/3vTcWovwKz3g7mqaChMPzhN/0M1cjImtA==","shasum":"b0ff6e693953156f208d1dde1ede803dfc2e4603","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.9.0-20180822192508.tgz","fileCount":137,"unpackedSize":256687,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfblpCRA9TVsSAnZWagAAr9cP/3/ogKmkWek4KFvuunjb\nt+SvEkOPRMSpA5ZBFyh+R+N4XU3CRxYJNCcs2jy1K179fPHHqV4RKDld8FfS\nGQdP2lH2JJatH5zX/wWTOhSsDWBruGpSRXEmlwA7tw1mguhgGO/g4uvExADg\nwvQ0nVFbOgHmmR+OFypxOqvb5fypNQOBGFfe9j+IoQVpynD5LF3+1PkGJI46\nCoZR96spKolO0S2Zq5udyISfMtfhhm9xBW0bnWEtDUBT3FdSXyXWnrkOukfd\nxvDy+wXKUowAUNFgBGMhja90TaOMOkYyFa0mvjg/iS7LC3lFuD/aiziTz7Ua\naXUmDHkvupTJ/U8AjXgVnNkf+yddCvPKGAUmfH5Z9obiZpQAMDzBkjRZQILR\ntTaU/taniT3RzQ1tOlJyceLtS1iI1FRj6OgO0vB2JPPlgbN7jsOoL3rM493K\nhdWGEXTGfWvvFWjrDIjQH6mZKzgdRCvZwMMrDKDEFojwZ3fHTayhHipM604D\nkJjmEnoOS75CWbCSVnJdwoLZgP6xg2ZgOuM3DX0+pgVBdDSE1z+hOK2mJFNK\nFjCjZHPlt7006UXfZidwV/Sc2s7SEtFofoYL3AoEpJOnidDRO5NZOOFESCCd\nNfGv511EfHVfmPytRGcdLx640V6C4ciRSc4waI0BkfqYp0KRjJRvKgJYnlDA\nwhmf\r\n=Et0L\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD5ZvPalHMVs7P3tLhIK/CnZ+VxAvu7wwTOIuyMjI/KbQIgPAE9pgiBRjq9WNej5xBBHrNJhYsN3CyV336W1mAJEn0="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.9.0-20180822192508_1534966121176_0.8984464101867318"},"_hasShrinkwrap":false},"0.9.0":{"name":"@atomist/microgrammar","version":"0.9.0","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"aa0c93d4429ff5ea0d9f8dbb0e7115dc227c389f","_id":"@atomist/microgrammar@0.9.0","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-AMMqex6+emNgG4DAp44fmWYxULArIZfoQRNFlOJZbHegW/X/GAVEM35hEESLYKLsbRkY5QEEX/VVAKWU8bHjRg==","shasum":"ec86ef163b0c3c75efc4feea9e2097ad15377650","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.9.0.tgz","fileCount":137,"unpackedSize":256672,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfbolCRA9TVsSAnZWagAAAEkP/A/yxKfao/aKw+ZiLytk\nGRtmY8wWxJEA4qtSZOEng+wDTS3J0O+4DzlFkJL1jF/ubkQ2QP79fIjLPT6f\n/WU6gcYYWUX2Gz+2GpsQ13mZI74sP1948RzjLZ5R29oX4TShotzWzpkIZurx\nCITcuXWF3RLMH8o3drKasHE1V2MYgPQ1ngu2LoghSOescPV4tOndtCkLyWeL\n5vuGUis6vkQjmgXtqR4R+qsfmOCsytb4+psQt2LgtOl3R1ihc3t4J4LCGv2g\ntxssS5Vx9aCTzwWsOG+O/lhrW9izbd6ZvBrLf94Pb72YmwFqQXd0HdLbVwWO\nscGQusVIvjUCe60Szs11chWUoAGmeYvTLT8csK2+DfgMdfVc0yvX3zvrHISq\nwj4jocb5YGXV3QStwozpdzZcmvmtAIKTcLfQhpw5WM8V1Ho6dFw1ejj/GIeE\n+KW2/rhyRLV+b+NWE7Zniqd4u52lEMIiZUE4RSjrUrvuiv/0U9wMJpTXFojU\nHbM1p35gfpAluS4YHbrAPm6Kcy2BIsF24lnjZg7TU5417p/aMzgs/PGY1t4p\nCnvX+ayhG1iC6JfEjzjgkazgQWdI7ca8SwgD2HUxt5bCCgzU/eYDnkf6Wgei\nexxykoED7P89kvkSPwN5FTUnGvshNGZUAsYxlnqzUOGWyUHUHQ3FkhWrFS1y\nY/31\r\n=mZOl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICNOFRtUOM6pRuc1srXW7wX9zwyvqat+J1ftLRClzskEAiB3AtBYnzr4DsjI2iUwi8kRe1WXM7MRvpf7BUPMQDpBZw=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.9.0_1534966308712_0.6791080437317694"},"_hasShrinkwrap":false},"0.9.1-20180822193237":{"name":"@atomist/microgrammar","version":"0.9.1-20180822193237","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"bf01734430e418ff826251f562808298437fead0","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [node][] to build and test this project.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nUse the following package scripts to build, test, and perform other\ndevelopment tasks.\n\nCommand | Reason\n------- | ------\n`npm install` | install project dependencies\n`npm run build` | compile, test, lint, and generate docs\n`npm start` | start the Atomist API client\n`npm run autostart` | run the client, refreshing when files change\n`npm run lint` | run TSLint against the TypeScript\n`npm run compile` | generate types from GraphQL and compile TypeScript\n`npm test` | run tests\n`npm run autotest` | run tests every time a file changes\n`npm run benchmark` | run benchmarking tests, results in `profile.txt`\n`npm run clean` | remove files generated during the build\n\n### Release\n\nReleases are managed by the [Atomist SDM][atomist-sdm].  Press the\nrelease button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.9.1-20180822193237","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-4W+jGuCVN4xPL9e/OER7gQJ2/DZlYX7sVB3VLqpXsm+zWSghVnPz3L3El7HBJcX01kn3tWBbjika+oldJKTXlg==","shasum":"19cbce78397b7df706b609bb35380c4e9d8f79c0","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.9.1-20180822193237.tgz","fileCount":137,"unpackedSize":256775,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfbqlCRA9TVsSAnZWagAAMi0P/3K76wOu9qAypBeENlNk\nZgj6HgHa69U5hLKgEW59Nd8C5gkLQ5Jx53yTxaBbIUMTy3tUpq0dW8fCI6aK\nDHJ9Oa3v++AiNmGXQC+Vd+lpbDzcBMM0J8QraZc9Ai+O17+IXk26lS4Y0MOG\n+j27Tw85IL7bD/8PVEP6FPyGSVIzD2op4hnDgm4DXpStvw7ugixkb0RQ8LcK\nUFlOl9EwDYNsPqJ8edIjjSo5RtUsr/F8hOAshDnJYgE/4jqI7ZWf6pM3KNRP\nmTeYoq/dXON7ba9T+sqJxo5ySmRlYywzBc7iacOEVDrkvr7TNi/q3LTq17tI\nupiW1urX00Z+R9OnmAVKpT49kfG0PxAlxOCCqKHz6oyQ0ubZVNTdE8vn0L4i\n12hUiolPkoERN4QiaWdH/ctNjj9Btt1dLEd2swbr4lx57FlIqhmojOOFJNlE\ncvkOyjX16OmS6jo9zHRMb4YPrx5Dls9iT/3g3q2k6cTOT/Xfd5S7BZGWj68P\neeR+BdWS9ctLRv/tQ5/ShhVz6aC4TWuTDih8NLo2HjjC9QdIcs4OJELIr66f\n+1HJNs0uzmlbAB23wD86PKgIUZbx9FOXXaV7YbiQpbCoPYShPa9RtFJV9L2Q\n3yusU3/Bre7WsdCmq93lqkXN1Mvu5HPQ5jp2PqWSW/KAsXFXIPtUjyYpoasP\nVEdM\r\n=Zn4l\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD2Vjj4ikUYF9YDlDu+VytZWpfuOyo1YIrwlszUdjegvQIgH0lzAaWRTWyMJCEZS/UOgPg+Al8xFotrHgf2+oRfdwE="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.9.1-20180822193237_1534966436785_0.558034369824435"},"_hasShrinkwrap":false},"0.9.1-20180822200900":{"name":"@atomist/microgrammar","version":"0.9.1-20180822200900","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"3affd26edaca2e637aa4ea1d8ac15baf16058f3d","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [node][] to build and test this project.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nUse the following package scripts to build, test, and perform other\ndevelopment tasks.\n\nCommand | Reason\n------- | ------\n`npm install` | install project dependencies\n`npm run build` | compile, test, lint, and generate docs\n`npm start` | start the Atomist API client\n`npm run autostart` | run the client, refreshing when files change\n`npm run lint` | run TSLint against the TypeScript\n`npm run compile` | generate types from GraphQL and compile TypeScript\n`npm test` | run tests\n`npm run autotest` | run tests every time a file changes\n`npm run benchmark` | run benchmarking tests, results in `profile.txt`\n`npm run clean` | remove files generated during the build\n\n### Release\n\nReleases are managed by the [Atomist SDM][atomist-sdm].  Press the\nrelease button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.9.1-20180822200900","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-E7GwTJvXdChNSUimD853aEBBODv6ShSTcq3K/p3ot99QqvSE76z7weBcpQxQAROVh4Urm96QyCDA2cZpr/vW3Q==","shasum":"7bdde683e15444c04368c59bcf731764d4de26d7","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.9.1-20180822200900.tgz","fileCount":137,"unpackedSize":256940,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfcM/CRA9TVsSAnZWagAAfDsQAIJ/laq/p0WOx11Jf5OZ\nY0yiEwWv3iVxZ6BAFK6SayXgnfpVCbi6b7JwD+ZO1xzEoW1FDYdO/Gk51aKL\n6uK7i3TKPh2kkhtlH8F2TVUU1qvQygTIzx+TZ9Uqv+cNrM93dvv1mkKkRJlU\ngqf27MSLLALMA4GI98W09Ciut03R77HKMdaMDzk72RdKHaZWkOsDcqken0zu\n3152egskGizpDXRwrW4S0RZV8JtXOaCkhdgs3dbUNPtTgKshZtYJ8AIfCQ4u\nkTLLqon0DCOY9rI2vyjg9qzKf96GvByrIOGw/na7xV8Ngh5jVRwJTUPbTcgA\nKcEoEHwwwrv0w5TsPLYDsIrySGxsvCNW858FlT/i7RXO11nuflc7LPNtTZFq\nhds3ArWs5mmncULUfiSwYDCp9TxY4nb9fkrj5kmQmWTQUnv4Bc3cj9IJyxuu\n0NtyCayISMcI7RGAdSccvRM4S03IWjnAIbHcKqTWtU4F6sAmgrasF0B5YfLz\nSKNx5a5naUH+CmGQEvSCY+CMtAs2Y3r0lcnE70QGQVQe2v/4e58ZDzGmYRap\nMZPWahj4SUALWjZT95UgEIWLuzELXppZ9A4X281rpmcdmN0hdSwyJnFep3DT\n7X2zg9o83uRpB4hPvk52B2cSVG8jvbSALPoyvcrClxPIyNVxDqWyPb0bWFHr\noYW4\r\n=0BUF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCD4CuZrS0U8ydIprOUs4BpqWsf44E0W2ixwLl/9hl+FgIhAPqqzVBSTdjdIuQlaU3WSsk4GrdI9bzLJT1XoRcmIrNf"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.9.1-20180822200900_1534968639201_0.37005597024001635"},"_hasShrinkwrap":false},"0.9.1":{"name":"@atomist/microgrammar","version":"0.9.1","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"3affd26edaca2e637aa4ea1d8ac15baf16058f3d","_id":"@atomist/microgrammar@0.9.1","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-QigsreENGWWZDvuiJfpgZdUW1ibI1+5bNOFL2heXZTiuCAmr1GCzzebF8pVwErBlIxRDgZBnsVdOOIamHIjHxw==","shasum":"f9675228a6c5baac69925e80f2fa182e8a2c7b91","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.9.1.tgz","fileCount":137,"unpackedSize":256925,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfcNwCRA9TVsSAnZWagAApzUP/3WYBnvWCr3UtkI/J8sV\nzi2nL7eOi+/acBmUMM8DKzXWxZALDZeMWXfIlXuUH5MI01XiPI/54ulBMls4\nCqBbvLbzLM20j2qM1WftW76IZAhZvaTsv+m9txnsjcr2+jjBIDL0dSVESpau\nDwy3AcuqB+pAfULX3lkEWPFEZvCW7WnFj116ZUuSPqNsVsdSr44fhmVHivtZ\nsAS00t69/Rn5qoZnsanTmocIKAL+ivgVggYbCTGsV7lMSH8vj3EeIbncfGhn\nzXULvr7AUzj4DajbAtWk0/3R44iIYwQWHVfIV7kYNH7J8fbmZVBhGmEl2rqE\nC//aGHqB/QXRvIZeJohN5VBJTglLcyqZldxBlS9srJm/QUkxVQ5PXE6S96Lo\nTa2+jQhXu2V1DvT6Xv1ESJQQ/ZefYLovBRuZsSndUEqYBn0vrPPWh6JLo5eF\nDwrExbJBB5uuo73BGG1k/uvOsmSFZ4MCCbN+xhBcII/zZTa/KSXUwgxHT2vH\nljJwotLV5QAhx/Ubh/IUF25C0e/rDvLGmmn0/JkMX1Qr4UMUfrM/NPrHVaed\nyif7szN8ukYxoUmEqNqr5RblDUme3qVfAG5tbxHo93vRKghFCgQi2KxpKSGF\ncmkUh/ThdWqoUJUPjQ6VS519w+CSSDDDTiYQE49VLG1dMsPQ++jn00hU2WrS\nMIcB\r\n=tCtD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFvCTqqUie+Rgygo538vu5qVu2JUoeNBLOwZHlTwbMMmAiADX5Dec/8mvvEj7ryuhqPUR3ZQHG3Okx3E/s4wajAtfg=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.9.1_1534968688153_0.9992435788291949"},"_hasShrinkwrap":false},"0.9.2-20180822201219":{"name":"@atomist/microgrammar","version":"0.9.2-20180822201219","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"bf60f1dd1d18950f876d7f7fa44797faeda147cc","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [node][] to build and test this project.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nUse the following package scripts to build, test, and perform other\ndevelopment tasks.\n\nCommand | Reason\n------- | ------\n`npm install` | install project dependencies\n`npm run build` | compile, test, lint, and generate docs\n`npm start` | start the Atomist API client\n`npm run autostart` | run the client, refreshing when files change\n`npm run lint` | run TSLint against the TypeScript\n`npm run compile` | generate types from GraphQL and compile TypeScript\n`npm test` | run tests\n`npm run autotest` | run tests every time a file changes\n`npm run benchmark` | run benchmarking tests, results in `profile.txt`\n`npm run clean` | remove files generated during the build\n\n### Release\n\nReleases are managed by the [Atomist SDM][atomist-sdm].  Press the\nrelease button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@0.9.2-20180822201219","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-hIjCjff9j3xHru/kLRyZdp25WKAvy3M0g/dDM/zppdnJ3Gdlv27Gpl8wRqCOWgmsEnN3ZWNshe08o78j6Noq9w==","shasum":"e4b9f084f863793fa41b3cd2c07e067b595029c0","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-0.9.2-20180822201219.tgz","fileCount":137,"unpackedSize":257028,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfcRGCRA9TVsSAnZWagAApbAP/iGxugOXQstV0Saxd8iY\nDte8LQoDYpDv1CghR+4tZdg++CALxTfUJiS/FUYte6sTX1RKFYCNwzNoLTbK\niYAbyXDMsWMXmyC0q7Bril4YqbS6WSO2Nbc6oeugw9Q5xBtBdXslzOmU/ofc\naOvvIb7A7PqI1GnhxrRhlSEpDMhwUcLRCE6iWSDB3pAyMyvQ4rBkRr++O8VX\nF7TcUCOzPfYW2ch0/9ZDDDtili42JOiHO3SOBr8Vk9mDGVXqpDk+bPTJ3q5w\np19V4TWtiH6nBCphzqcYzHXocQcBfROG7r05syLZXeXyZl2nPBZrEbGW2dO0\nphwJIJaSOQoX4jv751Zm0eMhQdOsBYEcntpxEgoEoXVFddrbo9zNGFAIlCc2\n78i7Vz13YERUn6uSSOMSXJlEW/rFvgLQ61DobZ7vSTV2TgwEprzBFaGpl9xZ\nk9DO5+Gxx/tnJ02c2O2b6opLgOFdrFSqCScCWsYwXgfrFOtIZ4pmRUKLQvIa\nK5K+g3NLT1TdfuBrjPejrn3xGUIIsT98E+ZgmjEAx2oMffPPHooIEQR4Akwl\nYT4p2XeDbKCs1gSp2nMV8W52zC9VVYnpIswosbve0XACef2czXGW7JtBRKu7\nI+Ep9XKcsfzBAB6I9voSseP7tpdhHh57C9XcRZ/AegvTW/+hGIO+UzMKCB1N\nvDaP\r\n=PyAB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA9H/m5TeNNp/lt09iziJQ9iX8BlOlAYkLq6rL+60OI8AiEAoxY1OMRfje+3W+hPuER8Ij934LpVsoHszHmCb4FgHU4="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_0.9.2-20180822201219_1534968901782_0.7560923839626756"},"_hasShrinkwrap":false},"1.0.0-master.20180828164924":{"name":"@atomist/microgrammar","version":"1.0.0-master.20180828164924","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"df2043b36f1281df4fb2219a0a26d35ccd8a6b9d","readme":"# @atomist/microgrammar\n\n[![npm version](https://badge.fury.io/js/%40atomist%2Fmicrogrammar.svg)](https://badge.fury.io/js/%40atomist%2Fmicrogrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [node][] to build and test this project.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nUse the following package scripts to build, test, and perform other\ndevelopment tasks.\n\nCommand | Reason\n------- | ------\n`npm install` | install project dependencies\n`npm run build` | compile, test, lint, and generate docs\n`npm start` | start the Atomist API client\n`npm run autostart` | run the client, refreshing when files change\n`npm run lint` | run TSLint against the TypeScript\n`npm run compile` | generate types from GraphQL and compile TypeScript\n`npm test` | run tests\n`npm run autotest` | run tests every time a file changes\n`npm run benchmark` | run benchmarking tests, results in `profile.txt`\n`npm run clean` | remove files generated during the build\n\n### Release\n\nReleases are managed by the [Atomist SDM][atomist-sdm].  Press the\nrelease button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@1.0.0-master.20180828164924","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-d4dT7NGIiddbuWv2x8DBFseBKXPgBKAMzon8AC1QyVfOXRQ/qVnDZJbiyGGNE7+us2Kx6YTIkMT5k2bT9WyoxA==","shasum":"a2382ace1ac0f98fc8ef10532c488134e0d889c3","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.0-master.20180828164924.tgz","fileCount":137,"unpackedSize":257117,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbhX12CRA9TVsSAnZWagAAPcIQAJIXK3ZUXdhVKNIZFHXq\nziMRsW7wqLXdZ7CvrjceJjvlHVlsppa5+I7FbDaONEUOB92+ckHGumFCSCZE\nLmIjJmOIGXkPnDmu51cAxTfyM6vcOItTdlrHp19bcP8SpU5R+ua+w9QHZph4\nkir/1SkG+m0MUDbPD/z8Tsi5ttP8agkrnfg37p3EdmfZNZ7al6OETHwKBV+S\n4TwVBVrK5leyphY5nUXTqHZAyPxOTfvdU9tfZn4mW9cOlJI+tsG6oyIk1VT0\nrXLk86ir3+na4hXVHPWO1pxS9WD/Ugh4G8JSoFkIyHqj3E8DrHM4WnFZb284\nVzBU+0ReGQQLtsTFFNatWzXzhyIKnFETQXgHgqL9kiHCqBTI6hQuPLPd0DBZ\nuDoRAWhcJMZ6Gtt2+OutF/k4+78QD2MZKyItVR95zljqoV8pZCuNkGUTNOHm\nc2rTphQAJT1NuAjsSTVBYNuuUrPA9vTjdh856rWJO5UmI21ZSHnpghQrfCRp\n/NNY5CXABU4fUDZMvwf9/7eyCcMz6O0E1Iu9Ti2+piZMtYYanc1s6YolaNwS\nlDqmrZIVQ8te0d7iZkrePe/YD552z+RT7B95k2Rf8xjBa6y17TpYzy+/ISi/\n5FRVYJRJkjO+5yaOVrYy6jQFUqV2K2T8VbjlURHotoQJfdIu7GKRjSuEwLKj\n5X8y\r\n=a1/Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOHWPi887oKbii+fKdMr295d/JzDBxD8cY6+I6QYwnYwIgdo3QVQlzYqM8HTX5VtAmCzsu8sGWuPyMgAlOQ1HJtCc="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.0-master.20180828164924_1535475062198_0.31294689039840295"},"_hasShrinkwrap":false},"1.0.0-M.1":{"name":"@atomist/microgrammar","version":"1.0.0-M.1","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"df2043b36f1281df4fb2219a0a26d35ccd8a6b9d","_id":"@atomist/microgrammar@1.0.0-M.1","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-gf8XYBz7RPVoUdJj4CGvCi+0SWgrd2HiaBNMRAYbqBR/1BuzBwR/EjCeLljdiRkRyRExfWb3zEiDRsBCbtToAw==","shasum":"81b8d4141a2aeab63371b5f0ec4fc4ec1a376fe3","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.0-M.1.tgz","fileCount":137,"unpackedSize":257099,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbhYD6CRA9TVsSAnZWagAA5wEP/A1oVOR6X63cXze2BM9a\nMSkgHxJUEQBJh73cxbUh8SSoKgqDNF0Z938RCtmgA/EL6/TzKN8OBJzLF+Wf\ntsf1tncyREvTqO2xRNIHFnr1jJt94Kl6hxJaVZfFqYJSVmCe09JDOzTLtUUU\niyDsVWq+K2IROvR+Ijpq5wyTrUNNS68hi5xrhBAaC04NW0yvghYYwrngsCqs\nHOafvwB3EiRE9YKCltx4ZHjSahizBOnYwLM8VemPzov4AYc6UHkK5KRzcOE8\nrAwLyl2RGTc1T3FbIHVeR8Kb+OJDYQJFKha5L6GlLLUDpZhBemhkbATwsu2R\n+x1l0pmzeIoF65tkwwHqjoSEpknh3QcTUTrqhb0c3PJ9bJ62D7fDh4H3dxRW\n46ixYUrFbyLQfnRGv86uP1V9VjI8FAukafo0TCy9x5iEldo6QtQxMK/0Dcy6\nO0e9VfnGt+pFhAdYPN+o47WRJHDW4Fk2QdwI2EEv8EK0hU2mr1c2MiGABm6s\npW4qOimrHZFu2drapAghkoldRpmSUt7BY67sYoXg3r9+ZiN9fiK3pvtjqBVR\nKoLbuv8zup5T671AdQZ2mA3qToW22VcZdFjGzx1vlK9q1fkUVlYOIH44qwIG\nSNZphWs7bmox13U/Am7/B1I3wS6HOvxjKfqAdDR4I3Vx7uiUFFsGzcxoc8oc\noxYP\r\n=tCmH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGKVaxYiMUibEMUBc8iWa4ZJpxOSlNRN7Yzqi4SwyuE1AiEA+y85FVA9urz0ovzDDxmCEU9Tqyajw+SnT0uWkBp+CHM="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.0-M.1_1535475961557_0.5325433070498202"},"_hasShrinkwrap":false},"1.0.0-master.20180829162516":{"name":"@atomist/microgrammar","version":"1.0.0-master.20180829162516","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"c0473472e0fb60d79599d743739c1b1b87096195","readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","_id":"@atomist/microgrammar@1.0.0-master.20180829162516","_npmVersion":"6.4.0","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-qNAUDdXtCECuWCZirW5qd6489htRnBtq6aNQGHnffbikxAlTPKB3/uHuuBRSDx7vKPhkNP1UpSWZPM6a6MrNSA==","shasum":"5fa5589a97b5c73be544b3410141ac46f3bf4a20","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.0-master.20180829162516.tgz","fileCount":137,"unpackedSize":256903,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbhslGCRA9TVsSAnZWagAA5tkP/RXJZ4Vt7crLPwpwICEz\nM5mzDOLzns6yheFsW48YvglWSglty5dnCecPXl8ZQ+KtFHojOzdedE3UzBdK\n0AuVdXVZRQ0EaPnv/oLyZPzFCFEOinaZm/EBg47DFjsN+maDf8ovCLr9YouW\n3GF7N3tS1ny8xkx9XoUxIjK5OWRTD7wNo4dN2ckQXkHv3HlF5I/hwzGUXF+W\ngE0aS55yYONTAJP4nT6HsqWRaRoNfNxoAMU2Lxgr58FAfJYohJzMdUHC0nwK\nAArrVEE2mQwd+4fMbBGh8LTNgimiJzk+lowhYXVDsryQbhcL+2TPrtO8Ce7A\nW/Qjx1qmeQ5TXcPIVf3wYgHBFpBMQVLEy6hbwYWMW4OzBJuSn5Q+SBVNgBBT\nx3JMRehEzyRHLD+mhd2zeioPxZkymP9yQOpUSgiIMB56CNVXhya4rHfSkoZe\nBgM2VnMocOyVYflKTQUXNS5qTO2cxvQXyXh5y71PX7yOuZeDtpd7OkGH4poq\nICjTxOU/ry2QMpPY+/yb0PSY70Cmo2GXf7rcaLuT9kYcU8EgjzM95dgIhZDp\nreVOwygUnuxr946l1u6KybuHvKtomNjyEPRT2KJ/dulMgdI5UtR5gd5Upq91\nL4zPgaS5ahiHEWD6ZxfMLrYhXPjM399EN+1oKP1Ck/YzFlkDDHZTEmOjwTQo\nwhck\r\n=JyFk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCkdiMiiT+uP/cyxH0eRhtfvWsmWfMs9M6w5hxF4CP8zgIgAt2eVMIxJC3iX1g56k/hSJC3VBavxmMOqKOFLt6vXMM="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.0-master.20180829162516_1535560005487_0.3047784532660667"},"_hasShrinkwrap":false},"1.0.0-master.20180916080140":{"name":"@atomist/microgrammar","version":"1.0.0-master.20180916080140","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"3559a3a3c44dda893a8a45e5d133cef4961c42c2","_id":"@atomist/microgrammar@1.0.0-master.20180916080140","_npmVersion":"6.4.1","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-2csX4kaeqFoNdToqroiiSL8J3SyTHBXbawMBNMZPEKk29wFnYR3enOuWdaJ0RuOIKakSqc4hR4vCK2H6CyO2/w==","shasum":"857c91ef1a93d062117c5800adb1d0db4b907da6","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.0-master.20180916080140.tgz","fileCount":137,"unpackedSize":256903,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbng5OCRA9TVsSAnZWagAAkHMQAInDTV541DojAuKCzwfN\nXYrLBF4TznO+MCmLjsBjhpQzo7cM8nyAVJNJd9oR0nemCixx3GXzvvhRswFp\nmHu4TzMmvoBiE9hWkF2RV+7oYvtvuQRDi5856gtJA+K27npGw8hzTg/yQyeH\nSGSLJynVoPqDEDlk+Gzim+g6ZHfmkBDZnjg3g3XOR7PDyMV3M42g3hIKIFNX\nFqTrpdo3ek5gl2bfSpwtNnq4ifdq/u9N2IKe9VVeF4QW9zpFlA99YKrHK0sL\nrrtDZhxgu8lJa3uJti5BSyk0Cn6QM+4/dUU4vzUw/RRj9glmUmCra2gXiewg\npn0n9W/xJ+dWTQsl3VBUHbQOGLl1JW32Bdp/rhxM9yOuY/BPQ6X9NiR/l63F\n3JKWrlxFBoEAXzjwbi9+B8mGvv2yyPKmJv+VaFQ3SnEaeIBj0SwSWWgBoOQx\nZRJ9XBof5tOF61HMTDSqfPs6BVUq86WpAE3x3OM4iov1Z1fB0Hh9xZ+wmEC+\ncvr8gOcfMqdwXnby34e5AR4/H0+OuOBz9jO1DpdFNvhzzIiRU57Cz6cn6P4Y\nkNz+nhnzdBr/45X+TF8I7BKgiaicvWdKliMgUJiROYOGBrLmX92HT5njwuy3\n9MrxGbU5sj1MOh2G9M84ySLTOzit+Sd6yJ7rKbf6pL4rQdDW3PP3V767Ny7c\nodKx\r\n=Gbpb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFDfq9xbw6aEepjgaYoHbMX/2gbVUwJH1QqV84fbDiQDAiEAznBacySFY6rrCo/+IwAul5PY7ib7Nl3iJw7RbSwul54="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.0-master.20180916080140_1537085005587_0.510879852132478"},"_hasShrinkwrap":false},"1.0.0-M.4":{"name":"@atomist/microgrammar","version":"1.0.0-M.4","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.11.1","typescript":"^2.9.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"3559a3a3c44dda893a8a45e5d133cef4961c42c2","_id":"@atomist/microgrammar@1.0.0-M.4","_npmVersion":"6.4.1","_nodeVersion":"9.11.2","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-HmXBEePPzXEdVEvbOwn3Dc5Pnb0LZqUzNVFq7VzuR4KO+vmej7Thm5R0eIdSjxNOzLQPWf+zYWD6D/j1YRXf7Q==","shasum":"c6de1ca3003f080634c4f5189fd169b60d6ef1fb","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.0-M.4.tgz","fileCount":137,"unpackedSize":256885,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbng58CRA9TVsSAnZWagAAGVAP/0+ICOSEN4g+G0vQufFA\nVyDTchYMNSj+qVHPQr1bxzVPfeEFDK7kMEnwesYGg0XCL6MBQ+5RXoP0LF2K\npt8AjH4lMJnly/xAr4jt9wLBh/o0kNmIspqQFV87iL2NuZk/NMXMDs9oxnWG\nOQQe8/mxElnDIzFDDbQATAFyPOohfBmOlju9E1dW94VZ/liZrOPFr4Nj0S9b\n2UO1BBNe7yz+4xDkMkqjg6Ly0us3K8357dviUczZbMjBLuoPU9NWH3XhLbxY\nzNWy6v8qKurRGHwZziHoqeXIQubTB3bbGkZ4JCkXeMNgrIZ1vOMi99DEpAy9\nUlmysmTZJx0/CLxht8zqGTCrPCFVdetAHbV3OmCTkH1HCtm6y6vbbhM8P7LL\nfFPy1VFXjtTr/B6q9/uKHE+I2OARgNL4hEw6RqJ60Xkxe5L2zRtr02/RF0BK\nJHgZJB2SUCVvMK6cDM/ksccFog3RYVMaIUth+/O23XKt2o9gFLcmfwEcfzj+\n9SlwKYAvCgpKBmSenghK2nQ1MwChcylsW+1IwrqyQXFq1anK8VzSBp3nxan7\nAr0bzYdXkzpD6i1W03AMoNWRztPxllDVB8n9lrmFXFQuOwEA9A5N1zGDEexD\nSuIRvkyyxm8+7Jo2pC32fl48fyKVVgwtwLlHYOgmYYUbiogUh8Y2zmyhhLdi\n7bl0\r\n=Xdr8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDhIynEswx8W4yUBDDIWWw8n7iaQbY/aEeqq0d//U0esAiEA6o4Dkd/kajGA7G0W7ObHl80A91+ZrqU1d7Nn15fwwZY="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.0-M.4_1537085051670_0.11913018314813306"},"_hasShrinkwrap":false},"1.0.1-master.20181109093737":{"name":"@atomist/microgrammar","version":"1.0.1-master.20181109093737","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.13.0","typescript":"^3.1.6"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"3040dbf3b6f3039fdc20582801de88b3888859c3","_id":"@atomist/microgrammar@1.0.1-master.20181109093737","_npmVersion":"6.4.1","_nodeVersion":"10.12.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-n0JV8GmB3KkOgyqeMteVJK+gfQU3YLGvCX0bjbpCstqbxV1ogFYiTTgbA/J7eDD25W2jpKOc21piFoeLsGJo2Q==","shasum":"ac632c851ccb6708c0cbd5f19ae85b2b4ee2e4fa","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.1-master.20181109093737.tgz","fileCount":137,"unpackedSize":257880,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb5VWnCRA9TVsSAnZWagAA5GMP/R3HJH9dehBoyw1xVbIk\n8hbNxEkTQ+uaUtFzm+VqsSUCqJYue6IeVBCetSC7x50ub9+VCoiEUZwrMQW/\noTcdtwJQjBU8dWrTLQzqo/JmmiGT86ohWtmTr4i4I8zOfo+y4RyjoKyP5O2/\nMUa+T6wdBdmSx/mgMJl611u31giYxbUls90+EweLUCK7g8GGvd/g9FjCtrwF\nrm8i/l6+JCJf9P5y0g1Y0bon4ZgymR5+fIAJZ/DW2bB6Sw9KLOI4Z7ApBRdU\nJKEc+wXgfnpRVFBY0wEQrRv/36pJuQs/RTDAV10nMBuewi+IGSHEtuHGWte0\nVYJB9eqoNhX49Ko4qxHibzxY5vbFm40EQFwnARRB/JX57c2gTHwRTAjW8cYL\nL9YbZLG9/vuEPSgf6IMQDef7s2ha1NkcTDleenaLVX8UCNHxalFsDbL9DDXf\nejckAy6Hp/elk8m6evM74HQgH8or7vzQg2q+eqD4aIl9sK+zLsjmut6KF1Gp\n1z7/uAOZ6BDYXHyb3tcTB/2+R64WCJMsSi60BBB4ZUZ2LNfVbpqQSI9TuIqj\npAAYn2BxVkPZUZwmf7AhyF1ekGptFio7qR6NokWiwMbvSeoLxxvSwF+O6hYL\ncnUnDFHKOxYl0PxSgH28bQXfyTySqQY7uYS3AofCnPu4ja80IeDASK4G6a5E\nqkRI\r\n=cfgb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICtYMXC5vNT3k9zUOORmtY81YJM3DFovnG5zbQC4qwbQAiAkY2VEJ0BfdC7UUcM2ODvdivP2Pg5Igu3iD1VzOx0jeA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.1-master.20181109093737_1541756326455_0.12031146096303358"},"_hasShrinkwrap":false},"1.0.1":{"name":"@atomist/microgrammar","version":"1.0.1","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.3","power-assert":"^1.6.0","rimraf":"^2.6.2","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.11.0","typedoc":"^0.13.0","typescript":"^3.1.6"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"37883fe50223a1cfe256807a2bb19237ab20bc82","_id":"@atomist/microgrammar@1.0.1","_npmVersion":"6.4.1","_nodeVersion":"10.12.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-XJA+QzCSVRb8TV0oxlMHUbyHxQTbXKwh3Z5yus491W2SvBn6GvR9nM7CoDXhNfb2KBGm2TVV2Lx93yOPnqtq5g==","shasum":"01492f3220211d7d0ba0cab0f67dbaf3393ba74c","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.1.tgz","fileCount":137,"unpackedSize":257858,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb5VYeCRA9TVsSAnZWagAA96wP/j9Z90AXnTSt2t3Rmg/M\nG0JA1tar2CWFi3fJNUOyjo8J6MIZNyWQe969353emk3kV13ZcAuJDwTp6G57\nAobPS/tVf5vWpSedHcEKMR1GHH//pPc08CTfFkHiJXqsSpfKA7fHaH8YA2Bi\nkUfvfvycQKBmTGTltDSHV9L4ZUePzPfJeU4q4s5lpMKTN/yeiPhR8mDH8s5q\nLMoJEsrNGewwWPWrHUUMuMoJ7ZCJbE4Jz1H+DOVXEr3SaskniAgL/dY62FZg\nRL0WWvxeJLNzf3JNOtl09RT4Dl1GuE/mMeD7Gwpay5RqBFDUWXkw0I/uy/Go\njQoscGn/pP4JsR231DFer7MO0TqwE89jSIZBbQo1R+iUgmRUbII4Zyb+oHMZ\nGNLWojrj7YiP98LuNplCixo/rInL7Es+rdVbGI39OoYypSxX3SYUWzdpd6mr\nVP+ikgkRcSwExqEgMsf2tJm4f2b1Rdy/2hAZZRrU84NtS+fy6LRRG8lksk54\nnfWncYfHy0/ssdyewrYP3K3Of39E+Old76zn5B6Q8PpzC5wKlXPrf5L8z0XF\ncEj5nzkYKEOmsopgK02RdmwxcrDeTx5SxMQiqPzhgE6THgy4uKVofSCOLnn6\neuyhaajO1ez0NjfctUB9IWLmdASoxOBeJvHoLs8DO/Fhn0uTDuMXILhzI0X6\ndfKG\r\n=DIMD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBhoEIXprqffIwZTf29VvmXvjRaSP+mjfh2YyMTGVJjcAiASQ40xt4enpw1VIvyyJ1TZJVxRsDgZKEKaOTygDQL4PA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.1_1541756445623_0.3866731979067042"},"_hasShrinkwrap":false},"1.0.2-typed.20190108000950":{"name":"@atomist/microgrammar","version":"1.0.2-typed.20190108000950","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"da93d163739dc644642407057de79273b0a896aa","_id":"@atomist/microgrammar@1.0.2-typed.20190108000950","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-V/bUicOamxn6O3Gv0JNKyL10EagbW/LBodHHIyiIdkIrokHsD+w2Mf7ssNRlHsrqrgrOwG4kHD3Atsaj5BXmyQ==","shasum":"432c073c2ef7cc7f9dcf33dddd1a150caf60fe8b","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-typed.20190108000950.tgz","fileCount":137,"unpackedSize":258403,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcM+qXCRA9TVsSAnZWagAAoZkQAISKRtGAPpUK09/lxHNJ\nRzU3UY6a5V+fCPMPSDcEfaBt22aSbPiYbQjzbMm6U1C2w1eBdlxhZU4JaY/d\naPMBFIKQozUa3ee5liGqfBkW7HRvD9T0PB+P17CGs7GtwdzbXexIuumewyQn\nh1bLX00/gh4xtSrdQ01CPlH/ewbQyag/Keyo8n5Ae9MHp8AoZHmkcqn6/yPF\n9jRaLy9KtMTaW+7C02h1wucBh7txPWfRAZg/X9UP7UGPBiWyD4bq0DkjQJt/\njcYv7AEsxpc/LrGwzhirQzzvKeU6DaL1RmfrvHBVeJrVP83u5vD1kOTXx9s/\neDAS0jhQLD29rHyOQ0SHY2aW9GG1d1Y3FZkA4kpEDxm/q6LJpFa3N6xNeyAO\nCUaXiSkM1TUBeyXc/W++xhkGHdN4YZWQZDASkEFgvOjTDdAwoRtAV7clUDnN\nO0EJ5zdaa0Tf02Y3Jd9W5ymdK6IvlKa+50wjo0pXwC/qgnsvHkYzWN3sXwLT\n7kuaIrJMDkqffp1h87JyH+p4ktxiBxectE4ZkLGVVTB/Oud+RIW/DnE7k0Q2\nHv12mCJkL15PT/46Q9wRK7/BO8wsTFalkEeCED+EdSGo4JD+hiRr5vRZe7Hr\nXqj3JEFSdf2RqcOdLKqM5N83nrbBjr0bYKdslTRq0phzkBKTIWfNMQId9JA1\nbhgx\r\n=ZUnR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEGDwiKDPM39qhTx3rlp1aWaohMrXrzql1W6iCY2nLDYAiBvq0bu0o5Qq29R0HlAziwN2rLOQomnziguA/XFO3jLlA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-typed.20190108000950_1546906262474_0.5141968573172144"},"_hasShrinkwrap":false},"1.0.2-jess-test.20190108001135":{"name":"@atomist/microgrammar","version":"1.0.2-jess-test.20190108001135","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"npm --version && tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"185dc4888c51b24856dd4d77a8ac418be5bbf0cb","_id":"@atomist/microgrammar@1.0.2-jess-test.20190108001135","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-coJaKazfqnVqvogHbSQeJyv4EipZtlmnzHCe35mrADQAPyPUQGy0+lOlqh1/PxcgTUZJxMvrS+cJgYYRIj8yGg==","shasum":"5f568ca2989893e8030214a8cbae95f653792773","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-jess-test.20190108001135.tgz","fileCount":137,"unpackedSize":258424,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcM+r2CRA9TVsSAnZWagAAX/IP/A8LUHibD+hViFmTZXkZ\nB2Kt1P3VMv+5zgpy+Utoxr8faxIVNef4aYI2dqk45D/5Tr4OaBFkAXBQAKb2\nDMMvLk0gvMeaKW7esWtXfWmBp4lyCXsc4BLO5ol0KkyZpQ4q1jeBW77FJVg+\nBkho/3iYnxHAj2NXvUsem+e0pZQNdRsr9rcwch5WpJ7uq9yCzwoI1p33LWMi\nUP5Ry5OKLJr24tpa3ckbmgV9slyIFDXbH65d3h13ZayTwhKO52n/XKk/xq0H\n1NlQ26FuQLuZzGc8mffecTXxe9LcR8X/mfphdluK2Bl/yiV6XHNhK3k8q2xn\nTz8dXQmQ7bFTMCgswH5X5JiOFDvj+LWVXmHLex+Hx8JrpnT1sXv0dOPOBJOL\n2OIgT/ZM4dm0Yhsz/JurL4PnskJqNDaC6CiNWmhxXV2U0s5T6KE7DNeSmHKm\nRzilIhBEhMp30zLol6QzUMFSNBnQUKDUuG+6huwrXOvhu/C1tAFk7lykV/Ex\naHplAAZrIdKTY72sqkuZLHsFdnHvRSJTOmxD+qIcoSYoSccFcN5dG2ynF1sm\nArgdc+6Xr0o8BdA1Vq1LjKPQW6uGmP5PCHjtbHYDHB1XClPeiIEEcqTLH060\nDZfq8sGurGC8tdpcPXRMQcC2+KB8Jzv1Tiw6bQ17qqyZI5k9LnFb/1920MUM\n4Gvo\r\n=XqJj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC4TQpkPiFsbubv/bYK53bIlxGDHBCs4ZfhluukUuyKlgIhALO9GHvINJ+VDOjmLPlymPmBbAs9F5gZVGX9eIJv3PLn"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-jess-test.20190108001135_1546906357689_0.9930031561744144"},"_hasShrinkwrap":false},"1.0.2-master.20190108055535":{"name":"@atomist/microgrammar","version":"1.0.2-master.20190108055535","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"d73796f94229e571e9eba352b0f8790f399633bd","_id":"@atomist/microgrammar@1.0.2-master.20190108055535","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-TnfI71e0e6ymW1/fNP3BFZtcQz5VB9Y8GIglDjkuPKJadMPzvZjtGvcYOhqCauvlUt9tgdHTyUGfZOo8pDfSgQ==","shasum":"da9ae2d3e19a13298d76a29a7ce507514bbf49fc","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-master.20190108055535.tgz","fileCount":137,"unpackedSize":258404,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcNDujCRA9TVsSAnZWagAABF8QAJJTqzO2zbDHuyVFXqtk\nAUUFyVFQJCiZk+W/dKR5dbCPhV5qem0rbj8Y/Uee6BWkfk6NYiD9kf4ZPeR0\nGs7XUIv4MLED6FzybePRlIojsu/vh774ZqFsruE44gvfTG6Y7XcGvMOerrUM\nCJX9oux2FN2NsfOnY5Tk5Aaej3nmi3VNXNgWwG5BxdAYJrZ2e/Z51QJ81UQp\nmzCHN5JwW8eUhMFnj1i92HYJwmS91bLVdKjRycoWZ50u/hOSrfKoq4BKxrj6\n1a7VwffEtULc8u3qBlflqXHyV2Iy6qPI9HobwKGWsgyBggTmPdHJXP5j7osz\nU4/PXxzurFjdfJFn6LbqGpwjmlVx/7WrfogSpN8eBpttPGBtzW5oaUtJhRlh\n6WH6LGG7yG3h1hZfqNZ6jvhtNNj25iWDyjWFs86Ggup568HfbUMGmi6GR9XD\nSCj4nf2u6rRdn2bLKak+nWGwZNT418+A7s6/2Rbycu11Ub7XZb6FYVs71jaM\ncou8gCg3d+jt4PFO6nitO1zxE+/PS7ySvIsDiB9kDrYorDfV6YUINM98NE56\nxggxKoNj77lDbervn+wtYOrH/Y63Sf6QRT9nR9NFrG2QGmdDjZ8jXD4CyA0Q\nNx46j6+DTckzLXCJWstQwroYaePcQTZLKgDzZs/00I3U8g1ppiaoDRTVSRwv\n5XV0\r\n=n6Zy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCYMnzMWMw1c4R6pucyRFHGnznZq/pH9Ct7Qba0dwZWdwIgAkDTsAle5nCxoCoZvLgYsrgnkAO5XZa+HaPDko/4BJY="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-master.20190108055535_1546927011304_0.8697657877811131"},"_hasShrinkwrap":false},"1.0.2-master.20190108055954":{"name":"@atomist/microgrammar","version":"1.0.2-master.20190108055954","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"2c72c010f9c62bbee674fc0ea700444c0e6c12f7","_id":"@atomist/microgrammar@1.0.2-master.20190108055954","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-iigxv2nWKmPUvAvBwlwpZpkpk1NLXuwiXm0Pi4BbNgCDARlT4Eh3o2/0gWOmROeLlCmF+Xm+c1DYNvg9lJX8cQ==","shasum":"a96a26c19c5f3b9cc1f2eaeb06d80b3bb7a4e86c","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-master.20190108055954.tgz","fileCount":137,"unpackedSize":258958,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcNDydCRA9TVsSAnZWagAA518P/0t0mTgqxsyTnXtPQbr1\npMhMOj/a0MNoLiCGIN7zZrpd7AEua1BIn4StXSdekOCE/Z81S18Aw63AbVjw\nADCbKJQKvoLKY9UWt/6/HN/Ns9pj77VwMPCss3pLPbqt47TmlkYZp8j8q7jz\n89UI3haq2fMqBbZ6V5HyIJMXBC2GU0xBj+0n/tMvW4i9JT7yamsHgnhq318w\nrmbC7NF9zocxWX0wRE5VOi00boMtkBS2yL2VHeWNMadyCKmE6HIhVnx6rZCn\no197kxCuei+Q/t1HhQxGkBQx4gOaoMig9np7LzUsUpdCB1xrcZcGUINMprag\nqiQCbIGYc63T0q1r4BCu40vtiKGyWIDLgNfKzIKu6Bj5nGrl5pXL8VtW/Zm0\ngBYMtyRK6i6c/md5A0hixc3FbNOULHFeCfEpUPtlNbkp4ENDcjEp7kyRKuLa\nxh9I7OrIe6TZnVoCv7FwHcK6GXz2Z0e36h57zmZyXv+vxPImQ7Qn2a0vgx8C\nl9suR3aj+GSBBXlA0XUKMmllS2gggSjHkaZz/EWdUOZq8U5DK1Z7gx5vO5Xr\n2BPoIIc1T7K2yzsxDkMTNfPKlnSrV1iIw3XD1jYjaL/XfZOGGqifnXDBb12b\nbFMcvpkEyrAbxdnl1kr2LXSuGD1nfSutnu/JzY7RUCJ73gQiR59xQoEk/iVT\nYH66\r\n=8rpi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCQPBev5KG/pkEGThw2WyV6Gq4uwdWAzjDmOWgcwMGoCQIhAImFcwOLEu5lgSAMMP8yAcM67R9Wm1My1bsmHgeQvSMQ"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-master.20190108055954_1546927260772_0.5520148832655716"},"_hasShrinkwrap":false},"1.0.2-nortissej.concat-enough.20190108225105":{"name":"@atomist/microgrammar","version":"1.0.2-nortissej.concat-enough.20190108225105","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"a31978fcf4d61a715ba48c9a3a7c115c792af69a","_id":"@atomist/microgrammar@1.0.2-nortissej.concat-enough.20190108225105","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-mVNKs37XXRO7Y2b8CBvY2UIWElceuAAcPyH9HD05zYtRzKKn5qQ5MgrS5OdexV3FzSLzprQ8kzffHKQ3WbMXgA==","shasum":"48a21a3b4eb08bf3300617ec43bef69a5120578e","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-nortissej.concat-enough.20190108225105.tgz","fileCount":137,"unpackedSize":259340,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcNSmhCRA9TVsSAnZWagAAIl0P/1euRsnzLOnO8Sa91Ago\nWhfyrWIJkkRoMSmXHx3NPkCQGMhwloYGQwlnkQ5j1LRdVFUq7k3GLcLd8PpF\nCiZA1PkO+6t4zEn8QlUi6/L/m/39iPu4IUg89FlMLTegNmymGB98bR01nuqR\nSEdcZkNWA3yaVet6G3h5+u66pFrSWXkaEZiAhHDQgeo3nzHraRPmDKq+tGLW\nbU7o2g0n/op6Lvjo5MzVNXhPhCiYjxfv7BwP3JI8LC9De8EsJXY0cKRQWHK4\nPKG2ghRmz6V1zzBYf92GDFHoNpzz4+itqqjXe8qD82/y/awoYXfouEYqYUH4\nzSp1YQ3QaVxVgO+P6fxFLSQWaRQgT1OZk8FUncOALkgDRNpG+VYTR7SEPBY9\ngO+cVhgLh0yhUPqCQbMesoGUOYTqQG94yt3bE+xrwFE+ozd3+z9pbYn8drw2\nLkAnRlUQoOjmkZO8ZuL8tdI1FEjzAwFGfiXBvKTpLufNaPM194m+oztK7IVR\neAJK7hYhCpATZrUk1KSXaGgggSpHov9ux3nq4QmSS2gfhaez/t/z1cbQNB+9\nOKPMTFWGm0ASYehCkQK4AEP6CrYppFjhmIFnXGrSOJVG+HR/8FO2IGl+uZq9\ngyX9ZktLGRtEAb0Xzp2+ps5URemByipHRLuYhUPH4+k/oU6HwC0EJhQvYSUL\ntxQn\r\n=qHzD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGh/6t9d+F28KrpttCStF97WAD3Kw8Ck1f3EMsGSQbxxAiBrtP6qbsT849LjxF5x794clt4TVk9kVeO7EieNcuC0CA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-nortissej.concat-enough.20190108225105_1546987936401_0.07667678435207459"},"_hasShrinkwrap":false},"1.0.2-master.20190108233554":{"name":"@atomist/microgrammar","version":"1.0.2-master.20190108233554","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"6a7a9cbb8e98cc9f106deea4800bc5c4639bd6ed","_id":"@atomist/microgrammar@1.0.2-master.20190108233554","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-Fb83ggjKlsYSOl07trJfEnykFuDe5SgV8RVqVEjOvkkPYmS2n5EPTK/P9SBXGCyGVRpbRo6Hhfz+izCPvGsESA==","shasum":"39c171c32b9b057741238a56a068ef8fee3c1d62","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-master.20190108233554.tgz","fileCount":137,"unpackedSize":263497,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcNTQXCRA9TVsSAnZWagAAeX8QAICkkCqD4S4ZYonzQfo1\nrK0g1qaGrsRq4V2KSVYu6pZEzf92BygmTeHO7ttieFv5dhcjqMjS1HlM7Y3x\nRKk3XtADWkYjezIpONPZyDrj9yWoD8SjB8vm5bWaLTXD0V4R4H9OUFzMRfIc\nwh7aYFcymMoFIbukaZQvmrivEwLPtwQ4Z8qImsRAeZvBJD46nnTdTGueDh4O\nwICtqxC0+x9TSgbTFoVvq44L/1aNCqhqaVh+eCa5VvLWgqp2ApypSMkdKsE6\nPhm4BA6oAJ10PYjr4cDvKK1RsMlSN1wNH/Clr9O0I3KLJjnayryu6qPOLJzx\n2QKiOIzKoF7u827SAHjX/Qg1cUJ4tznZ23j0nvIV5D/FH8GcYI/GRBmIZLkX\nXGcGSzAPSmcjkc0CiiVCTXjbcM/ODjBMBQ/WgdWxH5HGU767loNSXmR9Dlqx\nMHj95ElWgDuf8pXOfSGKI3kiIO6s9MVwj81c07n0WtJV2aXFXdD70Gsmncuz\nQYVQz/owAbJpXz3dEr7fwt/lf7bYBky/6DSDm7xkEDlQqx5i6qIAuyFuAA0V\nv3oAblDpmZBik2/NSLhPXxyhdA279+d4BOVA3muDEt3O+EpiYBW9wQnSs7j9\nMOqUZPNt+pDwuFMAyDm086SCNzN1Lj+FJ9Yrb3jdOloKZMuXK6+XyRlT0XG/\nw+U+\r\n=8lBi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF/PuOmj5b2B1UAxrOxVG51EbxUx+VAfsSP29qXS4BP1AiEAoGu3nQnM1JDbnJ2kCXToFRhsLrlB93EJ1M+ZWSFuE8c="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-master.20190108233554_1546990614907_0.1105795718357463"},"_hasShrinkwrap":false},"1.0.2-nortissej.concat-enough.20190109221257":{"name":"@atomist/microgrammar","version":"1.0.2-nortissej.concat-enough.20190109221257","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From definitions: Defining a grammar in JavaScript objects\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"3584243b2ad75ba2c3c9cbbb52b65be95bacbc03","_id":"@atomist/microgrammar@1.0.2-nortissej.concat-enough.20190109221257","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-U4PkVojK5I2uLGkYIQoP/TPMdq59zxBWNFcNjcNaWtyvONPnLKJ+4pCo2hlQclpp+JCgXYI9RC9jKaRKLZszxw==","shasum":"101c053ccc540fd5a78225301faadaba8b851cf6","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-nortissej.concat-enough.20190109221257.tgz","fileCount":137,"unpackedSize":259399,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcNnIoCRA9TVsSAnZWagAAAqUP/AvyzNIEWio/kxzAOQAf\nKL+cE3gpOHu0tS3AjPx0V+BqqhLhfT8iBau880M4VtVfQTHUB4Cv41SGnLkl\nDPKEbgrcNsQ1+p5f44MgAVO6eaBpSjjKe1h4GvbgskfgJmkUwhYfELkEqbw2\n9m5XLsjn3cdG8FNlXNSlum0BMvYmalOUIW6EyDYbZ+fgxqumpgOl+RRmU+cc\nC1pOQ7yp7vUuIZe4H2jaSf/egS29wZplUkhCpMyXxLNxRlwCk3gd96WE83j4\nHUnjDh3wK6fm/jUS793usGK1/DbdFSo3eEBmMadg3x9HO1R830/hg4vEG9Lo\nz3Fo2WpkXbTalDOCsKZFrZpjx9ONyL5wfdYARRz5Huqg/z/SNdro/+wJ0W1f\nHE0rGTPQtg2+s8zQ0DkKQgxSaoFzdZH5s7f8kMuZ0/owMFr1wHboc4tZ+c4a\nQUeO68aSy+jH0xzUBO0NbWxWSRWD4bv9uYJdyb5PWWWFb3Cf82MriLbT5yjC\ns5RDtfAmISejy/7AgXmu1jKVxRWMT/tDX4jtSfdRqE+iRxGguhMh619ExjgY\nY3Op0NeDBn2cuu3aTOVHoJQ4mp0u2px8xZxtrmJeh5qu/hBTzFvYzw1aEPzI\nwXfBt0hScXW0S1/0VP5ol7Y6WhGmCR5PfJT+rdJNynNJU8oHFlQGt4wP8ZoX\nj7E3\r\n=v4gn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD8Bkh1MPmCymciU3xQCQiC3DYTIrYX1qvUZ61KObXjIwIgD39qAVpxVjbr2Ecr5IpOpln61/j+UO2RwMqcR1hae5o="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-nortissej.concat-enough.20190109221257_1547072039454_0.4728250959847502"},"_hasShrinkwrap":false},"1.0.2-nortissej.concat-enough.20190110000649":{"name":"@atomist/microgrammar","version":"1.0.2-nortissej.concat-enough.20190110000649","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"01ada48953c54ad6e44441691f51c476e87f707e","_id":"@atomist/microgrammar@1.0.2-nortissej.concat-enough.20190110000649","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-NKrEaHmbi5C0wDYkYeVO+wueajyuxgS5nGeP+CwJyUn4V/dMAnUKxPSBDRSnva93sE6c7LLkOarVFlima1am3A==","shasum":"be05c1fc52d55039d4e414acc2656b563d338c4c","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-nortissej.concat-enough.20190110000649.tgz","fileCount":138,"unpackedSize":272468,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcNozbCRA9TVsSAnZWagAAgF0P+wWgHF4mCAWZGd39lgZd\nyV3IgKd22v1BStiAz3ctOJC8kGSDIMkKXtygPWBAGV3MycuQtsd82C6zT6uG\ngfIhEIYG+yfdGjC01POdAoli+mE8dr6wnjRHVjKczYVxrsrblAYlpHkZIgap\nZbUcOWaNPQLukGHZbMhxvPluzGDlIZO8KBVhj0VrnfxVMld1woIPbjRaaFSS\nXc2T45iI+WmcSeVyKEPf9Z6BTxv8OeYmRovSRcs9zVj0DU0BkP8jdDaejRrv\nBsos9pvTOLACm5v75OPtvR9Xmwy5n/uuLbTIFozYtsgEAVpCLr7t1Cwgwbuy\nci74S7LT0CDdwQERp+XzYpRRu/qN4ntgntP/OvyvjoppAJ5MrcQsRyUxtesb\nyZjA5kCQNwKw3U1shCMr5p8oQ5GGCkSX/IcH1TVJmoLQr/1ka+rh3FqH0ouG\nK5k7d4gmiV87HLFy6+N/kk9IyRWysBpsM+bG9+/smkq/4MWpHxHy7OVfGc1F\nBY3lA4PPZbBtEfqH6DqP3fUax+TrnYkGWDPtT1w4gN9LtqbWLOCj/VAVbX9S\nIYKbSHgKz54eweDJb+8IX4TrpiKC64dVOkrgB585Alhjcno1db4y6rQFHbat\n/J9y4ytiT/ElvupAatCnoFS4x3DSpdSJQE74sLfkBKo2oVzYy4EXq61HvXcC\nkgXW\r\n=8pGL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFNHr92o88nTWiAOKGZXnsE+6RjXkhd2nzZ5QItlefOEAiEApniribnRnSkhaXj+/E0IP5tyqgAfvPLU0N02mGJxnco="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-nortissej.concat-enough.20190110000649_1547078874645_0.4707573343847691"},"_hasShrinkwrap":false},"1.0.2-master.20190110002349":{"name":"@atomist/microgrammar","version":"1.0.2-master.20190110002349","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"5ddb28382040edc2b0233f88178cfd699cc07257","_id":"@atomist/microgrammar@1.0.2-master.20190110002349","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-0zjHGFJE5z+pjEgZEI1rUlOcOhnDKYSlE5b2yiGiVWH18607e7MSqULRJOtO555VSSxD1BuG1ELqXjOR63nWjQ==","shasum":"75a83610f62193a54438e2f37f2d1f188e67cead","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.2-master.20190110002349.tgz","fileCount":138,"unpackedSize":272450,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcNpDkCRA9TVsSAnZWagAAP/wQAJuTNXf/epC95hCkUhg8\nq9HrAw6DqkJ+YlYoRpNUYN/wNCh+HEm0AfWx4/nlU0SAA81hltv3rfAUGpPU\nMfIW0Os6F0LNDtf70r1YeXsFgbsjGVqTVq0DIpfwaZkh8ITLIfu8/M7/NC4D\nZGeVtfZU3Xg9JntPfv4oYMciV4i5dvUJyAIAPARI86piRwojrIXQGLVGLTrD\nEJR/QdjJJqSVB25soonLbByn8u44bhjIaSxJFQeQK9wcSIfqN5Co1tsTM9eO\n15RtwJ9w9RNXXVgWKBOk3IYcXTBsmaU2gMbkuTVwjqinwRvpKJOMffCpZ/f5\nY9CIKUmkX9j0vOfhWy63+uaPM4EQFaUCnRZ2SHO+ZR4wuWQVKhP2hvGmEoBX\nlvGE4hxqdkjyNWpnPNUtE2AsB8TlFso6sUYjZdz9s54jS3QZ396xXm5qMzjN\n0hCoBzyKVpHJpP46ugkENQhOAKWRu0784ELSmVGnADK7roBVWwyYkE+YwNpl\nRHl89cKWoquDhmkdjkR7ke+i/qgLM51dLDtniQpqhWQE3vXM2eguSxYuBM1X\n7H79y7vfIsxgSA1w7nng7FlRsjPJO8AZqkt0QEy35bF7RsEX3I4ATaR2qcjw\ns+2bd7LHaQY2YL1Ye1eQg0B3ZvMuf+2mScQRzBYg5DpmW+VZCTgvGv/d/SSN\nlQv+\r\n=LQLz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC4c9AGXLaIe2s2qdAcNroY8+IXkijUjXsPTwyn6vOcrwIhAMHkJJa1A4ilxKF+n4BmMRph1zlLVEi//nl5pVROcaIp"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.2-master.20190110002349_1547079907513_0.5648247034103544"},"_hasShrinkwrap":false},"1.0.3-master.20190111000638":{"name":"@atomist/microgrammar","version":"1.0.3-master.20190111000638","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"fe642733ead8a6a499b0eea7a1009736adee7987","_id":"@atomist/microgrammar@1.0.3-master.20190111000638","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-WpsQ7KZl5X9nYdy3xkNVrCOBL4Zca1U5/1BLiteZujVcQGbmpqDGCk/jBWFLVJzHQsmIqt//P/i8en2L61R7TA==","shasum":"a07bf2efb9ce2455ddf005454d216720e8226791","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.3-master.20190111000638.tgz","fileCount":138,"unpackedSize":272450,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcN95gCRA9TVsSAnZWagAAVZcP/2gnGB/sp1x8BBkuEff4\nlt02rMKmaCs157NHa0b+KVh/+S+4PilTRAjlibgE6EIPXAAqo2UwEVrZia4q\nrwHfHVKbN9GOLTyMfB9fCCAuFn1EDwx19YUincQ7UcxG7m7TsKLx6vqrAENw\nwTxa4sV/n2jPEISwDFw6RiqrUuewyJ1w+JEc6gERTy4k1GGoBUfcXyIwaiqu\n0TqP2OUdvpa3Oa1FZs54qTqnsO2FRuq7etjUkMicsQC6AwCtXfkWLqgsedOU\nAevv+6YvZWm9BX+cerWtXCOPnab9FjyQhVbcQU+jBdGqUf7rxS8hmD6R6wGd\n0JgEKnRvFie9O2BgCTlyUf2dm5NHW8YlzXInJ9d9WDRlIwX9t9uw318W1ibj\nwuHwYs+RI2MLH1aqDa2UGRD2Qo9d7jLCwfqB6I2/FhVViAU+dvuBEzsx/46Y\nKVBldWLj7Oq1DOVTtd9X2oUeW2aClyRtgOsPdzNNtZQ020Q6lNxlmbw90qx8\nw2IOnljQcrDI0xuYG3mu81IKUbxTMOXy6bYo9bQb0+wYxOAtvI8EaXxuxdLc\nHmuw9nfwLukF+xxgMm3ltfra0RMbb4WpwbmE51Ucsaq3mf1SMPx9EqdbCl5T\n4vpi/uGSOURFcF+LGMJOGTW5IsFhspBV9rVAF+kV9hvovGQm2wiLr/9bIB06\neIDZ\r\n=hsR8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC4GmQJhc++8FFU4v7+2l33X2QjI5zqotlXcYbaqHl8EgIgc+JfCwagt9ort1kt9b9S48T9wDfspdALQrx3PMqrBKw="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.3-master.20190111000638_1547165279676_0.766802827073515"},"_hasShrinkwrap":false},"1.0.3":{"name":"@atomist/microgrammar","version":"1.0.3","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"3ffe89f0dfc907d80c7a82b2f6d74ba65070cc59","_id":"@atomist/microgrammar@1.0.3","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-XCtu0nnk5tiDMYsBv+hKNC3zbTIKY8mC4d634y4+XUX38FqXMm9TGSSWGeUL3/jL7uai09Gs3L9JfDUep3838A==","shasum":"a5ecaf8c1c30e8490619c9b5d6f82c3d3205b071","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.3.tgz","fileCount":138,"unpackedSize":272428,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcN9/PCRA9TVsSAnZWagAAQr8QAJqyMI4xsHu4L4QsCFkC\n3vqgZz79qtu+X6+Msqwn5AqRf5qSOsFrZet+LsVrfkAhpOX61y7oggVZb6xA\n5gQAubeKC0V9bDtd+QvqYRWLerdinjt9zSUaY3PO+W3OqB6GIX1NwLQC+Bnl\nr1wl1TsqVr9nAkogDqnRdsSVGd5jKRVEgOdA6fbCTskHUF3Oc8S3lxOj6WaR\nCAMGacx1ghUPdMqK6WMD9UogKyOQiPA8vHgVKfA7LK7tbWJaPmCxQxIS+3VJ\nHzAKMov1EPibUi1cXOUB+K2ln/T/hbNC+CqrGUxXzaFNTFLr71ayAH9ycJTo\nM2IAESj3OoCmekm2PUs2pjF19CTshuQ7aktQjFAR5OIkIN71bQ7FhSLIawXW\n397UoEz3EHNQDofcF0mszl07OWcVLx7fLhX7ToM9AF1cnP1nBqyIA/5cAKGH\nvwgrOkvQk5QiU6r8BtLjAtI6GBEQArNWgZsGpH4TMlhZeSYUQQuYENb7ee06\nnd6Ma3Qln9pIyG7Eay496RnVoq0M20bAI+HrMOCxvjEqQZPwznGqvoRP8gxC\n7YQXCqSPWWgmQ4eTM2+QHoQcygy9ptX5f93+MKd6ZIDJLTa9KafIQWahwxhN\nFb5iRWz+zUF87VOfjUkugSMzIOk6CzCwEM03efTFWseeKQdqObJwI9Vt1lo8\nllZg\r\n=MBmL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDQZ8O4iTAS0racIRQ0/W3oxHb3k6z432/wI4r5skdarwIhAO7Og8OzSdJkpmUmWf/JExjJLnGCTS59fl/DHuE45Olx"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.3_1547165646656_0.05750154287898157"},"_hasShrinkwrap":false},"1.0.3-grammar.20190111010520":{"name":"@atomist/microgrammar","version":"1.0.3-grammar.20190111010520","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"4b89ba21b38b6f20a6fd92b5744c27953c6c419f","_id":"@atomist/microgrammar@1.0.3-grammar.20190111010520","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-0U565jvOUSJCdZMCOFMzUOE+D/VrkqwM6RhzLEQHdErCM/JKs2s+lZCaSS1dR23Ki/GPyqIujamyYEA7A5CdtA==","shasum":"788b2a9feae2bb0b61fcb1c1f7b6ee28220f416f","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.3-grammar.20190111010520.tgz","fileCount":141,"unpackedSize":276803,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcN+wbCRA9TVsSAnZWagAAOqIQAIlc/qYFgnsjxB6bODH+\nrq3XPP1FOtZvAovSzSPmSs2QrmnN9DU9nWZZc8DiA+sYoYdrh+C8kXLkRT2O\nlntt68p+8K7x4pCoL86LYEJWR4SyeInD9y03oVoRevyY0082SYR6m8s6ld6L\nwgPx05xyaO/cRgiJlznV+F24oJs7kOndbtk3kOngpG2z0dATflY33aJskLdF\nY90Q3AbNQlGuiRMtpdXuhYB+jG+RKpHGB0gnqjaFkTXoPPd4sgt8qrCu2871\nxuaZrDII1BH27knA42J/Ub0X2FcaBeYuNdBzuId/apVjECypr2+Y+CA3wMkJ\n9O9djUK1mvgW9KtJcGZphexgHdfLMbzU10r0CvAkGKti8A+tiDLg8NZO2D7w\nfCwX0QZ4uXuuf1dsfQc2vjz82y60KuTRSxt8fNuI9kNMCcBCnVxELcWxMAaf\nU6uI75dvWFyf7TRHod49dXAoQXXY0zdqn3vcGJWOAZP4VIvFFjrQkMKzDGR/\n2tuwhzAf+HUafMg040BCnmf+UHCxepNNIL0W7dxP+tpAaORzVfEsk/VpjP52\nI68tYBt2/2YA8S6+ZQzTuFbWL4cTcBhxWek8qriiNVS8R6wHrsftJWAsZPMa\nP54u0Zybx+cR2eFLVQzvwiZyIUuFDvtXof2pc1CoT0+dVw502kzzwtg+CgNT\n1soW\r\n=q09B\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAF+HbRYNu1pOb7MKqDTLHH+mHffuDSCQDHNczoA+fDkAiEAwWjm7rIQZx/ZQqAqhzwpJyPEARWZt14iLpkdSwzW/Ew="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.3-grammar.20190111010520_1547168794868_0.5686169592953401"},"_hasShrinkwrap":false},"1.0.3-grammar.20190111012054":{"name":"@atomist/microgrammar","version":"1.0.3-grammar.20190111012054","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"2734626918a4f66e1aafcdd5cf24d32c40f34b21","_id":"@atomist/microgrammar@1.0.3-grammar.20190111012054","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-7FUJ4MV9MdeQ/JzMmrHif/sgDUgIIgdEOH8QN4Y7V2wy2JEQ+GnWsb76v0lDZiBAah9BPpswfk3J4/o/FmzL0A==","shasum":"342fe7e656c4a9aecbc150eff600b3d271a36056","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.3-grammar.20190111012054.tgz","fileCount":141,"unpackedSize":276884,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcN++/CRA9TVsSAnZWagAAC3UP/0KX5LxuRJtn5z/IqAhQ\nBOOIXqeGgtamEPY/FC841Eq1dt2Nhe/qfD3KhVssDJaf1aMvYK7dJWcyQU1r\nE+THjrl//rvkwPGvXON2eS9rV1MHXRVlgd+TLpNaAJVk1Q9mPsDXnfYhspzu\nzNwifuuiEw1ptK/DW9l7+uw1B3hOx7y7Q0HWg5PWyujPkCcqtT4afkOye2b6\n5COuCQ3o2VlhKyDvJGwLNrjibeKV9yqpPVYXBNuzMfuCChdggEDakvFTY/sI\nijIARWnAiVKgFvzC1Otx0gb+Orq8hlnFc7G2Nal3Qrk8tP89YzTO/O4nuPub\nrdpcbXiA8LMAdiosrsOdDkJINu5F9w8Khev+EJj2egvtpRwgddUGngYSLj6Q\n2nQ0+qmyi9XxIFzGm32UNu9+DU6JQf8oeFOR1wxy/HIffHrnII6YoxgmG8W5\nH3/f0IMdkYodhb0kkrYOC3XI2t1REoPUZuCGMOHJ9FJA2QPft5WBUzK/gr9w\nleyR7zttm5KQavdw7baqegzxWp/VvTsSSeaAR/6mQdQgE4y2441bk2noZMzd\ngGsv6pcMWja4H/MaEA6lr+7pYb0aCYIIiMANnNBS0mJmItXg2z+/QJpb+uQJ\nkZJSO/o+MD9kR+8qlwoAsWbLd2RYkuP6NuvIO2+7ifIqLOY5BFvZvjaFZYJ4\nat4Y\r\n=ukPB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDGYziYgXjK/5NNVKlQFpme5LNtn7Kpz2OMbRTQp10V9wIhAN4g2lTwshzPpnFAfeZlM/IBfW9AMa9ER8DE8tAarHXX"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.3-grammar.20190111012054_1547169727139_0.2037763688601799"},"_hasShrinkwrap":false},"1.0.3-grammar.20190111013920":{"name":"@atomist/microgrammar","version":"1.0.3-grammar.20190111013920","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = Microgrammar.fromDefinitions<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = Microgrammar.fromDefinitions<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\");\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = Microgrammar.fromString<Predicate>(\n    \"@${name}='${value}'\", {\n    \tname: /[a-z]+/\n    });\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"7b4912377f423bbcec9c9234cefd14b016dbc930","_id":"@atomist/microgrammar@1.0.3-grammar.20190111013920","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-ml4RsoE43I8Oal4y7ad35Cmyoq8RRaIx1MtHrWD91+h11gbBvtKZxMBWsq0INmkEwlIt0L/f667q+VlBeo8EwQ==","shasum":"1ebf77204ba61f0ce0819b48f55a6f3fbb315e22","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.3-grammar.20190111013920.tgz","fileCount":141,"unpackedSize":277365,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcN/QRCRA9TVsSAnZWagAA618P/1ThbzLzGdXuQB/MHnty\n3RqaBcit2dR6seQZVTW1fgKrLBnx8QuxjZvCDRKxgixaYcoUhC70ebrDYQux\nrbPCzYVqnIGbs/zMdaxMVYHM1PIjctWOg+DxiZV+LX+hYQXSjn5EYlbdDM8j\naCjp+6dXsbLJs4Ri69qSfYCAknKrcO2VilO3lfEIBWEo7vSbOKBnMis+4xNh\n2eO19ysz2C/7P6LIrYugSwf2SG3pFP2Yxu74/veDILW+Y82LzwbHPSNdkPtC\nZV7JASTtI6hBfj+v0LSgyUnkaYdyRJGONBcN91zlQxoqBQDE4yLPU3eRxU4q\n4gbN9hjQGVVGeWCGmRTSKMMfUmLJJDUbcCy40DP8W+PvvLtWF0daKnsWThJ2\najKB+fQvcregBE0bImUlHXmMGp5jGTlHo3cd+RhwHp1bC85zzaMKOCP2Ctzy\nmpbc/1Vxxw1I9DQkdvQxLhBpZNg31QbeyRpxtRdN3kJNChMM8wajptK/64KD\niwi7n7LULY7p2ZVIP61YZF/pXzwkG+YpmzFxjtOxc3IelraHV5lTo7/R4gul\nOUM/+RcKd2pD7hQb++OqP0UDG92LIanB7V/3nHXrAX6P7WPTsFL2geD/IFvQ\n3VpKow220aWahjaB7B5zfIdS1WzO8wGCH8eaE1hDBAWgUFGcaRokinynrKZS\nQIo4\r\n=x4fc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1E5uyhKgc2tMGLpuzHiDJXHFa+v5A6wwJqinGdUxdJAIgE+oTQcVeVOYYQWxvk21fp/7lYxTmny/2BI+f+sSllKs="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.3-grammar.20190111013920_1547170832788_0.1595632652003014"},"_hasShrinkwrap":false},"1.0.3-grammar.20190111015924":{"name":"@atomist/microgrammar","version":"1.0.3-grammar.20190111015924","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"b26f8110c23d3873d701a40b9a66b60836042905","_id":"@atomist/microgrammar@1.0.3-grammar.20190111015924","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-bUlb0ThuySd6nOtEXjVvx8yN+Cdq30YLfgMi1JDjw90T9iZ34J9P8ymmWIz1Muv9PxxtWhlmbpFbqR3JQP8jXw==","shasum":"b60512168fd23048e47b539a5ff5f2b0a7155613","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.3-grammar.20190111015924.tgz","fileCount":141,"unpackedSize":277344,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcN/jJCRA9TVsSAnZWagAA1/wP/Azxhr0B69eLR4qNpamL\n8wvTwUNZiYP/iPblADsdYIu8CQlTw0X2ilsbSHfAsbzS2pnh84niYDcx4hCY\nHnoyn1RVGl0QLOPreUb671q30VZdjcj83QPZq1sCmNl3a4cWIyk3p8wIvH6F\n0696V7jH7ltGoE4Ef7kfMLjct7U5dxzKKEMBNPx2RK4/PfrICzWCeUz9exOy\nh1FggZqWwyStzsE93CWAUg44R2cYVkIW9syr5536gRkCqrw7/y+MID9lKn03\nEvlbIBlJH4rUFClKDKAJjhA2wUAtGS9chZ+ZwmRYO/J8eE1pCCczCT5r2iai\nBjhfzLLnzmDoydEQXjlOB2+LSx0gfjuqe9fErgtQsa0j9bv3kX/aS0nfK06h\nustr+1c6np/Lf0vFD+k+wQsQ3nOf6vBtyOr1Et0TLPj2bI5aTuL3K9ONAvLB\nw/E2zoU/HO7nZr/aSBXl4U08ndjqusSHKHQVBAi+8wxOui+3sABNEtPxvzwG\nlva6mthc3s+M4UMzv2TdWOzD2QJX6I+ZPdmwmhBmWpIIMxHUhzf8jdtKCJaU\nXr1/60uPsiTk1BHZ26lwY6HYv+XcGIntM4OEaPjZ4PdU7m+QiBmMPXQ41Wmc\nfkMfU52LpoSlZyaPJPvreWnOeLvE6Ahlf8OsucfBGIuHon6VPf9/3oyHQig9\nQd2l\r\n=Y+m/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD7uwg3ZWjMtLg9iELK0d+v4Ix1/kvD6I4tVOsnDmkT/gIgSlPL6J2x2widRC4b135FvPskRbOVthHajP40jRqaZh0="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.3-grammar.20190111015924_1547172040704_0.40700709036499694"},"_hasShrinkwrap":false},"1.0.3-grammar.20190111181509":{"name":"@atomist/microgrammar","version":"1.0.3-grammar.20190111181509","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"d025ec554bd14de426af04495c5641e882d6219c","_id":"@atomist/microgrammar@1.0.3-grammar.20190111181509","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-qvW7hPAB+9HniVw8eTTd24Yoni59//DwKZjySOV1Yla6lg8GUi6oskMlfNWh6u5lERsqapgziRLf/M+p3RtKNQ==","shasum":"b73b3517075f285f08745500bd1e4f6c56f3dce2","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.3-grammar.20190111181509.tgz","fileCount":144,"unpackedSize":278740,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcON3QCRA9TVsSAnZWagAAOfQP/1yaNHddfG0v1jxSnV0l\npYnGUV50Mkl9vpXn9ERrZT9ZcxaykTV8gQiMi0dvCJR54FceXOuo5Mdwg1z8\nE4h92joyUYSEYKoN1AmwUeD+mwH2wKWVNHVdX7pXTk3AAeTchqyp/85wwlam\nGfK5OuojN8TLI9nqGdwVX0IdQgoxZ8yU8m8rYj9vNl0hJuF0qUL0AF2O+yhf\nN5fK8fnJejWXHT4mbXGhFVh1dgUdKcWt3z1NWio7On5rvKggBmfp1lMMB04X\nZPCAOYQ+Ur6ZCajjGMoo+LZFu+ntgfYnxoFQ/JUyj9RqNVig8MS/6zx/WwSN\nCC8jKRdHKy43I1rARztbc1Fbpm3+4kDIXsHFWslJsOnBBo9CKKB0XCytUpVc\nSnZtNfzsKlBhTDVF8m6wQdi+RCp7u6eZRuXxP8faqlIHhEpunWAAgLzsby6D\nXA/Fi5DlSZrH0+8mVVw9/j5a+dOSvEre3y+N3ETkC8+iTtfAhEN23i/z8lC9\n7K7chf30K6j9gXitxiROYWlfA30Z9RCQ0D/p2kJHvXEdfVJkP0OCVtzEKOIo\nG4LSUJ8r6NPP0kZ146V3rBjPLlKKyyrirf2LkYXW8F/xQg0f17ihLSSzGN5B\nu62cEKJgx+jkA1FdpWRhzGH5c5M8G5/ZLwVF5VLYApl3pF8MPT9SVKpjnx4F\nFF4L\r\n=eI8t\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDGXFRvsCHdUuXbdbEuO3K1MoTJF5kCAWhQCyFsb3oETgIgMfzU4T6kjPNkH1e7ugGvjIY0gtMmaUPviyVTdT7WYow="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.3-grammar.20190111181509_1547230671528_0.9496428255955263"},"_hasShrinkwrap":false},"1.0.4-master.20190111215805":{"name":"@atomist/microgrammar","version":"1.0.4-master.20190111215805","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"092fb5db6d6ab3d09502e92fb5946673f37e6c37","_id":"@atomist/microgrammar@1.0.4-master.20190111215805","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-GwIV3OdV4X6yic90x9K1QPF1Z6uduuhLTqt801rDL94mxjhXAwEXXQDN+jauPjb8fwQ8HSY1Gef1NVmUhjPjyA==","shasum":"308761af5ecf63cf0cb8b99e04222438fb30c71d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4-master.20190111215805.tgz","fileCount":144,"unpackedSize":278827,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcORGwCRA9TVsSAnZWagAAoFAQAIeDRNSeJ0mD5UoD00GO\n2XUdtS+KpkJWlisE1gjAcQDMo8lN0npaPdOhsHe+FdpstRwd/aIvRe5Mtvil\n2yWYzaPUs4/gVgVbWYBuzDtv2Eju8KFekNwTozUTYDsdnGHI+dWQLFLEZ0go\n5lKBxxKEtPUiNSApwVQ9jHjXVzRFIPmNWmk4/GiqgN5RC0JkONKGGCTSi2h+\nofGW6D9slBiYzqCvET+C6b30K8VpWI5szX8zaRfgJPevM7b2u43LWcVDHWC/\n5p1Y58UjMQSirL5qqI6qLJQsCuDGCjIPf9VtpaXPstnSjPWBwWHwloq9N/Sq\nNAlhIK909YUB5JTWZBoOXjUJJ0s3eaoB1X8+Fi+A8FZwnnEVQyS4B6gRODua\nqy3osEnmajGfQAbBX+/dyNx3ozuW/Tum+T6h1wdvi4R98cKPilOR/PPVI/H0\nHAmo92A/1xhWu5O642SCFss657uwGn1N0aYIGTO47ygKgq/7O4y1GNmjUal6\n4RueTtFWsVNuhM0xaCskU9NUIFY3791Yl2eLwe7O7AkggCK3fJ/e8Jp8r0cO\nNlCUqHyAqBily/+nRjNZObNhr38pOg6/ty6EHygbfETQLgVjWqbhRdf2rdEg\nP1MO6CiLJk9cvcnwdt8T/qvw3D1DvaSOgCwPyzkoij1jEy5GTwA7Fyg5rYF3\nwK1c\r\n=3g/v\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICumaQrRfzl+Nbb7IFBlLT/8YV16dCpxj/0wGgkKgV99AiEAvEueNIwVhIytNNkGc/jp2brSv/3Zg+6XUQzR4iHomaU="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4-master.20190111215805_1547243951436_0.20797995875896746"},"_hasShrinkwrap":false},"1.0.4-nortissej.failure-reporting.20190122024851":{"name":"@atomist/microgrammar","version":"1.0.4-nortissej.failure-reporting.20190122024851","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"575642a82e54a36e2061ffc4c48cb679659159e7","_id":"@atomist/microgrammar@1.0.4-nortissej.failure-reporting.20190122024851","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-sLm85iCW3QP7cG+BjG6XXBV/Fq7z476yl2zo95b/WDTxaQIBPAfERugFgFvR1iP21T4r+aACmm2i1wFdPsmC+Q==","shasum":"2e5a065b261395500f89bea95156652c9925e46d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4-nortissej.failure-reporting.20190122024851.tgz","fileCount":144,"unpackedSize":282348,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcRoT4CRA9TVsSAnZWagAAwFEQAJFIgTSGiInzzBdcWwe7\n8VrV/JGbOOXUJyIQSSXvNzstihaJIxSZGpgWxOnav7OXEx+TvRenHvmS2GnU\nmvGTcF26DRnXUiSvBRR3frDC54Pf2VldFpqlXXzePf76db6roXW5a85SFacP\nTMpfu4+glDNv7YwLQihjudHS/tgvWifjkfsnPdj9wOm373rHSJVgZ0eCEd2f\n1hEpAhQ2CK8TYFmE6lGZszUPejgxJ8Mxf+1Ts1ZatDqOQCw4bX6HNNHBsFeE\nmkrxB8pjdjMOjVVlfy+waTVyk244OAwple7DwpzNIgmm+zlFSC5E9xyKsR0r\nBqb2yWdfkEacseHPspf766TwSjRh2hfIdOiC5aVFUNe2S7XAQyr95jmKAqEN\nAk1WpOJGgjDBCBTyrqvhDj5Dg5GBWveXJvBhANZ2fgr6/W2zg9E6VueTl/vv\nH3VzQ+156aTutKV061H2PWwy3fd2biGwqPa1tTMNqw+zSg4O4BalflzzRAVv\n18ywpT7stKf5le4DSfbL8yJBGqE7YhYLwARLeGVqaadQ/ahIflV7iwzQMFdR\nAi8QHe+/1DvHjG6qbPBLpTeRX5oqg3KYGhHl5fdxDjLtzRkdaTtbb0QPWANU\nZBtZ3+y74AwXM7jIDU21TEu6/TlO7rcF2UFn1E1Beluzk5EAMVs3KjvnvkoX\nQgfY\r\n=e+qD\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD7wShs6WSgEJdEyz9OT/dVDlnLVQPTsjUZFNihjsEDjQIgJNOm9dRTgixtcYgEks3idhLGuAUEhzAJIXt84unXcyA="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4-nortissej.failure-reporting.20190122024851_1548125431927_0.9164694306604471"},"_hasShrinkwrap":false},"1.0.4-nortissej.failure-reporting.20190122032620":{"name":"@atomist/microgrammar","version":"1.0.4-nortissej.failure-reporting.20190122032620","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"bf3bfe354d318c904de77c2423cb66edabde37c0","_id":"@atomist/microgrammar@1.0.4-nortissej.failure-reporting.20190122032620","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-L6I37ATfo4cT9H8C3kGap5amftxESTsDk9/CZ+XwjK3Xg0T0/NBL2T7+AkTtXbJRg2GnishUtMycoeDeiA5qOg==","shasum":"db0099603fb0cb3a071ad1c8aa2cb0455a7cf35a","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4-nortissej.failure-reporting.20190122032620.tgz","fileCount":150,"unpackedSize":289172,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcRo22CRA9TVsSAnZWagAA4AwQAIQBS5eq5E1PYcjYi3bB\nMxnu8rYdDhqkQCChDcSqrNJuyeGLzF1TeSPWHh8ZCC3BzV3KOH88vT1TYjDz\nmjwEAPDf7vFyIEovghpbKPmZggEqIQ4UogJHQ2tJJ5c0AJJ/k7nQENd2cvrx\nIZ93jjUUNsswXP8LRSn/eXJe89O8XaNKSRHOAKZszQtqt9zJbrkL/zpscVoI\njfEaBwYoe0OrRm0qUerRLYZoQbIH0D2KJbPjorIwVI6XTnrTW/GctGG+OyAo\n3XfleeA174T8frIMsGvaUsGpsWDFF0xXAG/d633Rpzd3n57Jy+dSYSfRtwL9\nxGDl4lVnL1PTsog2gWtK1F9gk1b162FX4zkzhLrMYPDyUMvD4oVucki3Weo8\nSZrTByGnAcnmpGasdaSSG26mn0QfRCLrIje/uZdy1LDKFBuJHb+dj67yKUbn\n20LezpzRfwhqJI7aIWYExuiBNbmZnUS/+gYgA3MwnZjjRFqP1NCcjgj0oRJt\nQdQe6hqRMTTNqwRxg19cICbrV9vOECfBEy5uPCPwAxDZBZ2ik3TkY/xfDQc6\n08ZU/O7ZwGX87w2RwuYnT9GCMS0RyvTNvgRg/O9iGO7/TL8YGmqUZ3+WFok9\nq+elPvzp0NsuAuO3c5ty/s9gFMSXi97aEthT8r8Oxm8pB+Bo58k1P4wwSisf\nocVP\r\n=OkCS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCrb/00CrlvuKAcMXj0ehgDkxwdW82eCPpynPrPdxpuBAIhAKnTsqEKZtkgNKWDq1PBpEPBei8H1X+IJLW2c8B2qFT7"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4-nortissej.failure-reporting.20190122032620_1548127670136_0.9201123513080052"},"_hasShrinkwrap":false},"1.0.4-nortissej.failure-reporting.20190122034452":{"name":"@atomist/microgrammar","version":"1.0.4-nortissej.failure-reporting.20190122034452","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"daa62db488db2afe9ed54b0a2a20e25f83763f53","_id":"@atomist/microgrammar@1.0.4-nortissej.failure-reporting.20190122034452","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-4wdrArn9qcNimXSEGO/IhnAQeATrmEWZDwK1ZF0opaHe1o3jlhrbqN8enaeJmPWQfCs1xuZA+PQ0nfgnZmuxnw==","shasum":"55872c7c4701a32fa2fe440f6a4cccb43c8b80b7","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4-nortissej.failure-reporting.20190122034452.tgz","fileCount":150,"unpackedSize":289178,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcRpIbCRA9TVsSAnZWagAAySQP/17tG9Wd7N9Sz1l6se/F\nlQHWPD+DLs8Y1T8LLb1bGPqKcELjCdojfVDmBrYhMEx16yw21vstgpzokY1V\nSKEyaLGbc2CMBfHQNKfFZfyzDrd8yFatwERs+NcFuj2GIK1mBiZ/zAjR35Lc\n/Rfhr6f/92y+4pSwvHKNnwC5RTgdyZLKQLKYvlvEED2G3xVATbLZ8HTxNibe\nS6nDBJkDu24jKrzh5HHr93INj1GzDxKD37LdQK57iL1zGJFq/505atzuH/fy\nJ3gY+7w6O5uGm6V+NmFBEUyOHdyR2yDmza+nJmLSYloxkSThEskvYI7n5IJC\nKgeSkxzUIfWoXrV5uAlX3B8SKWcGD3bV9NsYlsykQt1HQhu8VCZWKW3i4/oQ\n2hvZSEJhT365At8jX9XepASHrZgqZAYQMbQJvIxVTVFCTZ4olWV0JV0ea0x5\nCBBhiRw6fPMDrDLnFHY6C/q8mrrOvICe/kWbS2uSJxHfGThWkZqMa7miLyNb\n6S0XT9iodik4eWil25QT24uJ7BqGo+/IpJU+sv455BkUYtmPyjuLSuPDBlri\nkpIMVrpInJ73h4hTrAmTAcrjHVc7V4yTtvk0vz7oE5LTxr8F+OVM/l4/fMY7\nqNyTK3Fzv7bII85WbfPjOUr/LlQkWj2uZdTWkhVFXsyP7jC3o7AztOxNMZcs\naqyv\r\n=EF4T\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCsT6Tq9J1asy26t/2DUDX3A0VBW5s/xvUa1PkSw4NbdgIhAPw1fGAE5E8r/lQyPZGueAUgl46s4frVbI/GOfYJTQOj"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4-nortissej.failure-reporting.20190122034452_1548128794340_0.6376817673452104"},"_hasShrinkwrap":false},"1.0.4-nortissej.failure-reporting.20190130180617":{"name":"@atomist/microgrammar","version":"1.0.4-nortissej.failure-reporting.20190130180617","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"d79251181425f9bca6e6ec4836dafa0ee6c01987","_id":"@atomist/microgrammar@1.0.4-nortissej.failure-reporting.20190130180617","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-UxpoH9aQlfo5idi8MMIo8pxQrZSApAeNXkItQd/+ObuA9WQRm5JLkzvYOJwnnYojvrPG6dEKUAC/U6OXB6gnvQ==","shasum":"5c0b76affab1e2517e07a3a59c4f6e9e05cb8db1","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4-nortissej.failure-reporting.20190130180617.tgz","fileCount":150,"unpackedSize":289192,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcUefrCRA9TVsSAnZWagAA2gcP/1bJhZ07HbRm3tUZtXYK\nZv1QMfVjRHGWVwOZOv4VkPqdvCQQxAIPceBB4C5FnnWOyJGKRu8AOF4A5h41\ncGCeQJgYOdjGnDvYxKP/OVmMD705neqZQYwjvEjhFuTGY8730Qs8i2teAF+e\nQMidTWVeq/icK7IaTfW6HL54Kks1f4H9X0vqOR38yEJGaiq3nftfJ/lidiAr\na8JAIWfSCZFEFGBBz0YdJNhaE5wk8AhFYLynRu+6MKr3302IQ5xrjx/PDgWm\nptbEbsxVfCCjuf67jX2U7mLuw0ufXZDhYi8brgMABwO8CeKsmV1rBsroKUOH\nqLVc+vgP8R9ezqTrj91kA5H29dl0rPf+wN+VVfrR79M3It8pntcuyS616uy0\nK98eEb26vw3iuYX1JNyTYpfX0At3Hn4U6b6joE1G/2FBFhLwghKLy7PWB8Mg\nawwwubce+qaiir5M+nsqY/oUmn5BjoQwIqcl4zdQf10P1nyHehdoKLUAl/lU\neWrqwARKSFJl0vWEOyuAn/iisWTobUpa7Bl4zAMViWrCX1Bum11kp9Rr4xQz\nVB2W1n8WDXcADpTjGDYsFWj/q2SM24iZAv6m3+DkvTKt/XGv5MOXG1pZXojE\nybX1ZFoMTnUkg6d0+XKh/N461JGkRxvsmkwSM1Sn2tO6FXXVpHtl7Dw+EPfk\negRM\r\n=4lea\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDpkcddN77NVAEZgAa+ky8ULDX42KVXd8hl71XfF+I4mQIhAOcjvXMSZeUED+uJZNVTwcOucrDcquu2q2u4IL6EAp3i"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4-nortissej.failure-reporting.20190130180617_1548871658991_0.7980248462180268"},"_hasShrinkwrap":false},"1.0.4-master.20190130181034":{"name":"@atomist/microgrammar","version":"1.0.4-master.20190130181034","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"092fb5db6d6ab3d09502e92fb5946673f37e6c37","_id":"@atomist/microgrammar@1.0.4-master.20190130181034","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-WJltXQmMofDjvF1lHvgFaMzKeCqwXJgvSDxGQPGGrhPw4NMwghWPTclHNY9NJpiqWayxN706+jtRGK4ZmVVjCA==","shasum":"60fb2170e059160f85c8f5c2e42cd3454ec7178f","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4-master.20190130181034.tgz","fileCount":144,"unpackedSize":278827,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcUej3CRA9TVsSAnZWagAA9OUP/jBsFXsfmgfOnNdJKjIA\nOIxYiUqVDtRkrypcEMa4laOb0di2z9y5IreCHbUqQGJvVyG0yIvvBtG8PV+j\nh6aHmF34wxlCn1DZ4mIO6hU/bmZeDA6ezqBwS8kxuaRWrWotN9f+6YemoIwC\nzoupLe5GR4MGtOT9NRJl/KoF6pJYKyC4zW++hb8qc/bBxlmKufUAyrc7gE+1\npYf+HgVaL7acl47NVIPcAsBitSNg2dC/z/6RNGvp32ctCoArYmjMNYU85wSn\nWUHwfXqTTmxvp/1/ne13sfLwy2UkUmK/fNLitoiktP1cdCxfp5pPdKL781D5\n3I7NCy4nsoc4YfG7FzP2FoNzGJMA9VpUHM5FCLt6MbYiJ8LqXIQr4UYe46dU\nUvfs4UBtJlK7UQdDodzLtikv2A5V99EUK2NJvGExtZLyEquKHQhUKilbY5TR\nwfx1sZ+bhAdDe/LU0/z1FZW8DKYTYsDE9oEWVn/qk2lGAIMA8LqGU8wjdDV2\nJ0WoBvu4FaoE1oH8lSloQUh8FfMH285usKSYzenDML9Fnj9XkuxQaLBf56We\nBqNhb8HOPUgf5GBmLuI+bRp/1NlFRIGgeM05E7U/GsnbTFotHrMBXSJA+S0l\nYVLmWss7OtCKmRbzg+NaCwUWnar68h9v8oGgd+CjYmzKrG4lc8MZWgyqZcEu\ncYuz\r\n=1oo7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID4jhT91btUQic15M/6+NUtyX9nq3xjNQ0s3ATEmHOoQAiAFdtUvNBM+oqGI/I866grCHVy+xQOo5sRr0yYCl66Rbw=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4-master.20190130181034_1548871925923_0.936931172425594"},"_hasShrinkwrap":false},"1.0.4-master.20190130184106":{"name":"@atomist/microgrammar","version":"1.0.4-master.20190130184106","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"ed74051466e0e4df963117df51a7e436a95538d9","_id":"@atomist/microgrammar@1.0.4-master.20190130184106","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-rcSeAGCsqQc5XyKMDPxi0Uq1DKjTRdZBJ2tZhArbB72stlXoRvVpP8coiRJ+IkdHI9BzGkRWAxbDjQY4s/3ccQ==","shasum":"92e9e375876207c2c78649302fc8c72be51039da","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4-master.20190130184106.tgz","fileCount":150,"unpackedSize":289171,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcUfAUCRA9TVsSAnZWagAAyvgQAIFObuMzAYS1CjPgdlZp\nlNozCErCFzd5a0x97cg3UxIwVTs/UdRkZyjJDgILI3lNWHuQbQE+/S2KqQ8Q\n4/FgNks8oxua4wHxGAF65mN4c5dsJHezm0ZfkFjwcVRUXR6Ak4IXnFekYbsh\nReP+nIu+cRNvlrOPXtJ/ZjoMHC8EQI5tdq12fN6BZ36DkY4j9fHozmRz7mqe\n6SIgGbSJNiw8M560nLyw+y0NoST0I2tqYmxxSqPgglyHnqP3nR7FsrGFUDS7\nry4goieYg1H8TZveABsiPpkwvEJnYMNTq3USL4AS0YkqPY7s81nR3XMcc6yc\ns2MAYoKtwwTIRH2Y3iOKYgdutu9be7TrWJBYaosIKBVloHbd4aWj6jwvx3H+\nXWhCDwcx7i+/ji1fCJXMiVyPZ0crPt31g1HT+ueDqqcX6QcSa+gK4Z3TUsar\ndzkoqQGI/rBl56DcIwb7N8Iyislll76PFpP9EaVPSPbifABQzhS8IUo5yeL/\nhahJ1X76Rs7NTd6qIG0mMGg/Wh1GIqJ7Qr6x5dHsRnfCzdUU+g3iOflZQqDc\nwRqNgj8sahPF2GGvQL/p+WpVdTz0uGvTOo9wXmgATgsNszqb9BQsUkyOKHFH\ndqhDgZ74UafCL2gFuV+7xygoS8/T+uHVDMJbeDrFslMzO/nwNQmdcvBcHfLc\ngU3H\r\n=zxtt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBOX7nXdJGUJEYID8rpNR52H8IURafOoGqqy4k8k1CyXAiEA7hGuyTi+Nge4ar/docYZ/WRlMjPgCcIXPNpT8oAdRMA="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4-master.20190130184106_1548873747649_0.5727551027275755"},"_hasShrinkwrap":false},"1.0.4":{"name":"@atomist/microgrammar","version":"1.0.4","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"17856f67673757bbeef806eed6a457342fac698b","_id":"@atomist/microgrammar@1.0.4","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-NBQc20oMOypEJNxRYDIPPV+VJg8GuX9AkJxdKwMWgeZSyYx3+0fumYnV/r9+fFlLacFG5zAIpgc/iw1F5Z66jQ==","shasum":"048dfaaa619573ca5ba998c7df8936fb4b27d27f","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.4.tgz","fileCount":150,"unpackedSize":289149,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcUgU2CRA9TVsSAnZWagAAchAP/jVsvKprRa1Tw0QxSBtR\nWMOaJsQgSXsgedLYPeUishb0/kRhy8nYCxDHbpDIb4L6O8GAUtU1GbuQ5c+s\nEmv2EzLXGFo9fS3J5PcThmcjmsMU+Yr6zbvCJCnYXAPSv91jVugbFV3XTb8b\nxP39ZvK4urMzVrM5oDvk0dffoWY+BuXQgiHZHtXORyG/1a4M96H2iUKThLX4\n1GbXaT61Zo+0cZrAC19VXB9g88wBq8UL46RAHh+cHvtL4lZaZbFWIzvE4gqu\np8UtoRrEwPQV0XPbOPtNqOesRASaosIq1aIwvuwZD0acXmCkkCnjYlmamiBv\nYJZdbQw1gB26APRbvpcASTkdl62baFHcLB169uQsrWZdzY8tYfMY0t1X/O3G\nObMxRNAtb4e+y3AXQYc59yVSOhMuD6Si2U66OdUh1/e3CQIa7MNj0WTmKD7I\nX/yhmqG3zUzMxJHeOeMpTRUdW+A2XvlOOuFYeiFx6HoNgzwbmFuCUUcoxNjq\nsnvCS0CKnpNmICzgGIoexwwRUNJmpXMyXwNFQfYbqucFkZB6o90QKgbiN/aY\nZM+HqmNWeZw6AghZPLty96Tj1QonXUY7UZFYftARlY8PVj72PCSx9TYzLIjq\nnMW7rzO1ZHXsDbzvPpgFcWCLmhDbBuj7BxYwVWmGkxm87sxgoRshdOx+Vu1B\nJW2x\r\n=6V82\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCAU9y8sQlONEpR9WVYfbhv/JwQusk8NRhN8/Pfpy8SSwIgKokBG8yS2V0pv88UiR4VDCCsxEVA4H7vIvIcK/KHzog="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.4_1548879157911_0.09058439355650605"},"_hasShrinkwrap":false},"1.0.5-master.20190130221910":{"name":"@atomist/microgrammar","version":"1.0.5-master.20190130221910","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"b9defcf8522d60da89c9651dc71344215c013694","_id":"@atomist/microgrammar@1.0.5-master.20190130221910","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-BSp6WKKq8i0hlxbfrL66RcScgWR1cs3sKehQciYp0QRpM4R9l/vhbGwzxOkqoEF+xlfeoHxrDsIm799bb5mHQg==","shasum":"255a91ee3ffc229932efd68db8ba4fcbcc3e5e05","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-master.20190130221910.tgz","fileCount":150,"unpackedSize":289270,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcUiMyCRA9TVsSAnZWagAAMxMP/0ecOt2jmvqPEcoVzne6\njPiYlmb2J8ih0uD9iPnPeN55bdqrj82SmSdEYGtO21gs7dISiGOPuGVK7AD6\nIx6sJcLeqDpga7kfl4REomxfX7QlID6rvB8g37xIuHHUuGwpnn57okJ0l99X\nqAgdQwovtLP98ixUsXg+hm1lvGOG4vm6++MRtTDUSkSTrHzu+MfDFtJjZvmA\nmY1dQy8AyYHafBZ+cETPMN+Bzf07bWg6zo3tjLuYUJ62gy8s4L2FhUkfJx6O\n22mSOaBAqI8PB9Bd5qfEsvmrN872Nb4T/DaGYq9W6aKyl9hZjnwZ2gtt6XRI\nykV/nyGp1a90EI4KzOTI+DTjSzJI3QrZd3eU1nnREdV3HNw2hK9XKj2jWlxT\ni6tcahL3k/YUKxc7GuVMU4s2TAerVgvZL1gymttqnSQCGKGMFE7rjaK5zvE9\n0x65wDFVYHYt+l0jPmgjy2Nf1WUXoaJ7rZ8deoaFEoMi4nbmT2+JgoZ7hWZC\ntS95qPP/0paqfaEqp/exu9LUnWXqMY9NZGzZ2XivrNgR3Uk3WBWCuVfRuW14\nfp9D6I2CJ/tfTdotnemyjSGY7BDSJkj/DGg62ybFdY9ddSE2nDNyG0xmDHGl\n5KAvKSAnz7Mfr0AQOkZtob6JLgeDrImWym/hGC8yjKNIML3MWU8VkDptO8v8\nMBwK\r\n=Tvxm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAXASAAZwR1n6680Rvaa0XcRPWv3hgOYqlf1zKM2GpfpAiEAtmbCyTDxFukfGuHfB+FvddGpvvFkaJj3GlC2RxrfXRc="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-master.20190130221910_1548886833440_0.48656806975540023"},"_hasShrinkwrap":false},"1.1.0-master.20190131044730":{"name":"@atomist/microgrammar","version":"1.1.0-master.20190131044730","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"6ec50e297c5cbecdc1ec24326d81f2f13fca3728","_id":"@atomist/microgrammar@1.1.0-master.20190131044730","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-1BfMvHFux0lj1fxz44KpQmel4bVN46SYv6TT7paAEqti3J2IrbbcVgnBufi8hALFUDn9kBOjuVeILQzshJqoUg==","shasum":"15f2927200657ac34787b12adec28b8784ac8c43","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-master.20190131044730.tgz","fileCount":150,"unpackedSize":289270,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcUn4wCRA9TVsSAnZWagAAy6EP/1z6hzDE3bNrPzsbv04W\nZvrPZgNUtaC9ef3XyDcGiqiFDD//drFtifI9H+nzyfD2DBMjiIgEGis3GH1G\nImyUSfLPezSitf082bifCilEathzb1dpebrl/ZHHGelTTOoaz9QA5vNRYOaa\nm+2jtJvis2O4Wm+bmzuOdA/1tv5XcOuEnBNQae1hKdDq7FkdopEUfDpIbXF+\nfbQZxSp+Z+idMGkzp2vN1UKjKHm28Q0MiKwPhrHVAmBZ2Q6Ojmhzj3FLfil4\npdCwW+sGMfpujq8efyeQJtTSqLR1YNP0a9YvI+LxB+rWImZs7nJwuGXyFQ8x\n1KtBRdNQDnym88qn+q7P12EY7eGinngDTk4cGbLg91x4OS/X78Adc4Pt6xjC\nc7piBM2EAtD50bLvZVVz851yzXgOUDhQDoANJ0KcN308oWN3Vw8baSMXcxV9\n03CPt4eKMQmXAaub3RbF+WUV3QF1WKva5Dcw1NhSIaH+ufzO+hrhuayjTJB3\nFS5XFAKgOppPm44HY2ZVUDLWo93A/udzJhcYFH4ZWT6MOfZFvJ/5ivT8CfBz\nN9sYCB/RZDLY1l9Jkwk5mFA6Zf13LWxSEiI2fw9rvGQka3AS/Hhwa2TOzB75\nDK9jEL7J26r2UmlAwlFVQlsGr3V8JUrZkodmsSgZ0FLKGHDdlojJcUKmvZhl\ngyIE\r\n=bCE7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDz2vhK7+4DJkGWXsskxTqaHLn96gINZol3KtbO6TAD+QIhAKvqyj0Qhqt0f7HnngGqp0TlYSGAe+BTsUYMVpHuZhZG"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-master.20190131044730_1548910128011_0.2907478921948805"},"_hasShrinkwrap":false},"1.1.0-master.20190205190919":{"name":"@atomist/microgrammar","version":"1.1.0-master.20190205190919","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"da971c73e53252b498e09279780a0248455451fe","_id":"@atomist/microgrammar@1.1.0-master.20190205190919","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-iob6qWc6KVwChdq2h0pjkO6YpP8NEuvVsjAHEqvXOF2v29DUNybsSyH/y0wcQpemJHLA7Eoqj0Mg71chM8hG+w==","shasum":"75ca77a2fac3a19a65cd8d0e6f00ae67d4716f82","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-master.20190205190919.tgz","fileCount":150,"unpackedSize":291280,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcWd+oCRA9TVsSAnZWagAAOmMP/iiAb+qSqDQ5ePhgXOcQ\nsXN7GIyB9FQfb/HDilh3mwjohmwYWUl4+CaXgQuXBZDFPesn/EveW2+9/3sf\nZqE133CFdiQ3EUbJPQFtV8HrBur+ffCy+aN35GoUCkKtrZnHTULH7T3WCYtL\njmIzOoblhRPpi1cyLYHZkIg02olruZbjjvAQ4jBRYO7gIIUPY98vZF/PeX5s\niY0zjG5SoO36+/NkALltJRjzRfT9ifLyg2+JTfPIgAW7igbGRU7RPWcQoy6g\nfRfv2mMRjOPnXx6kjE4C/Mm0mNP/9MlRVKD7gp6fAQwaH9uYZZEzdCW0+iHN\n9+ESQSqyPCBWFRiGsX369NHJWPj2h8pDtnuPoeJ8yQ+Tiyf2v+NKI4UftSGQ\n4Hb/BYyypETLD8ox01WKXsgw15xFawGxSL28BRg07d9SS6wLpZKACbBeR2k8\n7jbsDZyz4hg4tH6ixh1HuoAJ1jVTu18qO3E5188N0nyFOPZP8VAfyB5ckCeN\nfsbZWkNmcQjttSO617tlJN+kkyQkvQw/3VOPzHJ0uaGUleJr8/5St3nqIri9\nCgmlL2WFaySUW6TsxeOVgE2Xvrbx2WSh1dQeL8/f4oBgwngaezTUQwHSPTBi\nQvXf4O5eZtv5CPVONqsBnw0n6gbClTIDaCkV0/KmjviifAbQW/GV9udZ8p8e\np38a\r\n=4qAU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGM0GXfz84+DEiVq5cbuLAXDJECVFVI1CWNo/6CmFxrNAiEAhoXUshfIPtclNuW71C9ymza/IXzXpxHEMuG7RwlFdYQ="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-master.20190205190919_1549393832114_0.9694959197947057"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190206164724":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190206164724","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"2764142a7d336a687eb07b50abad4cd33e1b492f","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190206164724","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-PWVI8qohozmG6k7B1cyoRUAJGUSoe0LmVIiTtmO5lZfPqpcJ6+mYHI4+s0eEsCjYEub15xBlzx/PbE+PqP5KJA==","shasum":"be3d372642a47a76148b060b4835648d09c16a0d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190206164724.tgz","fileCount":162,"unpackedSize":323866,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcWw//CRA9TVsSAnZWagAANvYQAJfWlIgAeTa0moNm7vIP\nf86DTBaY9o66Ppcsrw0Hna9rH0Npp+KzTliIuJPiitYGY0ic5B/wjY3Y/gPO\nxI1ZTVqjjBhsOHUsm8lbdf3Rpc2nNqbKD/W51cP9agKlS8s6URXUHBsIhfhM\nnOm/2m3+CUbe8EIDunqdeAM9rbBD3uLTHmHF3mlt+EweluV7mf03sylnrabm\nNRBwYwWQZCdvZnOrABqV6qMcIE9oDoN35p57OlJKL6YCXHR+qEWgzfrKTW7X\n7D5QjUUlODWNiTHYaeF2ye3DERVLcksN5PPRfXvJtMkaPhT0AjPYgflL9yVn\nmA20/6QsoExOjszhUqY/dbD6l4PnffXlJfnXxJSKHTXFTaUegFPNgtf5nOJI\ngl6mbEqH1TeNu6bxQ6SVVTIB1lWXti2fbHNf+pJBITNsvqHVyziNzPEQb6/5\nb0LXFtgfEmQTKL5/EH5bBZh3mIGaV1Xx6Uks3sk7Jsw1ItDqATwZILh5N/Sv\nkXtRUCKoizOXKLF8Q096OsA5Dcsl+CfBqXaw7AFkengXW6FNmxbHePlNh2H8\nqD5M2Rs2hC/NDKWqqry1LJa32KZAbMhT5BkMtIg2+wVgrB6DhqE5v2i4K/YN\nWkvckLEO1iOg5FzEIIZX/Du8rBQs0lJcbXPI/q4pAGssodf5IzNYVn3BzzvB\nJCao\r\n=wt0w\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHcEAjgX30/YblDzi2kZx8SFpMpWcvLYHo1yxFD04WgKAiEA0GK16sTV2g0oDNNOmAHRoNeAyu6j8+/cOhjeMocqffk="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190206164724_1549471742882_0.6107626928209924"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190207015904":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190207015904","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"fcf7e79c1cb6247f366caba96a2203049ac0a8a7","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190207015904","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-MYq3Dba2+OaeJgRgaq54uyg0WcAbTXihb3jRw4ucef4spr1QMuolEK6bfbkTUknlSwn/zAuEDKuiBknbdRRG5A==","shasum":"70d930888d2a168e6e725b44ce6141e150d5a52b","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190207015904.tgz","fileCount":162,"unpackedSize":327675,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcW5FECRA9TVsSAnZWagAALYIP/0Oiri2Du/VuzOoe6RnC\nXZ+BImYJseq6jjFOXo9g4iR0Cdy/Ujt98eiKHgi4ZWk3V3KH7eWVmWo5H4Po\nh9dvDC5tpKYUBEAZUfW/cNpGE9W9VKpmf+ajtqWRtIND9/cO3BL5dAVcz1+W\nDhIMx5+9NT2ugzlv9mPAFV+b0GKhYOXzKWH3LvNSIp6Vfpr17UQBQ5lXlThx\nuWqgaslvXayX3+DVGl3meQ+OuHAUW2+41/doi+Z/oXk0U4AJLgxNzDsejxH2\n4PUgKMnPZTDLas7IgDPuAwLN1q1IUYGe0h/OjJJVEnFxvr2sU2f7KxHv4bXF\n/R7Ug6EQB7qN7kSNikCTGNkhRdAXEq3NBxkbXcO6TS7QyGvuLWhF5DIyrn3H\n7vjR6Z1xeeKy3G3Vv7xTL2gCmuJkqb0dLs+NyyqpyBQePLaU8AxWAslAM4GG\nyccKHO0r21+9S6/Tnn5nDmJVvNa6O58ZXvhLfKYvtMKqpMhjm6wefDLb6xaU\nHeDLBF2wVyeH6hgF8aX/evZ1VHv98z6k7ICQ9W+diqIc2S1EnNAJ+09dZgFd\n3Rh35dG2e0I0iYMczno1WWBrs6TXh2WhZhZSxsHPSE7UbKr/+UEs0fg5ciJz\nXQHV3jYGiactjuCoSOeW933MyDW3vLpQyxOBzpNKHBaUjk3UDlk1G7bOM8/d\nyTy7\r\n=WIZ+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCmgsn8ig4BiDI7bJLP7bKbzBxjARlVS78KhkF4uZN4QAIhAJr1zEqu7xxLdM3ZUgeCG7STpn/dMZSXzw0NeQYZeFBJ"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190207015904_1549504836273_0.9276743508083825"},"_hasShrinkwrap":false},"1.1.0-master.20190208183142":{"name":"@atomist/microgrammar","version":"1.1.0-master.20190208183142","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"0b0c6529370f1e74c82fe35a096cefe9e4a22417","_id":"@atomist/microgrammar@1.1.0-master.20190208183142","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-3o1pvfk8IHDYxxw76+OPNRVo5j9UXCnyA6MKyHqb6+Dg7Cx4LgKio+HZRb5fTb6y3N4cDeVrt9YmiauXQpIivg==","shasum":"bd640e4a0c0dd7cfb3aca3f9abfcc1ed3da51f15","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-master.20190208183142.tgz","fileCount":150,"unpackedSize":291280,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcXcthCRA9TVsSAnZWagAA8zAP/1iVjujfkttXwI66ddQN\n3P4MHAmGqnZ5GSrz9Wa+bmPYQb2THaxmKpKdvJOh5dUcH37kE5zSyLChTb0E\n/vxYvaa6TC87GodpIQvNlroIHe9WHaGx9i74Qx/IibcO2VxP+ts0vOAe1qi2\nBJBr9njrPz+c2fMKVHvVgDC5s96jT5O0p0ZuQVDvYsoISdwmUu0y1yQwIRM9\nkHQbfhzgGGp/WMoYtW3L1Xf5QRsoPkKE7RnVYTNAs1VvGw/uMyiAf1V1j2FU\nvLnYls5t8EF/DjgbMgBtHg1UV1tRnxJwIfbL51RxmRA7Si+Kr+pcRY1n61W5\nlw5cUBi77HS+GG+ppiGtUEXIkhi0tfOS4KuSXYdC5NxS9L7qZrdcqarxhRVW\nLNz+IWzpdRQ62OS/n6H0hgkRYH/YxFkLW4wyyZ8ABnQ7IlLZKBA+XoycD6Gp\n7NShh8P/5ktt2RQnfSFpnmUiN0HOe/Q3tg4sG2haHqWu0e2GGZHPqSBDWN4F\nMyuvCZy6sR+DNiBU0wGH37xG1ykMwq/0XOMBFT50WTbLDLDtY20lLrtKEPqj\npeSQXc2V0Ti2fv+h2jMDX7wvhX2SSH7Ru1a+p5UmthJsWVO2YYWOmb+q2Y08\nrvBqM0sG0bdsbS1iord0ZiR1C80c1pecY5xje2Mcfq2MoYjHqGfUmU9s7+YE\nlG8z\r\n=2Dhk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDsDDkSMN7nYuieSMj7Meo4qrm9YTs/XmS5Pw/QIKP2LgIgcsR8wz/rzKTu0wco0Zx4QlNqt+Wy/xoB1SrZ+hwihNk="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-master.20190208183142_1549650785136_0.4323002587163556"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190210181438":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190210181438","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"56807988bc1c93f7bcf965e43ac85c6977da91ad","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190210181438","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-a1vX6907utQrsGxBISnI/pmIf3lgbQu/fMLhim6USccNEd9dBC/dZUYHWF7lLAhfU1puyUKIexFN0hYrCxa9sQ==","shasum":"5cc3a65a86e7a1dee0b53943dd0cb195d3b278f5","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190210181438.tgz","fileCount":168,"unpackedSize":370541,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYGpeCRA9TVsSAnZWagAAqcUQAJU7EHF6YUQwNvBKWFKH\nSW8i1L+xoLbRcEHPCpViGwStlVMj6+cSEuXt4d6A5fS5Q5ckK09hYmux7xlT\noRVHgNys1XwXAryo0GOZI/sOZ6Medx8WGLeGggSPCg8mUT6a/yWO43EWq8cf\nDT6jE4vT/PbnGbl0J17AI1IsziwkfWPp8RelWy9tVRl+QU3ERxTgDvC7Lu7r\naK+Uf8gVpyOPzJN845A6cEfmg2GFQEl+imog0WMnfawV9YA2DdBCgjESQeqF\nYsb+JAZreCVfaHbeAVi+MQfpbqxrG2/T81IXHNyOXbspyUvXhytOYj2Je6Cf\nA5aYqOe2LMkhySu3ECMS1xL9g7sglwY6O1ENNYS4B0MWKWJ1ff/fuY1i6o0V\nQB8OaFwUZ856aYH8UoJyyIHV79UYJVr6gxEfZKJSb7qam53np62H4MjHioiM\nQH3+cSG0EfOYMircCeWt3QAlZMmJaXKtj2bCq5mrQ36vqKHpGOryDAZpf/7h\niHMFOQNiDYb3GHVS2+xw5f/hFHj6yH5OHnwKDaj3YNKZi0FGS8bdh6DdNiqj\nCZ/yYcUJr1qvqXWEqWmMaZiNMtMXnZlARL19OxBKZXWdJJkfHLh5Yy/0D3kD\nyKhC3dge2U1Lg92V6TXxio5t/Ph9N1V7wfpMtQMXN/q/MeZOQGfoULLqjVVA\nXryE\r\n=8AGk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDE0xA1/tX4N4+VdLECCGth15Uuy6UPr7vzpo9K2pDimgIhAIfriiD4QvOZsdMa86Vysyc9xAZt5y884P7ewZgbhnRE"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190210181438_1549822557414_0.962430690127617"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190210182036":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190210182036","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"3689129607771a2445134fdae96c4320785f5147","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190210182036","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-T9UIQm7KUjrHjvfBIMgR4vOgUQjJ15x0dfyeRxZqxSJYdOIn7d2WfyhQnKmqY54YvvJioq+05EEyiJsdOpApsQ==","shasum":"7a7a6535ce3a53971cac5976664008aab54b67ce","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190210182036.tgz","fileCount":168,"unpackedSize":370541,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYGvGCRA9TVsSAnZWagAAnNEP/0Xlg0hjK22fxLcYu1uE\nUR9A0yWAQQopxf5FUNm0/FYyP23vFF4jvevSym9F9tXZ1puEfemFAq8RiXdD\nxH0fByRGn39e+WheOS5GbcdQzcaVUIQz3I0v8mmFz4iMmzCa+MIBNqeRtGxd\nZtd9NIg8+BUa4B9qwLsUOBigmSkMAtpKeidkDAA0LnfFXiFg5f6KC0+eqZJM\nRudVBsIRfFN0jAnDGf+eOkW0JgarvkatR2Vqxl0MQZbD9lint3zByc0mqZbw\nW9OuS2JgQhl5I3Wlo21eac0bmRB0Slc+gD6/So2qjhqXeXX3GFsaFsLXBipB\ndNNH2no+PMaCXwn1Av+3rJ+IsAr1kJlTREdCzHl0Fdl3mOP9jwpJRHXdGJux\nZJY/3sc3TgNK0i3MHgRjKC221rxX/iCp4t1jAdo8l4wDgy3MNcWjjzHZUnS8\noSUepvNBWLzv22/6bYHzEX1MAMiwdGExToCAc0YhnMirPefBSbChEpa886P/\nm7mcQsJ4GpnpUl8Yu7QDZps2uN2y8LRYdPWaOPVOPcZ4c9v5IxmSnZlbGL7t\nyMLUCLfOZ1DKqLh7p9ikEeSUiBTY+5A2j1OQWxszzJLAz5y6X8kOVVr/Eunx\nvy2FG20CXw+r5y0Ltd99feDfQisFxON/2rXwk9KDAj11DSR7lR6U0mv/iXqx\nljG8\r\n=eNJL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEjQH3slW9ALgV09vWBXCg+2igSoR8cpRDQ/S8Ko9pbNAiARNha9xCli4a4Wali0ZDy502giZhjOkpkMkGqOMqQbyA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190210182036_1549822918134_0.26021209661504763"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190210211149":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190210211149","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"3388260b412c5e221cb6fa0adb969a85db2b868e","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190210211149","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-kTEMWu/Fn08ND7KvtzQOHd8RxE88SVVtucojoapmHbx/5o3qSmsU+ntdJNu6inWeB8aC14BUu5N1cvqlSljiEQ==","shasum":"32a6a04a8fe1b30f4964cc1ea25816a04cf85239","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190210211149.tgz","fileCount":168,"unpackedSize":374315,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYJPkCRA9TVsSAnZWagAA/VoP/i2DLq/Kp5Dfd/m3Is+X\neTq1lIQBccN6Rm84B8jjtJw0WAyGl7z+Q9tEyAkuQRzcpvh0cOxSnsjbZuVs\nF63wMlzJLQgB3sgp+eVFNdAH+ek1TSVd/n3j7CdqiUxDFlv3tiLNSW35VNzi\nt7KTuaxs1B9fBVok+JrApsClKMYLdQ3WAz2Ic7ZqfJj7nqp/nP3OhEBS+XHu\nAJXpDPNuAMwMcfw5f4bSQCHIfMXv4YhEZn3t7enzm7vjMOk2FjXWK2KfV8+H\nUTPRLGNPk3idQILwXHqyFVM1gLQtzIEExlKt+/RTGUAkTeUnsAF1NnKQL7hd\nHnBEB9F0QB4+X984PaN+SuFej7SlOERD8BENHvtwQPWhwlo6hFzq6OcedB9A\nJXw4/C2VZ2EaQqaEiYBWr3icFSdVCntwnWIkfpdd2hmcEb2UkFQX11H/npH3\nwsBLf4rGBNsjxCsl+tG8C7pXrNFu6U0p89W6gIEcOpfhBkVW32BALOY3EKOM\nTgIoZhRxfoe7dI26WFsZeKdfcwH4usm5dF9RLlDPjNNOWiTteejz2cp5Nz6u\nnU4aAWHSTL99weaIAD/1Ri8tHlZqM6OUzeCOEdOgrixtwnAv3neytg8nl6/J\nyZa+mBY2tdrg/83RHZHIaZfTAns6vxUq4OVMwG/WEZIiCRZBiaMToIIzcCxc\nOLqu\r\n=yAmv\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCORRGRUcz3oU8U6KAy56HA0SAc+5swvD71xtOXbi8sEQIgDnH4CFH9W/CIH7lpC1380q4vxm4FNKNQnWIw43Og4LA="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190210211149_1549833187859_0.10243698371394294"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190211023805":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190211023805","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"d3fca6bbf287b9efb66227d6144f027f6e7459b7","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190211023805","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-7+ETy7PkTbEFq1Ayk4iKOLifjQ3y3lSkX3shPqXA+Ow9jRwO4/LYW/rtcMIAvjmTqRylTa6MEvprxHFTKk0wfg==","shasum":"442acfe0c6969121b3bc333cc34946c34ecc51dd","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190211023805.tgz","fileCount":168,"unpackedSize":361852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYOB9CRA9TVsSAnZWagAAEz4P/RH5HSRvGP5zdXhnZhfz\nv5tMwAAgu5Bw6IWxMZbUxqN5gKkHdo2BBna4+MzGnTiLnlSnn/20/FWtBXLr\nH8SZQ5Elk/HD8doRtadeEH2+Qdhr1pacMQlc81TqVp08VPeusAnXQgIWAFNU\nVIADjMVKzd0cxjJC/I2ziLAT145YP6CfT9VucXKqfk5Cdxk150nwPJUSfJ6B\nEUbtL8Xpbv/SoOzQ5z3G117pThL/lNQdDNQLoMKLrgHvF3vjyA8fnurORR3n\n+9/sant1rvVlqJeHfXI9TfVXP2oFu3BZC8hVuULdQZ3UF2iW47YfSjVmHjMQ\nqHZymjQeA6aHQQsXmMg2cNUxP25JN5HWqrJSbBUlQowz58CFOTXHIMdwuGC1\n2jeKLIxnl1+kKuD4Qxdl2o/2BCq/zCTgEzpgGUzx+Bns+zP2A/lyY/0a4tuZ\nJOivkX4xGWsfG9UAcqYwVg+MOzRtxJ4S163XMtrBwTiDMxIM90+4zsGDSY7A\n7IVWvpd48u9nJzuwsSiRvAbp8vlN478v0tR7PRU/VUn1OH+sHf8/cacnUZ9f\np8IhC3T/52hLTMKXxtUSVTN0heICiFib9lEEx36Q3sIco0sUDUhXDQXZcmIB\nDaHHKr4m1w4eFWjVByq4O2AHnGbZ+I+YPEfvWKE0p5LQ68f65Anpv7nFpY23\nDFvj\r\n=/7zy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBDNSavoaEH+D4rbod8jC2ufeU0TAXxly1Smq2G2vXWvAiEAlABmo6/lZAj6zHiphnIN6I0PlkOjJSTUtK4IoTsbU9M="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190211023805_1549852797162_0.35191267875888776"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190211023903":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190211023903","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"d3fca6bbf287b9efb66227d6144f027f6e7459b7","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190211023903","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-Mn7ocJpgPIFpQNn03S/oaQd9mGhzztsrCEoIBtsrlJnsJ0mnNGQNWFi1S/wAjG+R+H8EJjJXnWF+46wR/r1t6A==","shasum":"8ebbd0e30e7381a3c8ca823c3d56cf04ed8ec91c","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190211023903.tgz","fileCount":168,"unpackedSize":361852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYOCqCRA9TVsSAnZWagAAEIgQAI1NaMz0YgMr3dCNZrYq\n89RHEdhsuf2e/aXLxi14r8eeej2+I+aaQpYCopwXQg0vc8hqxDpTBb48fnNX\nEklCkYQ80kFIefVLtHhyeXbPbuugIUbduG6qGFSgAxKOWtFAhbDOZD32Dt/j\nXqpCxBtc96Fm9dWK/c1pM08Emw6eDsIcdh8y3pGK/KytQM2HakqntPV/4iDv\ngLV3EnQzH3JSGw9W3/Ryws0Ro2L5hVRZaMojougLXWHcE8SByRamC5ncSYgE\nOjsl3mhF55HDF1R7k2mtq51XqclTL2g6tG+MChTQop2wYTtsDbgl3P1E/DQp\nylYradLSSP94fAlyiK2s4zPRJXRAKHR9xl0yt+5rk8NSGW4Zx4R6h8sWny5w\ncqhxtICqcLnPu8kxyGmSrv/vVyHgnNEMOqxGRp8a2aqFfnzVhv45dR60/Gc6\nwtmtBztDc66+ZSWcjPHB1+zqiUkNUtJgdqTXjwl4gfCVZ2t/VPW4bN8SRGup\nRTtcPDJtov6dVarOXSV3Z5xOBbnMpY+GjwQyHk5vlZFBnwaS7MNl3cEI+GMX\nHnK5KYfNsDl7Pt7fElP29F7R1PHzwVHpyBaYk2vrewwQYdKxhpAMD5dpyYkt\nFEw3NxzimyNx8/XXcvW5vxwBiNkr49QZPucLI7N0Bp2fQmGku6YkBDEVyHUk\nhc+K\r\n=h0YB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH0safjUZswJ0oPbc3+q8VBMLWq2WNy+rVO6MD1qXlJvAiB4N8Ds6s36BOJ44ozlYLgFDN+LFwK8up7MtDo3EuHMNA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190211023903_1549852841756_0.7566765283590331"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190211030756":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190211030756","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash":"^4.17.11"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"c6c841440fb26d84ecb731451d3c4045d4d0a8b2","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190211030756","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-4QY14ajd9F1eLXDyFCac3fUfCJT47DEmraxD+yydAwLdnQN/SH9qxU3RWyugGFs5UDkHX31+TjeJSeo/lh+ZcQ==","shasum":"8c1edfc73aaf6f790957bb5afb18d26956f43cd9","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190211030756.tgz","fileCount":168,"unpackedSize":356180,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYOdbCRA9TVsSAnZWagAANlYQAIGYkXb0owOl6pszKUb9\nW0l7mMwRgeyy+zY7wEe/FZMWUYPKZQHKMsRd86wmU1cMpe8tpWW+/s7JA2L6\nPUAubHE5Jmacix2Pf1/uemFGTxvMrA7hLHmRlSSdvMjY6Ut6Bq6eFn74c4ZQ\nKqq6NZG1XA/coooixpiJAD2SHKGLNbkw+F6khVncKach2u9abfDRAOfOIFuv\n/t81dBvNaULTeIuBhY8L7ZXICf3QuB+5mGymlzbshI59ro6opTMbYnsk52ku\nN5xhnLftQQY1dIKvLEVBM/eOj9VyAC4uQBG3e+R5vniR49bt58lA20ApEEuY\nRNorHT8yFJchPdGYqkwfKmSeH2JG1+EBS2syTb2/MEkaMD5sPqZgX1Q9eWl2\navKaDxVVPlN0eNIvsenkXyB5qiyMfPgGkdsw2RinrnUc/2FKQu5p4UeC3hg7\nHNeRymDNuu2SpM8ZFNMzdPUslcctW+a+l9Fd/Nr7ndW/eDY2CMbeCUS7zwnv\n9RWJrtPhhkcTNLNeO9DMAmdKSBNjTv672ZW5rKEEva7bL3UX3a/l/LCCsxR6\nyyfVLf9ute+7h2j6YPOhqOMzWgS1yjazvQbu2T9ANOueDIYuiw1hcZ2+y0ee\ntA7o4vQkR8kH5kh8sFr5U21zuTMNKpK4lH4Y/3vAFatKlbP6/qRkWmZ928lw\n4kGX\r\n=zerS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFzbEc3oFiJ/vtDuLJOZEGw0ZHwSUY/N9XOrSceWYYvsAiAoiK0cwm6X1zMmMDEGo4Vc7yB5/CObnOYPofvESJpIzw=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190211030756_1549854554837_0.9141765782413778"},"_hasShrinkwrap":false},"1.0.5-MatchReport2.20190211031146":{"name":"@atomist/microgrammar","version":"1.0.5-MatchReport2.20190211031146","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash":"^4.17.11"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"2ccae47cfc4e7802c63285d79da33c7d5f0a4f3b","_id":"@atomist/microgrammar@1.0.5-MatchReport2.20190211031146","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-bKZG/B6v8YAb7eokH/SFhZy4zj2DgePygwte+PgvKZEBxzVcbL8ue+8DLKlPvo5riMSWLKOtBRanm6GFAxpiOg==","shasum":"7a089f904455457ca16d5b2ba6848efffebcbaaa","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.0.5-MatchReport2.20190211031146.tgz","fileCount":168,"unpackedSize":356176,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYOhMCRA9TVsSAnZWagAAKUoP/j9iVl1AKDr6RspP6OxY\nq4xv6bt0Bcgac6mWnYjBqB+gZDdGBf6HihnZU2P8fp/r0hsRLPdqwMhwqRZn\nwJY4CbyQ8wJBNQJmGBHXnrESlKXsF1yhwLpRUh+9rXEjkWXkjZHzLAjSMnf4\nvwUjP4ghZXHw2hZVxO0u4HtuTA0y/WzAKmK3ULn6FZgRNr0fVXcvIISKVp1t\nlLwz6U0LsIEWg9/yZGZZWTyDzFcDoJ7GP7KLQlbqD/b1fY9uZ0ohB92SK7OL\n/w7gYbf8ar9aNRSctvfHEGszLMhyYgO0PEDIw0YGqZdn1+d+x2fG07P9GETb\n//s9CjnM6PNJ2RH25UnpwxoNTf+Xpj/3rboHXzk+oRkVCZ9GDJlmcs1UWshw\nC1MRLhzWbh3gbFSPt8X3ekjS133AAhOZSY/ZiHf6lUNHKlkcY6nTkF1affuC\niOFrl9GystMB7J+Q6+ddOSrBQogKOJE9+jKkeDt17L1TauZM7wgpwlWYQ6nL\nGnJ3N/qkNKSV5Z94XhW81W0cR6z8uanBL0lnPyzXoWGoiEIUmiHSwjoOPecS\nEV9qqQWQyTUN/1UE1GOeSz/GZdvMvA9L+XVkzgubmsRFp+j0HuVo5lDi9Yb/\nj0L4qlOzpg8cqjDtt0GhzS9rzQ8pWCNVHT9TrYeKf2O9NsMprFiGzg4y17od\nsw+r\r\n=5ADH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCWp9xIUhWmki+lUZI+g0VpsbUfLhaaVgu+i95vRrUINgIhAIP5RfTSA5CRi834/lLpGukhYNGowKv81iYdWPNcuMN/"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.0.5-MatchReport2.20190211031146_1549854796259_0.10919184838987728"},"_hasShrinkwrap":false},"1.1.0-MatchReport2.20190211040721":{"name":"@atomist/microgrammar","version":"1.1.0-MatchReport2.20190211040721","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash":"^4.17.11"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"a85c6ad5a32554b4e3c5b848e8b238d1cb86fb17","_id":"@atomist/microgrammar@1.1.0-MatchReport2.20190211040721","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-0J4rTrnHl6IKKpMzACkIOV4zqQzbPWvG8trp3RNzvinFuFi9iykJWaEMNw10DiyYGs7vldCX49os60KoIKsY/w==","shasum":"100d2cfa23125e1e9ac4eca77b32232115b29f39","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-MatchReport2.20190211040721.tgz","fileCount":171,"unpackedSize":360037,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYPVOCRA9TVsSAnZWagAAT9wP/1747d56LPVHViPpfDwc\nu9PAlf9zPUd/b97ihk562RVbypdOP32dMDHDGyypGa+Go+sndAJQROCoxFbp\n/nHH1e+Ei6x8xlLRc+nwpmXlHOZWwHny1OFZHjKbvaX+RmG7RPlIMO1h5ZHc\nEX33jjC9uPkZXUhJXWnLK9tdmbNX9jQAQ48Me4ulKqaB8kQGPn4z7KdBrP4q\nFLg6QRjmWOKPLVDz089LaXRF8CS0byKOxsdxzKB9ZAYcNr/MKfdiltvUd8DL\nZ0t1+OTA4D5fk3mz3id4lvYkzfZAN+aFGZGDNSRmPsFcq4fgMw50QQlXdU7Z\nQOKTv7EIwjap/P9j4UrIpMSQ96OJ4KMwxKG9II/rV3If4j1Zgj/fNKovgmuP\nXZDJrNK2marC0ICHXtUxdjT6tGb3ezK4SPzTcFj+NaUFej7mAjpVAddOE0SI\nUSpxpLTuwMKwxaMvianzdn91FcFCsHMIdsfwXmInGb86y8axHWyYv9i9aNgQ\nBCsBY2ziBbPI8U0W4GY2XHocAMfJZGHECAlEb/09B6mLrj+1kJX3QoEtTjSq\nMEvV3dy7WJk5kmb/pOEZadqTBprmcFFolTT5GfJpr8S98fAhl9aAnPTn31Pu\nSBZEc2SR+QAhkVBB5fAs35/zj+xGjYfYCQ4aP/6iPQ/8kl/nuaco/b1heEfm\n7R69\r\n=IDSS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDXEU8zpGAUTZcCwXhRHdblrxww6TaYiQp8au8svgQW2gIhAI2/8p3ResNdKmfqJdbo54sl/D9MjNjI6OwbHqdrNNrq"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-MatchReport2.20190211040721_1549858126317_0.9878505057639111"},"_hasShrinkwrap":false},"1.1.0-MatchReport2.20190211042928":{"name":"@atomist/microgrammar","version":"1.1.0-MatchReport2.20190211042928","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash":"^4.17.11"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"93ea9e4ac13064acb6ce683f7b505bd939700f96","_id":"@atomist/microgrammar@1.1.0-MatchReport2.20190211042928","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-BOPuOC5cGrAqndKpP1rSf7zsKPsOuOIhuChO7zERhOKga0za+2SxBkl7Cwef2122IE4H+6lf6R/W+JUqHJdtJg==","shasum":"49aed4c648687ba0e95693c0b1dac95a5fa6362f","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-MatchReport2.20190211042928.tgz","fileCount":171,"unpackedSize":360037,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcYPp6CRA9TVsSAnZWagAAfzcQAJDKlh033ph+EUEVEtXV\nMt+rLCahuF12YAhCAOL9+eTDRqNuEl0JDcpHFf+cxoKOkNwmWa2ttDGk9Clb\n/4frHCL/Yrpry252KO/frYDzUvBQnn5mI1APQDI+3qQSq5VutaAC0WEwENPU\n+Q4Wgm+1bn+ySXi/E9ms5o/LqQq7WQZD6HE0lgXusmktPvHF7JYOs0njyBkF\nYRFimjG9X84lZL5nKvpzZJGUUmuFUCr8Da+aX0NEpQX9d8Xhbiulr6jVUP3c\nA34a9YEh/sCZeBJG4gyMtmPLnj4TyYjyB4IA5U5O99d6bE/N27xBOCwAO9xX\nAXuyWqyXuKLEnUYq6g6CV9FwCmD5eazMoQ5DouHi14efmXSO7wu0FhdJKOkW\nPf3I9IPBJp8j5Is1keNwAER5lzue5bMMoXmcAWvw+jJjXf4qzaryJcecStrG\nLNkaolo1dNnjXa+Z6/T7onDvQueXsBL+aw108AdUeCK5szHUpQiIPElW6/9L\n2FOXbXciLvAG+BtJrXJi8TIB1EjnxMrRZtZlI92GZvzISaw5bfAI1MUxyAYY\n9MVZXxH6Buu6EbiM8uiVkolF6ZvDAftxXeyhtaiVqKBEPnizbsI3CxdFTQQI\n3TWelEvJKiDQ6pRgpwHattF5qYGb0HQksTWW6tpmZhhlyc3XtDgvbAGprQRw\nzZo2\r\n=a0rd\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDH1dRTBreEC6VY4n+TmZ5K/6rFc7DYUSPnms/Q9OiQqgIhAKPaxa4q06jD4LZSeQu7cE8RVz7XTkQd+4JSrNgMbG3u"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-MatchReport2.20190211042928_1549859449477_0.632960935719747"},"_hasShrinkwrap":false},"1.1.0-MatchReport2.20190220033729":{"name":"@atomist/microgrammar","version":"1.1.0-MatchReport2.20190220033729","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash":"^4.17.11"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"0f96b1e9437d0bd79b3d28f66412aec8b949ae18","_id":"@atomist/microgrammar@1.1.0-MatchReport2.20190220033729","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-+hZsFJijOfuAeGPPAwP0cH9358H+k+7ueIIXmJdje+eGmaGi8FzB9x0f8ORUYFSH6nwgayC7ins48NgtwjUZjg==","shasum":"19ecb6fe1abded40780e31eced53a3129c7c839d","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-MatchReport2.20190220033729.tgz","fileCount":171,"unpackedSize":359657,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcbMvMCRA9TVsSAnZWagAAzMkP/iyhUWvh7BmDYsK00R00\nfe0cTKFGCLh3gXfTq1FJOkl5r81mDEZgzrU36bF+vMU9ZmYSP1e3U65epaPH\n3xUFigDUG3+EAIPkyhWayWpS2BGoTi6NEb0cpQn+mzER30ODwL/6QXi1e+fw\nl8j8S5eJltiSD8dU264BqgVqZ5buptbnMKwr5PFH37zKewfGkXoNdx/SjfHq\njoWEo7lBfvkX233PFS5df5vJuN+MsCSBCY+oChE67kPtxWX3Y7gCz59naDLI\n8QULF/6Nv0RW5Hr/jvZyWKNFvf+hl5dqk4mJGhDz+z0XtE6WtbAbSzu9x1WR\nL46ClrnNExQUXtG6V41smyJuPArtY/ZQHKVYbvccYX8ZdqQN+4MAXa8lVyy5\nxrCtUpbAvEJ6TqfKIsNWUFFlzsaNedpZ/SCk6/y8syRfUqm4P+2C4uLKP03u\nXqIzG5jS+NktoCoBfDnzMEu1/BZ5YKU5WN6Ye6BUEikiyijC7PXseIU3z7Gw\nGJyAhmUjsG1jTYQKdE52HkT3xilXfyKFfMRdEusoZPKn7O7CNKMG8i2XTGO+\nuEcWz5WK50MLXevBvzdFE+DhQdeMrl+7IQTfJrfotog4oKjPdT4eTcX4XEIQ\nn+Bw86T7i3CpoHFAfu0n+SjE5LXSr4lNx9yyfkatGlCoYC3tSlIi13nKIyhU\nGPB6\r\n=0MVw\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCZ/LP5NrT01i8ar7c/DGMIxFP+snDNZQQleLVJSbPnjgIhALGqlQ+QLgWG99xxaREUj0bf5I/8qTc5hHJzN9qCJifv"}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-MatchReport2.20190220033729_1550633932158_0.8333264505439355"},"_hasShrinkwrap":false},"1.1.0-MatchReport2.20190220040924":{"name":"@atomist/microgrammar","version":"1.1.0-MatchReport2.20190220040924","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash":"^4.17.11"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"239f835783ee0d6295734fe9bbb9a7d437739db7","_id":"@atomist/microgrammar@1.1.0-MatchReport2.20190220040924","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-MdGnAm5aUlI5G2n0Cz4rI81sg4pQjZ4DhIhjVvH6QbXBsiA12PuDq7QV+UWQdxjWbQb1AaF475Jz8h1fYlk37g==","shasum":"6cfc16ceadbc1d005feafbd1e090ada41d2b78c7","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-MatchReport2.20190220040924.tgz","fileCount":171,"unpackedSize":359679,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcbNNPCRA9TVsSAnZWagAA/OEQAIJN2DQxRzJ18HfJ1h3i\n+dWesVQf4FSDVYk850+cBwKKtI3dXvXj8vLns8sedovI/Pn3IbITtJr9a/3I\n4nWPeu8S5UOlv8snwOcWAPgneFFro0WMEN+4rbsFJxESePeoedwj8ELxVoSQ\n6HZJmoSiYFI6Z7GKj4WD+cgToo3N145JFkk7TZULAvOFFBpzNI233wfu95pk\nXCYbh54x4vP9bxiQTBx0YYkk9I4feF7LUe0Ndhm0Z7aQzQcjO7P8O8wzEngu\nRLeUBVMCzSCdFnG6t5+zL1+ZxzVHi4gPUVbum0Qd+UhC0A0RKd8w9xDA0tuF\n7kMhRg93RJJgVjFxYQe4iMZUsTY3R9cY5XcFBAgGM0zwD/dE5X5GoVpqaZVw\nW5iH7aKpScrvEgOB984AoJvViYEeRmw8qa/PznJIv44vV8ya2s5M6d2Tg8X7\nY/ARjwuZfSYDX0ddIux1hz/SW3Ixlq0FGbDfs8Pv9aClndSTJ19SYn/okfJ8\n0YyweJ9H5NEsbpiZV7HhT5RgNdS4Iw6AVZ1n8s4vx0FTLGAVFI1IWNd77U4S\nK6AhRjJv7WMNFhxliphQV4Jk9S1xxsCy18R0uc+Hb/1u25QWIpCLbbDaQCUg\nePDzucgbJiSMGec9mP6CtLiWjgT6LbZ5Du8EpUyrE9Rhre1lZMRn+bXXUc4A\nLK+j\r\n=KxjK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBcHfpAjzCCeDEAlwBlEqdAhLWr8+xTDV2b3HVmHPvAkAiEAyNM5GUzPYeNzVAb5c/2cribN8sB9ZOumEZhLMPSkwmM="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-MatchReport2.20190220040924_1550635855278_0.23863579266645885"},"_hasShrinkwrap":false},"1.1.0-master.20190220043504":{"name":"@atomist/microgrammar","version":"1.1.0-master.20190220043504","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash":"^4.17.11"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2","stringify-tree":"^1.0.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"de386a33f87bc7f2e00a10ac50e5caa2053de89e","_id":"@atomist/microgrammar@1.1.0-master.20190220043504","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-ol/zEifhgi7pu61hEvk9aSrAKkOUC9v97r1Q+rxjoP7xSAwFj2noGN0xSi9th3cQiYoq0G/JHZykRpbQVHAIuQ==","shasum":"adb8f15aa94cc742ff1c44a5b2b656fc0fc79b91","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-master.20190220043504.tgz","fileCount":171,"unpackedSize":360401,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcbNlbCRA9TVsSAnZWagAADgIP/2ADQqII7jL6Ct6dDLa5\nCX4OzQLGj9FoVMHU4bgT8K7do8j8HvYV2GwqrHvWcmSCwMQmY92lm3wA4rl5\nlVBJxTrkgrZZPlm45oG8pbc3/lSMHb66u1+bJNmzNh5Kw+68d8/r6WSovmde\njXESILnoaViLykcnV6mjOenzzN72sPSXrAiXmHDSfnB8x5M/97ooAYhgj0fu\nfYse3THKe+FoIQryBIty1MmVPo+tF6/jZpGmHPvIuFziaMsIajBo81G/I+QG\nniofk6pOzbTxicIr8eAB7NPIwt0NTSHd9QfAnB1pMws1LsRkgAmaBG/rmzV1\nhZQUlWwirXScJ3V1pwExTDNOPH+cxU+EjjkDTqCqihs8LNQ2LQonpAnPZrd4\nlN+X68JePRlRzxKk5o6ilFV7rdNRwwidNPu9AhZPeVLb1RAitMosVfahtxjJ\ne68b/FwF5vrgw3EXww7UpHNaeJ90AYdfl2FR/h3LpbLfCOzwV2a4qFz6MteX\nQp6ozkJqs6PMrt4EPu2892GYmfdvNpSHVE2Hg1OM5bGDrImy//bQj2abwJHS\n3318zgF36Zl2eQOK4Y3L8M8PWUYzFGzZeruIfj597HDp69sn145FEYE6Jzg3\nXJXQ9Z5cv9dQn5IMr589gC809Tmb6JL8FRtlVJ7KY4POGiJXXEQR3D5RfSbc\n3yzI\r\n=ZiLQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGhyNUXmvapz6K9NP1hRrJFgDN5y7Pj6W8vfOn9tv6eBAiAXYo6sv0cujIWHJiuKh1awoAOJzzilj3eY7bC46fhCvA=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-master.20190220043504_1550637402656_0.9680473527555107"},"_hasShrinkwrap":false},"1.1.0-master.20190220161254":{"name":"@atomist/microgrammar","version":"1.1.0-master.20190220161254","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"3478d423adcc1a5efafd2a94ffbea6b5c53db75c","_id":"@atomist/microgrammar@1.1.0-master.20190220161254","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-DAPYQouyi08bZgMTPTyFa42ufwWulDuwB33xAMFP9w4XLtDI9+Y21Lh841aoFvH2JHbUBUI82M3ULRLquEfLPA==","shasum":"42949b0f47e17c47e23f121da1786a5565509993","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.1.0-master.20190220161254.tgz","fileCount":171,"unpackedSize":360513,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcbXzlCRA9TVsSAnZWagAABGcP/1DoJmhmAswqHhBSFRlD\nc6Cq88dvCjclVzsUUPmgLBuTNVpPlKhdAuqZygALv0Thh8ZqeG9zlTdBwWQS\ngnq5alSWhNT00wO+Gi8TO3F/Ib5g7rhxNuXAvstvQGGYgv6L7jn2umb6pdrt\ne/hmGz/o1ui02Su6OYlXZ6SgwxJ1gZmJr9bpwzpdpr4/yoAx/IeNvpcvb4Jz\n88aiOZk9tczjLCL75fyp+SEijQ+BNuaM3vSXQWNOWwZFk6/pwGJ37uKd9vyr\n637RSei27Smk4XgC29RV4pgvX+ySGqB8oqzXwcqBtgrVfr9mEU5hK45j+aou\nM+PuTSZq4egwE7xLTvnc0auncnr0YD+7YwlocmoD2X0h5Z64zxZH4gFjSpA6\nSdELOUC9gjYlTyhkceG5Oj6KSAHhlxqmFdKaOwpogBjPOImRW1ft7zWXp/JQ\nkNkv8Rswv7bNkZgNf2gL7WG2wMHoKHC1pCm5XUR2GjhSA5FVTlWipRBHQ26j\nfBH+bvSAsynMzwHzZpubVIncXQXvyK7ubLx9udI35Omt/UUL6a6Js6d8Eg1M\nU1kEwMR8S0NXND08xkthFUpChM07KSE0/BvjfX/h49gEnb7TNjCYfTDltRdI\nU4HD0HlExzIclh4fRaMKKz16AMbhBDPDdZ8Zc/n6CMJ/rWf6j4BV3VmhH166\neYa9\r\n=U1En\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBSz2tqzfeEff0sVppWYhrcnAnsShyXmt8RqKRdEkhGdAiBllm4F91pGbOpCuu3i+oF5EEKY6TmOZykkEtHRwK6G4Q=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.1.0-master.20190220161254_1550679269200_0.03416529485657338"},"_hasShrinkwrap":false},"1.2.0-master.20190221030950":{"name":"@atomist/microgrammar","version":"1.2.0-master.20190221030950","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"1dbbe37929ec515b042cf06b75d9d67e0e51ca1a","_id":"@atomist/microgrammar@1.2.0-master.20190221030950","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-1eVofP+85KxozbWDNnIHrwh8yLzufv7YeLQoI2ugx6cjbkAzDIldqcdE+mr7NyBY7RI9ERnJclX8I4eNlIdxZA==","shasum":"9cc6829193f4c1bf632767761dbf90f4dca1b2db","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.0-master.20190221030950.tgz","fileCount":171,"unpackedSize":360513,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcbhbcCRA9TVsSAnZWagAAQ54QAI6GyA4NPJHjWb+RDNn1\nx1OWRv8WRyrQ38oF/qoDGdRjDXJv1LwXVCY2QTkr/zQCsow9AK5V+6WgmR3+\nChy/DJt8osY2XGzkMxjvCRl1rXAV/Xf1VMfFJ3j3rMHWJxiwVK07K5xxH7OT\ngXGewlEZliB7ze7tlAQ41WA7aHejgFaaqkk9OQtRnA92XjIAnb2J7Lgx4mDM\nV1MDuSCKEQNSF06OraIijpFZLnpuYBRIjoTxomiT9HVSXKr1Z0LQhZsFrAVG\nIzUU6afJN5T9s5EEE3/TCJARu92WOdEZNMR5+ygWe726jmwVN295EUet8Q44\nlfMJaperTBK7NzVwiNJ5IpUDzZcC2+OIBXyfaUBansUA67mjkHcv+YUDPLhb\ncNjTWMNrjJudRafX3abtS0vXXtkMNv/OwdVa1XAdhZQB6Lf576mbaJWWOO5A\nZ14mRm3UQYXcxPv8Jj0TiT2MSs/FlY7e3IWOh4inuqtqUQpcjbY+fhIh6gH+\nepJKyD62Nq5v+/78mv+cG5F7TLg/TH0V18M6wxB25a4uXLHhJ+Rg+CM6j9FL\nEbLnid00lm/tUVucU26bN++XM3/eOjQj0JpC1dJvTFYQIJinuf+PwIrg5Y0m\nXFiSZLuANqtyx03AEoewHxX7KJpKhmeU9XhLR9i/ff9xxjCTEnLb62nNj5XR\n61yR\r\n=QNYB\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF4gRoF2uyfDCqXe7CZWrFPNSdxpMICNjYkY02epI+rQAiEA3/6LDLtwxBndk9ndA4u7COiRudWCIW+OzMlz9dnZ39s="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.0-master.20190221030950_1550718683643_0.38480094087084615"},"_hasShrinkwrap":false},"1.2.0-updateStructure.20190221054155":{"name":"@atomist/microgrammar","version":"1.2.0-updateStructure.20190221054155","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash.flatten":"^4.4.0","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"ac988b9b17f47dd041eba84873a744d180f38ec3","_id":"@atomist/microgrammar@1.2.0-updateStructure.20190221054155","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-KLQOZnIBRAsYYVC5VeKjb+TP1JMomChH37dwVBPjncifM7Y0Eh2oTqTBh/fR+OrE/EndjpC8BgtKhyAWTK1UwA==","shasum":"7e893924888b1c7ce9d21953b692585f16a31dc4","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.0-updateStructure.20190221054155.tgz","fileCount":174,"unpackedSize":367683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcbjqJCRA9TVsSAnZWagAADYoQAI2oDmFSiaCe8t/PXTM3\nm4BpsOI2wJkWl+LZPbDYLlADn6cIGrcPhF5KdUxMEOYQwqo4vZfHGjugFzGE\nEsO/buoRFo+ULktjKuUd5iMlQpRZSvZPy4ZbhqSl42rDL5C5XXVCqXXcTmWl\nGcpUP1AjHgkn4AVWdkr7MymmC29obePXVpolV+IX+F+rBKsklm6rMT41HW6D\niYLBCG/L8whB1jvyGh792Veef9ZeH697K1XdeplsaZZHZ/vv410rhY0yrvmx\nZIzgRvzAVN3pGPD7qq4cKGfjkCl8jD7sOAnEjRaUjosWq+JGgWD14Z8bpYT9\nwn1IxJB7GPuEF8u9ECbLQnO1ZkRvuL1S4ddFXYKhEX6G2jStvJ3Z9OyZS4bQ\nTrrfs7hX8Rot2yQTJK4f6QfNk+56iXwzwi1+hRA0yCBlAtLxVurNd4rjVT2X\n8QQWWN+jLOtg9aeau6yVXgbzf59IcqO9QLOzP2skfT4Bsgo9RjZ+sblf/HAd\nsOFKqXW16l7RR+4nIwikcn1TeUDN8HGEkmz6Ht5w5UWEkIx000Ffs/PMx/4E\nHAdLCRYFdp+j4VPwBXG/3jjiZbmt+ShlHR1kzgRq9ayJeAyU7LCwFxGi/izh\n6u7wmyTqPd5CxaMzBmB2J8Beoi9Zr+dMo21+3PmQ7jj9uuAJAWFvEtqQGM8g\nO5Pk\r\n=DiB8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICqKbtxWWUPrxy91uPhh9x38QYpPka+ybYMgfvbQrUOZAiEAgFEp3SO8GJasI3bsMZMe5kL02BuRmtA79GTxSfn4CEw="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.0-updateStructure.20190221054155_1550727816971_0.5282595672146371"},"_hasShrinkwrap":false},"1.2.0-master.20190222012515":{"name":"@atomist/microgrammar","version":"1.2.0-master.20190222012515","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"cec1d6831ec46c735208e56fc40c56616cb62f58","_id":"@atomist/microgrammar@1.2.0-master.20190222012515","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-UUvSVjGFJIbB58vcv79FiUIG8Ju85sKaIkEUc8V48luv2tJSJdF9adNzUn2UyrBYbRuvplxCW2E1zXYfbb0Mug==","shasum":"055d9b4e7380dfc27be8f303600fc91814736f87","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.0-master.20190222012515.tgz","fileCount":171,"unpackedSize":360847,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcb0/lCRA9TVsSAnZWagAADO4P+wenTXejghgOWihPuHGq\npvW89viQ+kE8bXKm6dM/XxXflrD7Q1MaF19F9SK+BXIuH0k+V4GL3ajsV/PD\nmne6TOrgOaiiTXaLZ/RWu26v1gSWY2uyL1YLBnQgyLV4wVjkbAKN8516t55K\n5869Zj9WoxZfFP3rnHOBjW7cFNcb1YxFb5XUtz3may8Hhq2mbxSTYZLbx2NE\nzhyweXDZUuJaHN9P2c7ZPDn0Tfy3NPrwecjFAmOxz+SmLeE0ynf+DdEfLC5u\nPMe4gda3NYAsLXwnZEKbQko0iNy7U3ISuDhYKcSu1Ba7iTiW4yRPrRIMsA/S\nDZFjrKlZZRGqiZIGKu7PNPecrL873XuWpnkvvXek0SkRjrG7KCenwAY7dcKu\nwKoVstXWQBrZLJyZQbXwRJ0bAPz+eiFa6BS/jwu2nj/TgU+xb9cxtyR90D+X\nujNg1PCP1Bkhjz8uRPbtSFRCIhCzVTBJYPRbTkPfwiQMTMkG6ZsQUwBA+TR4\nMR7wCpDl8L7M49udARcSJ6RgqqKlMHRnROMEoiazmAAyOl3Ve5ZRrvmMyExC\nB3SQAdiESFY9DstmHezZlkbdilCGEQOX8Lk/YXldUVeQdLWsHaLe7N0S5XEi\nrAD5ONr2hZG7VMtM59htEh9UJ0J4xMqskVWkz56z7yebFSxsyDmLm0UGcoTc\nna7o\r\n=Uof8\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBxPs7z8MBT+o+O/oy6HtLskkSnVlZAvn6iKKOes7fygIgIjyNzu6fXEM1WS9n/gkFSfJMzGnUDHcB55h7BLch5hE="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.0-master.20190222012515_1550798820408_0.0976189449472924"},"_hasShrinkwrap":false},"1.2.0-matchReportIterator.20190222200743":{"name":"@atomist/microgrammar","version":"1.2.0-matchReportIterator.20190222200743","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash.flatten":"^4.4.0","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"8066f611c508021d154878f3f818d694eacb33d8","_id":"@atomist/microgrammar@1.2.0-matchReportIterator.20190222200743","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-BhsMwEvTEVW2oearEDO+JPjkSOol6d75JxRrdSILzfU5UogQWsCfaYPV3eCZj2u9gAO5geSTrlRFLe8e1o2KIQ==","shasum":"2ecf8ffa2657de308e69eca0a67690d8aa3b6acf","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.0-matchReportIterator.20190222200743.tgz","fileCount":171,"unpackedSize":361872,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJccFbnCRA9TVsSAnZWagAAZNkP/isZBeHtVZIEUlqzJdzh\nL/48g/r4ofxiw9JJhf3LAbmhp906kDkDJFmKwdvQdphp9v0wQNKlT/HwP5qi\ntLmg8n9JYirCn5eSp1d+b3D6jE3F5fMtF03LL4Kp+qckLmdb/Ajvq/0eW4Dx\nEwtHwPzpQfhJQaWOGOrJMSnDuPKOfv75j38huB7RQDuW17Tt6/Vc5jETbgPU\nbBdQFGpc9WCuGNQI0kAcITS+qstO3QXT3mHVZ4WZ/6GXAc6ggmK5EVoN/YSD\nLa8Sp7JCYbYenQwuE9VbFfeJGtA/VktR2grBoMryfQb/GbVcR5Gk2qTs6ll6\nIwgGkw1IUdpjaulMFrKhvZIMqvELQ+XGaRK1iRo2EVlIZxdaQ2iiTZrwdjXz\ns28dpQwmU7HkWqmA+lBCMYk9mMr40ktRawT32okK7WoUIe0GtlPhfuUKLU97\nmDxgXB3qgONeJofw6Kbu2w+1y818Z4TcNfSLcaksjrQLgriQf6WYg+O5779D\nXNo7R6jfGzHl231wb4cUeNcgZLFErsr0i0et3Mgi5Afvmunp5Y3qwZHK35Qn\nUouWUhUHOX3KR00kfC7Q5pmJPsNIKITecxjM0qYmvmiHDjSWV3SNOyj6fh0r\nd6UQzq7y/JQtfPXYn2nezVhzz89Oe2wVHKzvdujFVipK1AotRHBtlWZipcmE\nAcfh\r\n=ycIM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC/wvSPPgDPGs3pmxuUSKvQbyS6K84EzPtO5+nF0ik82wIgek0RMPVODDElLNl/7UDJG3iRbNyJVpK6fEj6txpQv48="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.0-matchReportIterator.20190222200743_1550866150130_0.42399406723114663"},"_hasShrinkwrap":false},"1.2.0-master.20190228205313":{"name":"@atomist/microgrammar","version":"1.2.0-master.20190228205313","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"e6943fdf1e84143ef1210535b44b25e56a661f29","_id":"@atomist/microgrammar@1.2.0-master.20190228205313","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-TRWsdLwNw51LCz8quNTUR27fEx4vZMza7rGtn177rOzjmmPYfopu2owifAoe/OzZjVQLByO9YxcVVX29ZfBaLg==","shasum":"e03739397fcf80a474c0630c5031bfd22706c240","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.0-master.20190228205313.tgz","fileCount":171,"unpackedSize":360984,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJceEqgCRA9TVsSAnZWagAAaRMP/2vhZBux2Uqr0FInpBvA\nJ9aZmuYBKfzTix3A8f5aV3iT8XQLbGVIFs03bpOU4aobmQjvggtay5NuYGrP\n48dLScbGkX6JsEBhqz6P1fIybwPAeyb2BuDvOV7eKBZFHthQKLN0GhzGhLC4\nLxcbNCSvKRCWEOQ7ywOI7XEXRbBJiwIpQnchFTKS2NIKh231vKFkx3sgh79Y\ntRdPhGRREqyK4ku/GQ7wyl76ZMB7semjKqlGy6BR3HOc6jqfDshCdWVV5G/m\ncFRLhSwbaqjdTNipUv7fcRC8hDh+Qq3w7zTUeVH/kuyInixb0yuNc050GsEF\nasunLMGDtITt4Vzbzm0rcukOi8GFezaBNwnGhbvfP/a7dHMWCELNSYckd7Kd\nfnM7MVddFY2e/5AoDHvSBt7ja0uqRJXlWG02t03GBmV64jY0l3X5RSFdany8\nD8lA++laz7STzNdKaWA2ADnCPNHZZntZfSWDfqYA1mDbzaPRhP/cacYmhN6k\nrhA1/1cH38u7VvSMcHN9GWBxDhI1gNwiIKCu4Kuq0A09xGdMUuvgEMmVq6wa\nZidKt2bFDJvNzJck2U1G+ET8mAvN10Zk8SqQTFrIFS+SYjFHixNzxzhUmdyz\nt7ximPKVKtHU4E1XLm0CwGAaA/2jD/zmN2v+TezLlA3C0h5/r5QLofVoS6YL\nNTS5\r\n=fFgK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCE76w8xQxbqIQ7HWblqqh6goqRKNUROy/lXBpvd1UF0wIgXirHwn2scfiHGG32Q62cymUiWROMAJivyQb1ADnuNJI="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.0-master.20190228205313_1551387295438_0.06461050735799079"},"_hasShrinkwrap":false},"1.2.0":{"name":"@atomist/microgrammar","version":"1.2.0","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"f2b0fa2b8d86225737ce41538d0ec272abea7c65","_id":"@atomist/microgrammar@1.2.0","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-IW6cU4XjbCTIFAKvyxv8hMkirriWNHvUsSOsKZsmmwf2CxB1TV4POiL+fKAR8NUF/cKQguw1J0MhHlHWzUBK7Q==","shasum":"9f30492c4589091eec9a0a53188f3834e2c4795c","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.0.tgz","fileCount":171,"unpackedSize":360962,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcitreCRA9TVsSAnZWagAAzM0P/jd62Ms9z5ICcNoikoVE\n6rS8NsrrH0k9ugPRNR4HGTGRIDe6icrL7TcL3HwRyHG295yB/UkcHbCuJc3f\n1+s1K9O3I5Z1IrBnUC7qcvB6sa/CrcowtpThsQOtx1bp0RlTc9WatAANmq83\nUhpIFcuQbs0yFICmTOtCMKdG51s75iR6VrWFHwkTV7jL0sd6yd/dpmJPwjVQ\nZnYUMfdEqy7UaeY0pjsEJVXCVaSz9iVOAzpQH4GENOKwR7tx++EOhvYSO26y\n1J/AJZSUK9gSm9oBEvlDQfADKSdBYufeE2lfQSO7tgYylSNN7weLqJ4ZmwBL\nrWZy9lBQpKqpluEGSM8U856eYgOZ/R4mmDS5qAMA5t1CButtXOnQOTU9OVwZ\n0W4il1sPHfMU0cxuLMVEvKKVI7iMTbxGm8BJYZLGPbjpNVzV4n2mnSlYPxHr\n1RTjm62bVgYwt9WriiUpPM8RgY9fREW2qDB7JgWBz6U4YDVcD1sA/Chw+mTy\n2+fJMfzOQRhM8n/hNVcU1dVs3YFyveOtjRHAxwaO+u1D9+2AbflK4QblUNyL\ntS5OtVejnVIAIog4CY3yjzz1EHXwYwhsfVP1kF/qnQgU7kMlpi97XL0Bzd1S\nlzBtcvkIGjCuc3PSak+VxNDZOYKTxJ63GEt+vvYKPRPaPgN84I9LplrKbnLz\nOqHU\r\n=ptS0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGKAU/tb4AWauxHQIJgrObBEEixXeMQs3g+wFGKU+jIJAiEA6E45Cdt4LC8lyff5uyfr++hpyEulIDq1TKR1PLXQryI="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.0_1552603869640_0.014973835498463428"},"_hasShrinkwrap":false},"1.2.1-master.20190320034523":{"name":"@atomist/microgrammar","version":"1.2.1-master.20190320034523","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash.flatten":"^4.4.0","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"9c555baa6db5dc5bd110d97f359f17ba368df2c3","_id":"@atomist/microgrammar@1.2.1-master.20190320034523","_npmVersion":"6.5.0-next.0","_nodeVersion":"11.6.0","_npmUser":{"name":"atomist","email":"npm@atomist.com"},"dist":{"integrity":"sha512-eQC04iThBp2kok6wyHaHuLre/r04PaN7UGTrm9NgGoZABjuf6e2ytLAVyyVV7vi1s+5CZY/9vbKuWH7suupxFQ==","shasum":"f257270c312fb4e17a63cf8ceefa09e662027975","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.1-master.20190320034523.tgz","fileCount":171,"unpackedSize":362418,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJckbe4CRA9TVsSAnZWagAAADQP/ja1V4hQCexseEyRfxTJ\n/i5AF5DySATs+/tBY5kHmAaiRoOBxacs31jmppT7L5XWiL/EPaj/WmmknGE3\nU697ceH1Q9AV2SRh/WaR0UVTguuNpVisZicYlOfQd9xy09zxlgKF+UZmPY7V\nsnPfrlF9m7CesZDe/aFYn/NrrSYx5FmJt+3qwY4eg5tU0DHBSjd3RrbsveSC\nuyDvzdnFJ6O43rJiKjND/+VFYcJEnrjpelwQ3x4yKPUBRKx01/1WE6M+T8N2\n0Hk0jfDNn67GovHFYqQ8LkaOrqDFRPWf8mMxLdkpJ0yXrlh8L6IasYuLrDN2\nz2CC46vw9SQevOIUoP5cVOov+neguZlazxA7WabCqoGwqRdAVKvUwHA9BLGi\nGnp9MgFdk+X6Ig9xMPEGzlCrFl+ko8cFXC0hB3JCY5KIxi+voLYxGh1XPpfg\nmZwRg27c1RASJkOn/NGyQ9+Ql46j9Gw7ixnAcB4EqdQsD4UzJ28Y8eBUdYzR\nV5O4QCamnByD/hovxbGHVeedaJfRl1DZAxEQ+WkFw5TK6+eeAX5FBxeWWPQo\nz04jke46AOLnVFckx4j25fwOiWswSiLD9k2aKhxLgn7KtPlrvIYxwDI3+25R\nlCpjzuzA45dcwfmhl6X8a1wJ5u34VuGcXtsi6E0MMnAKGHDo9crmDM8WaL63\nqgM1\r\n=ijpo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEo9inM+VtqnhfBcqhMjAyhFwxDKgaZM8UXOloORrMy6AiB0VvMZe6TPsY8+v/FZtiaLjUzLZhTxjxA1jVeDbwwY8Q=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.1-master.20190320034523_1553053623936_0.5989889808048121"},"_hasShrinkwrap":false},"1.2.1-master.20190720154946":{"name":"@atomist/microgrammar","version":"1.2.1-master.20190720154946","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash.flatten":"^4.4.0","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","readmeFilename":"README.md","gitHead":"5316df812e34c6d460c4256a4669606d94ee5423","_id":"@atomist/microgrammar@1.2.1-master.20190720154946","_nodeVersion":"12.6.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-ggd3uCrsnUv+teL8IfYWLglssQ0LO7cQNkLOacC8a9dGmitXxjehsud2z44LE+90tAZ1Yisde2RI8r6rOYFTrg==","shasum":"c235ab35543fef279ae0972e06981bb827386c41","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.1-master.20190720154946.tgz","fileCount":172,"unpackedSize":368764,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMzhyCRA9TVsSAnZWagAAwHsQAJiklTppi3CMYX6N3pz7\nhzfdTKEk6zubIBBYimD+k8++B/536VaXhzfSbZ5xeP9hfwK95mhvvzX2N4yE\nVpTkU8/cahkZMwZMZo/eAzs/cuAl/mbWuF5r2ClancxseMJ3iVGuWAmUtBCJ\n6OSpsgTzkKUJ6jKdtf3O6h0S6l2SYrRjAeTCxJPu3rqyDW7zy4toIocdxnf3\nKiysKpOuTdyVolmjSj8yhURLP6q1048hRS/uqO/5CXYEd5WYY/ltPqVDIoPu\nuI7uosWXdD1aZj01EqWfHeou7kBkiZTBRBT1I56QZ4lJb0BSivSg8dZ1WhUS\nu4Tftc4+zsV3IRDixNnb7d0uAuv4zv+l+VLc3o7DqIA6vjfH2kDOsxApYmub\nNTD2gxLhlYhW7fVxfcy/oGCdd5R7GgBPmnu9MVm1D4eInvguQoTQ3FlMKO3n\nGe+qZBZgsCleOQ5YVmasWTbrTYkdyh1LLtI0v1wIZUs8djN0CzX45PlP2BEg\n3wOMCjcpRMcmqI0SyxaMQFX3Qku10SOtjR5eBNR3h9bSsxNtPaPnnYLd/br4\niM987D473yi2J+ykBG+ZlhWaOWzNVhaH/6mCi+n5fQeZ87nFfMHJMwCM6EcZ\n81+JINRchz7XFo5xarS4T0l8/OQba/UkpUzLnYsPzh591fAwlyaHsO83luz0\nTNhx\r\n=ouNV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCFolneHfg/LPj8/THm5CMYSD0XPQUXG1vZXW0BU0V1+gIgDfTFZJUv2JrS6PWbfDqHxCfhyiedfwXGzQBBW8D5vRU="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmUser":{"name":"atomist","email":"npm@atomist.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.1-master.20190720154946_1563637873525_0.5998426209258807"},"_hasShrinkwrap":false},"1.2.1":{"name":"@atomist/microgrammar","version":"1.2.1","description":"Parsing library filling the gap between regular expressions and complete grammars","author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/atomist/microgrammar#readme","repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"keywords":["atomist","microgrammar","parser"],"main":"./index.js","types":"./index.d.ts","dependencies":{"json-stringify-safe":"^5.0.1","lodash.flatten":"^4.4.0","stringify-tree":"^1.0.2"},"devDependencies":{"@types/chai":"^3.5.0","@types/mocha":"^5.2.5","@types/power-assert":"^1.5.0","chai":"^4.1.2","espower-typescript":"^9.0.0","mocha":"^5.2.0","npm-run-all":"^4.1.5","power-assert":"^1.6.0","rimraf":"^2.6.3","supervisor":"^0.12.0","ts-node":"^7.0.1","tslint":"^5.12.0","typedoc":"^0.13.0","typescript":"^3.2.2"},"directories":{"test":"test"},"scripts":{"autotest":"supervisor --watch index.ts,lib,test --extensions ts --no-restart-on exit --quiet --exec npm -- test","benchmark":"run-s benchmark:run benchmark:process","benchmark:process":"node --prof-process isolate-* > profile.txt","benchmark:run":"mocha --prof --require espower-typescript/guess \"test/**/*.benchmark.ts\"","build":"run-s compile test lint doc","clean":"run-p clean:compile clean:doc clean:run","clean:compile":"rimraf git-info.json \"index.{d.ts,js{,.map}}\" \"{lib,test}/**/*.{d.ts,js{,.map}}\" lib/typings/types.ts","clean:dist":"run-s clean clean:npm","clean:doc":"rimraf doc","clean:npm":"rimraf node_modules","clean:run":"rimraf *-v8.log profile.txt log","compile":"tsc --project .","doc":"typedoc --mode modules --excludeExternals --ignoreCompilerErrors --exclude \"**/*.d.ts\" --out doc index.ts lib","lint":"tslint --format verbose --project . --exclude \"node_modules/**\" --exclude \"**/*.d.ts\" \"**/*.ts\"","lint:fix":"npm run lint -- --fix","test":"mocha --require espower-typescript/guess \"test/**/*.test.ts\"","test:one":"mocha --require espower-typescript/guess \"test/**/${TEST:-*.test.ts}\"","typedoc":"npm run doc"},"engines":{"node":">=8.0.0","npm":">=5.0.0"},"gitHead":"ad35b3e0b645d5c49709188f843c0fc8f0410d59","_id":"@atomist/microgrammar@1.2.1","_nodeVersion":"12.6.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-UHDSfFZwGQEVIcK4GkVCimdKlcWUAW7xqI7VvIU2aHME+FaFmE37kHZEdXxFwxJ3oWnnwq3ZgERzQhHX7EspJQ==","shasum":"ee17854e1de250e4907082d23d6ec93bc7659378","tarball":"https://registry.npmjs.org/@atomist/microgrammar/-/microgrammar-1.2.1.tgz","fileCount":172,"unpackedSize":368742,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdMzuMCRA9TVsSAnZWagAAv0UP/2K/ZnySg4l1fgHupOcP\nOqt+GMeW5p6oUw7a4/t9m/n9kwEq59PM3b9nPaWQEW8GbTgEai2/vNnzqLtS\nP0HXNRSCwUYJcux5ik4rdlIDGnc0oSLDE2puLWrxaLeuk0xIxb1irhOgQIOt\nYNx2Rsc4QL50ZqvRL88ehN2L5vsc0iZqVayT1x1zx/yH7ZOpjUO/Oj2T0ikP\n3WD08136biDyiq/K0lj8NtkcR+ej7PT5QIXVznq6XdHIFWAXAF29stdD09rK\nB3fbHTT2NeMbePfciZLuwvS9S4vSkq/PCAuX0lebpqMURYPjOU2qeB4UnjUl\nLkzlyb9+Kn5TpUS91TMLasKi5V+P1UwIP/pD2ify4Fb8JR2g6pDAGIEUwR+H\nBQ6ua8AB+hurU2dTHlTELIiPZ6JFKoA6DrNEMAAJTP3B/4AKMTntprFb/BV5\nvQGn5TMScGv+GbPXqhn5T9Pk2E3BASRpdIAzojMDf4GM/l4SvbDEqBpHT5To\n7nbpB3hQ0RkJ6K7jZtirmCdDpXewLmeR14BbJlfieb7gvMI3PMgB7pZte4UJ\np9LRR5B1bEWrE+jsFyBsYTVkqkN0ZT8U2x+2OfVHQjn7JC79nb4YvVj1DDZK\nk9MSBtcX3jM3rvzsVPTK8zE3H7TqORRbPPx9byeWK1MPixFBJGGiEYMBTBqF\nVL1x\r\n=hB4A\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF7xZeWGjA1x4IuuwcVM3JWZP4zXymNCp2h0swMZGHkJAiAeki/PGfiESrlH4qeP/iIiZe6ocbHY1ZE7TQfQ47dcnQ=="}]},"maintainers":[{"name":"atomist","email":"npm@atomist.com"}],"_npmUser":{"name":"atomist","email":"npm@atomist.com"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/microgrammar_1.2.1_1563638667296_0.6056219382174681"},"_hasShrinkwrap":false}},"readme":"# @atomist/microgrammar\n\n[![atomist sdm goals](http://badge.atomist.com/T29E48P34/atomist/microgrammar/92d2035b-575e-41c4-9088-996dc70d69c2)](https://app.atomist.com/workspace/T29E48P34)\n[![npm version](https://img.shields.io/npm/v/@atomist/microgrammar.svg)](https://www.npmjs.com/package/@atomist/microgrammar)\n\nParsing library written in [TypeScript][ts], filling the large gap\nbetween the sweet spots of regular expressions and full-blown\n[BNF][bnf] or equivalent grammars.  It can parse and cleanly update\nstructured content.\n\n[ts]: https://www.typescriptlang.org/ (TypeScript)\n\n## Concepts\n\n**Microgrammars** are a powerful way of parsing structured content\nsuch as source code, described in this [Stanford paper][mg-paper].\nMicrogrammars are designed to recognize structures in a string or\nstream and extract their content: For example, to recognize a Java\nmethod that has a particular annotation and to extract particular\nparameters. They are more powerful and [typically more\nreadable][regex-hell] than [regular expressions][regex] for complex\ncases, although they can be built using regular expressions.\n\n[mg-paper]: http://web.stanford.edu/~mlfbrown/paper.pdf (How to build static checking systems using orders of magnitude less code Brown et al., ASPLOS 2016)\n\nAtomist microgrammars go beyond the Stanford paper example in that\nthey permit _updating_ as well as matching, preserving positions. They\nalso draw inspiration from other experience and sources such as the\nold [SNOBOL programming language][snobol].\n\n[snobol]: https://en.wikipedia.org/wiki/SNOBOL (SNOBOL Programming Language)\n[regex-hell]: https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags#answer-1732454\n[regex]: https://en.wikipedia.org/wiki/Regular_expression\n\n## Examples\n\nThere are two styles of use:\n\n-   From *definitions*: Defining a grammar in JavaScript objects representing the subcomponents (lower level productions)\n-   From strings: Defining a grammar in a string that resembles input\n    that will be matched\n        \nA microgrammar has a return type defined by its definitions. Each match implements this interface and also the `PatternMatch` interface, which exposes the offset within the input and matched value, which may differ from the exposed typed value. (For example, a `Person` might have a `forename` and `surname`, but its `$matched` value might include the entire matched string with whitespace.) The fields of the `PatternMatch` interface begin with a `$` to ensure that they are out of band.\n\nWhen you've defined a microgrammar, you can use it to match input: usually a string.\n\nGenerator-style iteration is usually most efficient, and looks like this:\n\n```typescript\nconst matches = myMicrogrammar.matchIterator(inputString);\nfor (const match of matches) {\n\t// Do with match. You can jump out of the generator here.\n}\n```\nYou can also get all matches in one pass, like this:\n\n```typescript\nconst matches = myMicrogrammar.findMatches(inputString);\nfor (const match of matches) {\n\t// Do with match\n}\n```\n\nIf you are seeking only one match, you can use a method that returns a match or `undefined`, as follows:\n\n```typescript\nconst match = myMicrogrammar.firstMatch(inputString);\nif (match) {\n\t// Do with match\n}\n```\n\n### Definitions style\n\nHere's a simple example:\n\n```typescript\nconst mg = microgrammar<{name: string, age: number}>({\n    name: /[a-zA-Z0-9]+/,\n    _col: \":\",\n    age: Integer\n});\n\nconst results = mg.findMatches(\"-celine:61 greg*^ tom::: mandy:11\");\nassert(result.length === 2);\nconst first = results[0];\nassert(first.$matched === \"celine:61\");\n// The offset of this match was the 1st character, as the 0th was discarded\nassert(first.$offset === 1);\nassert(first.name === \"celine\");\nassert(first.age === 61);\n```\n\nSome notes:\n\n-   A microgrammar definition is typically an object literal, with its\n    properties being matched in turn. This is like **concatenation**\n    in a BNF grammar.\n-   Matcher property values can be regular expressions (like\n    `/[a-zA-Z0-9]+/` here), string literals (like `:`), or custom\n    matchers (like `Integer`). It's easy to define custom matchers for\n    use in composition.\n-   All properties need to match for the whole microgrammar to match.\n-   Properties that match are bound to the result, unless their names begin with `_`, in which\n    case the values are discarded.\n-   Certain out of band values, beginning with `$`, are added to the\n    results, showing the exact text that matched, the offset etc.\n-   When using TypeScript, microgrammar returns can be strongly typed. In this case we've\n    used an anonymous type, but we could also use an interface. We\n    could also use untyped, JavaScript style.\n-   Matching skips junk such as `greg*^ tom:::`. In this case, `greg`\n    and `tom:` will look like the start of valid matches, but the\n    first will fail when it can't match a `:` and the second when\n    there isn't a digit after the colon.\n-   We can match against a string or a stream. In this case we've used\n    a string. In stream matching, we'd be more likely to use one an\n    API offering callbacks rather than building an array, so we don't\n    need to hold all our matches in memory at once.\n\nOf course, such a simple example could easily be handled by a regular\nexpression and capture groups. But the power becomes apparent with\nnested productions and more elaborate matchers.\n\nA more complex example, showing composition:\n\n```typescript\nexport const CLASS_NAME = /[a-zA-Z_$][a-zA-Z0-9_$]+/;\n\n// Any annotation we're not interested in\nconst DiscardedAnnotation = {\n    _at: \"@\",\n    _annotationName: CLASS_NAME,\n    _content: optional(JavaParenthesizedExpression),\n};\n\nconst SpringBootApp = microgrammar<{ name: string }>({\n    _app: \"@SpringBootApplication\",\n    _content: optional(JavaParenthesizedExpression),\n    _otherAnnotations: zeroOrMore(DiscardedAnnotation),\n    _visibility: optional(\"public\"),\n    _class: \"class\",\n    name: CLASS_NAME,\n});\n```\n\nThis will match content like this:\n\n```java\n@SpringBootApplication\n@Foo\n@Bar(name = \"Baz\", magicParam = 31754)\npublic class MySpringBootApplication\n```\n\nNotes:\n\n-   `JavaParenthesizedExpression` is a built-in matcher constant that\n    matches any valid Java content within `(...)`. It uses a state\n    machine. It's easy to write such custom matchers.\n-   By default, microgrammars are tolerant of whitespace, treating it\n    as a token separator. This is the behavior we want when parsing\n    most languages or configuration formats.\n-   Because the other properties have names beginning with `_`, only\n    the class name (`MySpringBootApplication` in our example) is bound\n    to the result. We care about the structure of the rest of the\n    class declaration, but we don't need to extract other values in\n    this particular case.\n\n### String style\n\nThis is a higher level usage model in which a string resembling the\ndesired input but with variable placeholders is used to define the\ngrammar.\n\nThis style is ideally suited for simpler grammars. For example:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\"});\n```\n\nIt can be combined with the definitional style through providing\noptional definitions for the named fields. For example, to constrain\nthe match on a name in the above example using a regular expression:\n\n```typescript\nconst ValuePredicateGrammar = microgrammar<Predicate>({\n    phrase: \"@${name}='${value}'\", \n    terms: {\n    \tname: /[a-z]+/\n    }\n});\n```\n\nAs with the object definitional style, whitespace is ignored by default.\n\nFurther documentation can be found in the\n[reference](docs/reference.md).  You can also take a look at the tests\nin this repository.\n\n## Alternatives and when to use microgrammars\n\nMicrogrammars have obvious similarities to [BNF grammars][bnf], but\ndiffer in some important respects:\n\n-   They are intended to match and explain _parts_ of the input, rather\n    than the whole input\n-   They excel at skipping content they are uninterested in\n-   They are not necessarily context free\n-   They do not need to construct a full AST, although they construct\n    ASTs for structures they do match. Thus they can easily cope with\n    partially structured data, happily skipping over incomprehensible content\n\n[bnf]: https://en.wikipedia.org/wiki/Backus–Naur_form (Backus–Naur Form)\n\nSimilarities are:\n\n-   The idea of **productions**\n-   Composability, including the ability to reuse productions in\n    different grammars\n-   Operations such as _alternative_, _optional_ and _rep_, that\n    enable building complex structures.\n\nCompared to regular expressions, microgrammars are:\n\n-   Capable of handing greater complexity\n-   More composable\n-   Higher level, able to use regular expressions as building blocks\n-   Capable of expressing nested structures\n-   Arbitrarily extensible through TypeScript function predicates and\n    custom **matchers**\n\nWhile it would be overkill to use a microgrammar for something that\ncan be expressed in a simple regex, microgrammars tend to be clearer\nfor complex cases.\n\n## Usage\n\nThe [`@atomist/microgrammar` package][mg-npm] contains both the\nTypeScript typings and compiled JavaScript.  You can use this project\nby adding the dependency in your `package.json`.\n\n```\n$ npm install --save @atomist/microgrammar\n```\n\n[mg-npm]: https://www.npmjs.com/package/@atomist/microgrammar (@atomist/microgrammar Node.js Package)\n\n## Troubleshooting\n\nIf you struggle to make your microgrammars match, please refer to the [troubleshooting page][trouble].\n\n[trouble]: docs/trouble.md (Troubleshooting microgrammars)\n\n## Performance considerations\n\nSee [Writing efficient microgrammars][efficiency].\n\n[efficiency]: docs/performance.md (Writing efficient microgrammars)\n\n## Support\n\nGeneral support questions should be discussed in the `#support`\nchannel in the [Atomist community Slack workspace][slack].\n\nIf you find a problem, please create an [issue][].\n\n[issue]: https://github.com/atomist/microgrammar/issues\n\n## Development\n\nYou will need to install [Node.js][node] to build and test this\nproject.\n\n[node]: https://nodejs.org/ (Node.js)\n\n### Build and test\n\nInstall dependencies.\n\n```\n$ npm install\n```\n\nUse the `build` package script to compile, test, lint, and build the\ndocumentation.\n\n```\n$ npm run build\n```\n\n### Release\n\nReleases are handled via the [Atomist SDM][atomist-sdm].  Just press\nthe 'Approve' button in the Atomist dashboard or Slack.\n\n[atomist-sdm]: https://github.com/atomist/atomist-sdm (Atomist Software Delivery Machine)\n\n---\n\nCreated by [Atomist][atomist].\nNeed Help?  [Join our Slack workspace][slack].\n\n[atomist]: https://atomist.com/ (Atomist - How Teams Deliver Software)\n[slack]: https://join.atomist.com/ (Atomist Community Slack)\n","maintainers":[{"email":"neil.prosser+npmjs@gmail.com","name":"neilprosser"},{"email":"npm@atomist.com","name":"atomist-bot"},{"email":"cd@atomist.com","name":"cdupuis"},{"email":"slimslenderslacks@gmail.com","name":"slimslenderslacks"}],"time":{"modified":"2023-02-23T17:59:18.387Z","created":"2017-06-21T03:43:43.515Z","0.1.0":"2017-06-21T03:43:43.515Z","0.2.0":"2017-06-22T03:38:17.980Z","0.3.1":"2017-06-23T00:29:33.578Z","0.3.3":"2017-06-23T00:59:20.346Z","0.3.4":"2017-06-23T01:09:12.991Z","0.3.5":"2017-06-23T01:37:46.028Z","0.3.6":"2017-06-24T05:48:50.717Z","0.3.7":"2017-06-26T00:33:36.570Z","0.3.9":"2017-06-26T08:04:42.569Z","0.3.10":"2017-06-26T10:33:03.029Z","0.3.11":"2017-06-29T15:04:18.793Z","0.3.12":"2017-06-30T00:57:54.951Z","0.4.0":"2017-07-03T01:15:02.729Z","0.5.0":"2017-07-09T08:08:35.968Z","0.5.1":"2017-07-09T08:56:27.412Z","0.6.0":"2017-07-30T19:50:18.812Z","0.6.1":"2017-09-16T07:07:51.929Z","0.6.2":"2017-09-24T08:09:55.827Z","0.7.0":"2017-10-03T23:55:30.569Z","0.8.0-20180803150803":"2018-08-03T15:09:21.295Z","0.8.0-20180803150932":"2018-08-03T15:10:55.691Z","0.8.0-20180807201900":"2018-08-07T20:25:09.091Z","0.8.0":"2018-08-07T20:25:42.096Z","0.8.1-20180807205720":"2018-08-07T20:58:46.015Z","0.8.1-20180812171823":"2018-08-12T17:19:40.870Z","0.8.1":"2018-08-12T17:20:58.897Z","0.8.2-20180812172140":"2018-08-12T17:22:57.704Z","0.8.2-20180812191723":"2018-08-12T19:18:39.146Z","0.9.0-20180822184742":"2018-08-22T18:49:07.763Z","0.9.0-20180822192508":"2018-08-22T19:28:41.268Z","0.9.0":"2018-08-22T19:31:48.790Z","0.9.1-20180822193237":"2018-08-22T19:33:56.878Z","0.9.1-20180822200900":"2018-08-22T20:10:39.272Z","0.9.1":"2018-08-22T20:11:28.271Z","0.9.2-20180822201219":"2018-08-22T20:15:01.866Z","1.0.0-master.20180828164924":"2018-08-28T16:51:02.357Z","1.0.0-M.1":"2018-08-28T17:06:01.755Z","1.0.0-master.20180829162516":"2018-08-29T16:26:45.745Z","1.0.0-master.20180916080140":"2018-09-16T08:03:25.786Z","1.0.0-M.4":"2018-09-16T08:04:11.837Z","1.0.1-master.20181109093737":"2018-11-09T09:38:46.582Z","1.0.1":"2018-11-09T09:40:45.777Z","1.0.2-typed.20190108000950":"2019-01-08T00:11:02.592Z","1.0.2-jess-test.20190108001135":"2019-01-08T00:12:37.909Z","1.0.2-master.20190108055535":"2019-01-08T05:56:51.461Z","1.0.2-master.20190108055954":"2019-01-08T06:01:00.861Z","1.0.2-nortissej.concat-enough.20190108225105":"2019-01-08T22:52:16.577Z","1.0.2-master.20190108233554":"2019-01-08T23:36:55.099Z","1.0.2-nortissej.concat-enough.20190109221257":"2019-01-09T22:13:59.719Z","1.0.2-nortissej.concat-enough.20190110000649":"2019-01-10T00:07:54.846Z","1.0.2-master.20190110002349":"2019-01-10T00:25:07.615Z","1.0.3-master.20190111000638":"2019-01-11T00:07:59.836Z","1.0.3":"2019-01-11T00:14:06.829Z","1.0.3-grammar.20190111010520":"2019-01-11T01:06:35.392Z","1.0.3-grammar.20190111012054":"2019-01-11T01:22:07.261Z","1.0.3-grammar.20190111013920":"2019-01-11T01:40:32.954Z","1.0.3-grammar.20190111015924":"2019-01-11T02:00:40.903Z","1.0.3-grammar.20190111181509":"2019-01-11T18:17:51.720Z","1.0.4-master.20190111215805":"2019-01-11T21:59:11.681Z","1.0.4-nortissej.failure-reporting.20190122024851":"2019-01-22T02:50:32.124Z","1.0.4-nortissej.failure-reporting.20190122032620":"2019-01-22T03:27:50.294Z","1.0.4-nortissej.failure-reporting.20190122034452":"2019-01-22T03:46:34.566Z","1.0.4-nortissej.failure-reporting.20190130180617":"2019-01-30T18:07:39.110Z","1.0.4-master.20190130181034":"2019-01-30T18:12:06.045Z","1.0.4-master.20190130184106":"2019-01-30T18:42:28.097Z","1.0.4":"2019-01-30T20:12:38.003Z","1.0.5-master.20190130221910":"2019-01-30T22:20:33.573Z","1.1.0-master.20190131044730":"2019-01-31T04:48:48.194Z","1.1.0-master.20190205190919":"2019-02-05T19:10:32.238Z","1.0.5-MatchReport2.20190206164724":"2019-02-06T16:49:03.120Z","1.0.5-MatchReport2.20190207015904":"2019-02-07T02:00:36.440Z","1.1.0-master.20190208183142":"2019-02-08T18:33:05.227Z","1.0.5-MatchReport2.20190210181438":"2019-02-10T18:15:57.503Z","1.0.5-MatchReport2.20190210182036":"2019-02-10T18:21:58.297Z","1.0.5-MatchReport2.20190210211149":"2019-02-10T21:13:08.045Z","1.0.5-MatchReport2.20190211023805":"2019-02-11T02:39:57.287Z","1.0.5-MatchReport2.20190211023903":"2019-02-11T02:40:41.855Z","1.0.5-MatchReport2.20190211030756":"2019-02-11T03:09:14.936Z","1.0.5-MatchReport2.20190211031146":"2019-02-11T03:13:16.387Z","1.1.0-MatchReport2.20190211040721":"2019-02-11T04:08:46.477Z","1.1.0-MatchReport2.20190211042928":"2019-02-11T04:30:49.661Z","1.1.0-MatchReport2.20190220033729":"2019-02-20T03:38:52.374Z","1.1.0-MatchReport2.20190220040924":"2019-02-20T04:10:55.534Z","1.1.0-master.20190220043504":"2019-02-20T04:36:42.909Z","1.1.0-master.20190220161254":"2019-02-20T16:14:29.331Z","1.2.0-master.20190221030950":"2019-02-21T03:11:23.882Z","1.2.0-updateStructure.20190221054155":"2019-02-21T05:43:37.174Z","1.2.0-master.20190222012515":"2019-02-22T01:27:00.573Z","1.2.0-matchReportIterator.20190222200743":"2019-02-22T20:09:10.327Z","1.2.0-master.20190228205313":"2019-02-28T20:54:55.607Z","1.2.0":"2019-03-14T22:51:09.796Z","1.2.1-master.20190320034523":"2019-03-20T03:47:04.119Z","1.2.1-master.20190720154946":"2019-07-20T15:51:13.688Z","1.2.1":"2019-07-20T16:04:27.432Z"},"homepage":"https://github.com/atomist/microgrammar#readme","keywords":["atomist","microgrammar","parser"],"repository":{"type":"git","url":"git+https://github.com/atomist/microgrammar.git"},"author":{"name":"Atomist","email":"support@atomist.com","url":"https://atomist.com/"},"bugs":{"url":"https://github.com/atomist/microgrammar/issues"},"license":"SEE LICENSE IN LICENSE","readmeFilename":"README.md"}