{"_id":"mona-parser","_rev":"49-825652bdf7c2c3171807a74ac6f17f71","name":"mona-parser","time":{"modified":"2022-06-20T05:21:58.192Z","created":"2013-09-22T23:14:20.176Z","0.1.0":"2013-09-22T23:14:21.744Z","0.1.1":"2013-09-22T23:15:23.785Z","0.1.2":"2013-09-23T04:39:01.970Z","0.2.0":"2013-09-24T04:38:52.385Z","0.2.1":"2013-09-24T05:03:57.492Z","0.3.0":"2013-09-25T22:24:21.489Z","0.4.0":"2013-09-26T07:15:51.495Z","0.5.0":"2013-09-27T08:23:39.345Z","0.6.0":"2013-09-28T06:26:37.005Z","0.7.0":"2013-10-01T05:25:30.281Z","0.7.1":"2013-10-02T03:58:45.062Z","0.7.2":"2013-10-11T09:29:22.849Z","0.7.3":"2013-10-13T04:46:56.488Z","0.8.0":"2013-10-14T05:50:31.223Z","0.8.1":"2013-10-15T02:49:00.739Z","0.8.2":"2015-02-13T07:25:56.463Z"},"maintainers":[{"name":"zkat","email":"kat@sykosomatic.org"}],"dist-tags":{"latest":"0.8.2"},"description":"Composable parsers","readme":"# Mona [![NPM version](https://badge.fury.io/js/mona-parser.png)](http://badge.fury.io/js/mona-parser) [![Build Status](https://travis-ci.org/zkat/mona.png)](https://travis-ci.org/zkat/mona)\n\n`mona` is\n[hosted at Github](http://github.com/zkat/mona). `mona` is a\npublic domain work, dedicated using\n[CC0 1.0](https://creativecommons.org/publicdomain/zero/1.0/). Feel\nfree to do whatever you want with it.\n\n# Quickstart\n\n### Install\n\n`mona` is available through both [NPM](http://npmjs.org) and\n[Bower](http://bower.io).\n\n`$ npm install mona-parser`\nor\n`$ bower install mona`\n\nNote that the `bower` version requires manually building the release.\n\nYou can also download a prebuilt `UMD` version of `mona` from the\n[website](http://zkat.github.io/mona):\n\n* [mona.js](http://zkat.github.io/mona/build/mona.js)\n* [mona.min.js](http://zkat.github.io/mona/build/mona.min.js)\n* [mona.js.src](http://zkat.github.io/mona/build/mona.js.src) (source map\n  for minified version)\n\n### Example\n\n```javascript\nfunction csv() {\n  return mona.splitEnd(line(), eol());\n}\n\nfunction line() {\n  return mona.split(cell(), mona.string(\",\"));\n}\n\nfunction cell() {\n  return mona.or(quotedCell(),\n                 mona.text(mona.noneOf(\",\\n\\r\")));\n\n}\n\nfunction quotedCell() {\n  return mona.between(mona.string('\"'),\n                      mona.string('\"'),\n                      mona.text(quotedChar()));\n}\n\nfunction quotedChar() {\n  return mona.or(mona.noneOf('\"'),\n                 mona.and(mona.string('\"\"'),\n                          mona.value('\"')));\n}\n\nfunction eol() {\n  var str = mona.string;\n  return mona.or(str(\"\\n\\r\"),\n                 str(\"\\r\\n\"),\n                 str(\"\\n\"),\n                 str(\"\\r\"),\n                 \"end of line\");\n}\n\nfunction parseCSV(text) {\n  return mona.parse(csv(), text);\n}\n\nparseCSV('foo,\"bar\"\\n\"b\"\"az\",quux\\n');\n// => [['foo', 'bar'], ['b\"az', 'quux']]\n```\n\n# Introduction\n\nWriting parsers with `mona` involves writing a number of individually-testable\n`parser constructors` which return parsers that `mona.parse()` can then\nexecute. These smaller parsers are then combined in various ways, even provided\nas part of libraries, in order to compose much larger, intricate parsers.\n\n`mona` tries to do a decent job at reporting parsing failures when and where\nthey happen, and provides a number of facilities for reporting errors in a\nhuman-readable way.\n\n`mona` is based on [smug](https://github.com/drewc/smug), and Haskell's\n[Parsec](http://www.haskell.org/haskellwiki/Parsec) library.\n\n### Features\n\n* Short, readable, composable parsers\n* Includes a library of useful parsers and combinators\n* Returns arbitrary data from parsers, not necessarily a plain parse tree\n* Human-readable error messages with source locations\n* Facilities for improving your own parsers' error reports\n* Supports context-sensitive parsing (see `examples/context.js`)\n* Supports asynchronous, incremental parsing with `parseAsync`.\n* Node.js stream API support with `parseStream`, including piping support\n* Heavy test coverage (see `src/mona-test.js`)\n* Small footprint (less that 4kb gzipped and minified)\n* Fully documented API\n\n### Documentation\n\nDocumentation of the latest released version is\n[available here](http://zkat.github.io/mona). Docs are also included with\nthe `npm` release. You can build the docs yourself by running\n`npm install && make docs` in the root of the source directory.\n\nThe documentation is currently organized as if `mona` had multiple modules,\nalthough all modules' APIs are exported through a single module/namespace,\n`mona`. That means that `mona/api.parse()` is available through `mona.parse()`\n\n#### A Gentle Introduction \n\n`mona` works by composing functions called `parsers`. These functions are\ncreated by so-called `parser constructors`. Most of the `mona` API exposes these\nconstructors.\n\n##### Primitive parsers\n\nThere are three primitive parsers in mona: `value()`, `fail()`, and\n`token()`.\n\n* `value()` - results in its single argument, without consuming input.\n* `fail()` - fails unconditionally, without consuming input.\n* `token()` - consumes a single token, or character, from the input.\n\nSimply creating a parser is not enough to execute a parser, though.  We need to\nuse the `parse` function, to actually execute the parser on an input string:\n\n```javascript\nmona.parse(mona.value(\"foo\"), \"\"); // => \"foo\"\nmona.parse(mona.fail(), \"\"); // => throws an exception\nmona.parse(mona.token(), \"a\"); // => \"a\"\nmona.parse(mona.token(), \"\"); // => error, unexpected eof\n```\n\n##### The primitive combinator\n\nThese three parsers do not seem to get us much of anywhere, so we introduce our\nfirst *combinator*: `bind()`. `bind()` accepts a parser as its first argument,\nand a function as its second argument. The function will be called with the\nparser's result value *only if the parser succeeds*. The function *must then\nreturn another parser*, which will be used to determine `bind()`'s value:\n\n```javascript\nmona.parse(mona.bind(mona.token(), function(character) {\n  if (character === \"a\") {\n    return mona.value(\"found an 'a'!\");\n  } else {\n    return mona.fail();\n  }\n}), \"a\"); // => \"found an 'a'!\"\n```\n\n##### Basic utility combinators\n\n`bind()`, of course, is just the beginning. Now that we know we can combine\nparsers, we can play with some of `mona`'s fancier parsers and combinators. For\nexample, the `or` combinator resolves to the first parser that succeeds, in the\norder they were provided, or fails if none of those parsers succeeded:\n\n```javascript\nmona.parse(mona.or(mona.fail(\"nope\"),\n                   mona.fail(\"nope again\"),\n                   mona.value(\"this one!\")),\n           \"\");\n// => \"this one!\"\n```\n\n```javascript\nmona.parse(mona.or(mona.fail(\"nope\"),\n                   mona.value(\"this one!\"),\n                   mona.value(\"but not this one\")),\n           \"\");\n// => \"this one!\"\n```\n\n`and()` is another basic combinator. It succeeds only if all its parsers\nsucceed, and resolves to the value of the last parser. Otherwise, it fails with\nthe first failed parser's error.\n\n```javascript\nmona.parse(mona.and(mona.value(\"foo\"),\n                    mona.value(\"bar\")),\n           \"\");\n// => \"bar\"\n```\n\nFinally, there's the `not()` combinator. It's important to note that, regardless\nof its argument's result, `not()` will not consume input... it must be combined\nwith something that does.\n\n```javascript\nmona.parse(mona.and(mona.not(mona.token()), mona.value(\"end of input\")), \"\");\n// => \"end of input\"\n```\n\n##### Matching strings\n\nThe `string()` parser might come in handy: It results in a string matching a given\nstring:\n\n```javascript\nmona.parse(mona.string(\"foo\"), \"foo\");\n// => \"foo\"\n```\n\nAnd can of course be combined with some combinator to provide an alternative\nvalue:\n\n```javascript\nmonap.parse(mona.and(mona.string(\"foo\"), mona.value(\"got a foo!\")), \"foo\");\n// => \"got a foo!\"\n```\n\nThe `is()` parser can also be used to succeed or fail depending on whether the\nnext token matches a particular predicate:\n\n```javascript\nmona.parse(mona.is(function(x) { return x === \"a\"; }), \"a\");\n// => \"a\"\n```\n\n##### Sequential syntax\n\nWriting parsers by composing functions is perfectly fine and natural, and you\nmight get quite a feel for it, but sometimes it's nice to have something that\nfeels a bit more procedural. For situations like that, you can use `sequence`:\n\n```javascript\nfunction parenthesized() {\n  return mona.sequence(function(s) {\n    // The s() function passed into `sequence()`'s callback\n    // must be used to execute any parsers within the sequence.\n    var open = s(mona.string(\"(\"));\n    // open === \"(\" if the `string()` parser succeeds.\n    var data = s(mona.token());\n    var close = s(mona.string(\")\"));\n    // The `sequence()` callback must return another parser, just like `bind()`.\n    // Also like `bind()`, it can `return fail()` to fail the parser.\n    return mona.value(data);\n  });\n}\nmona.parse(parenthesized(), \"(a)\");\n// => \"a\"\n```\n\nWe can generalize this parser into a combinator by accepting an arbitrary parser\nas an input:\n\n```javascript\nfunction parenthesized(parser) {\n  return mona.sequence(function(s) {\n    var open = s(mona.string(\"(\"));\n    var data = s(parser); // Use the parser here!\n    var close = s(mona.string(\")\"));\n    return mona.value(data);\n  });\n}\nmona.parse(parenthesized(mona.string(\"foo!\")), \"(foo!)\");\n// => \"foo!\"\n```\n\nNote that if the given parser consumes closing parentheses, this will fail:\n\n```javascript\nmona.parse(parenthesized(mona.string(\"something)\"), \"(something)\");\n// => error, unexpected EOF\n```\n\n##### The Rest of It\n\nOnce you've got the basics down, you can explore\n[`mona`'s API](http://zkat.github.io/mona) for more interesting parsers. A\nvariety of useful parsers are available for use, such as `collect()`, which\ncollects the results of a parser into an array until the parser fails, or\n`float()`, which parses a floating-point number and returns the actual\nnumber. For more examples on how to use `mona` to create parsers for actual\nformats, take a look in the `examples/` directory included with the project,\nwhich includes examples for `json` and `csv`.\n\n### Building\n\nThe `npm` version includes a build/ directory with both pre-built and\nminified [UMD](https://github.com/umdjs/umd) versions of `mona` which\nare loadable by both [AMD](http://requirejs.org/docs/whyamd.html) and\n[CommonJS](http://www.commonjs.org/) module systems. UMD will define\nwindow.mona if neither AMD or CommonJS are used. To generate these files\nIn `bower`, or if you fetched `mona` from source, simply run:\n\n```\n$ npm install\n...dev dependencies installed...\n$ make\n```\n\nAnd use `build/mona.js` or `build/mona.min.js` in your application.\n","versions":{"0.8.2":{"name":"mona-parser","version":"0.8.2","description":"Composable parsers","main":"src/mona.js","scripts":{"prepublish":"make","test":"make test"},"repository":{"type":"git","url":"https://github.com/zkat/mona"},"keywords":["parser","parsing","monads","parser-combinators","functional","fp"],"author":{"name":"Kat Marchán","email":"kzm@sykosomatic.org"},"licenses":[{"type":"CC0","url":"https://creativecommons.org/publicdomain/zero/1.0/"}],"bugs":{"url":"https://github.com/zkat/mona/issues"},"files":["Makefile","README.md","src/*.js","build/","docs/","test/*.js"],"devDependencies":{"browserify":"~2.28.0","uglify-js":"~2.3.6","jsdoc":"~3.2.0","jshint":"~2.1.10","mocha":"~1.12.0","moment":"~2.2.1","ink-docstrap":"~0.2.0-0"},"testling":{"browsers":["iexplore/7.0","iexplore/8.0","iexplore/9.0","iexplore/10.0","chrome/25.0","firefox/19.0","opera/12.0","firefox/nightly","opera/next","chrome/canary","iphone/6.0","ipad/6.0","safari/6.0","android-browser/4.2"],"harness":"mocha","files":"**/*.js"},"gitHead":"d20a69f6bf4783432ccc40a423c0ffd98e4029c3","homepage":"https://github.com/zkat/mona","_id":"mona-parser@0.8.2","_shasum":"ee12484157c84f5907fa4e5b88f4b76948f2e965","_from":".","_npmVersion":"2.1.7","_nodeVersion":"0.10.33","_npmUser":{"name":"zkat","email":"kat@sykosomatic.org"},"maintainers":[{"name":"zkat","email":"kat@sykosomatic.org"}],"dist":{"shasum":"ee12484157c84f5907fa4e5b88f4b76948f2e965","tarball":"https://registry.npmjs.org/mona-parser/-/mona-parser-0.8.2.tgz","integrity":"sha512-6PY3VzPZzzoNLo4/qobwLREmVqcCRh/OxzpFpUW65ruXzyf6BodwgkaZp3Anm2za18OWhu6pvKOfhYMV1bxYJg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHKrmHoEnRs8E31Wb36fPtDXy8Nd8aO5CBphfO73Nr7GAiEAql6xYlpPTppPsqaJQZ8p43qKZTZSBcCL1b297qUyyKo="}]},"deprecated":"This package has been renamed. npm install mona instead"}},"homepage":"https://github.com/zkat/mona","keywords":["parser","parsing","monads","parser-combinators","functional","fp"],"repository":{"type":"git","url":"https://github.com/zkat/mona"},"author":{"name":"Kat Marchán","email":"kzm@sykosomatic.org"},"bugs":{"url":"https://github.com/zkat/mona/issues"},"readmeFilename":"README.md"}