SkillAgentSearch skills...

Mona

Composable parsing for JavaScript

Install / Use

/learn @zkat/Mona
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

mona

Travis npm version license

mona is a Javascript library for easily writing reusable, composable parsers. It makes parsing complex grammars easy and fun!

With mona, you simply write some Javascript functions that parse small pieces of text and return any Javascript value, and then you glue them together into big, intricate parsers using combinators to... combine them! No custom syntax or separate files or separate command line tools to run: you can integrate this into your regular JS app.

It even makes it really really easy to give excellent error messages, including line and column numbers, and messages with what was expected, with little to no effort.

New parsers are hella easy to write -- give it a shot! And if you're familiar with Parsec, then you've come to the right place. :)

Table of Contents

Install

$ npm install mona

You can directly require mona through your module loader of choice, or you can use the prebuilt UMD versions found in the browser/ directory:

  • Node.js/CommonJS - var mona = require('mona')
  • ES6 Modules/Babel - import mona from 'mona'
  • AMD - define(['node_modules/mona/browser/mona'], function (mona) { ... })
  • Global - <script src=/js/node_modules/mona/browser/mona.min.js></script>

Examples

Parse a series of ints separated by commas

function commaInts () {
  return mona.split(mona.integer(), mona.string(','))
}
mona.parse(commaInts(), '1,2,3,49829,49,139')
// => [1, 2, 3, 49829, 49, 139]

A simple, readable CSV parser in ~25 lines

function parseCSV (text) {
  return mona.parse(csv(), text)
}
function csv () {
  return mona.splitEnd(line(), mona.eol())
}
function line () {
  return mona.split(cell(), mona.string(','))
}
function cell () {
  return mona.or(quotedCell(),
                 mona.text(mona.noneOf(',\n\r')))
}
function quotedCell () {
  return mona.between(mona.string('"'),
                      mona.string('"'),
                      mona.text(quotedChar()))
}
function quotedChar () {
  return mona.or(mona.noneOf('"'),
                 mona.and(mona.string('""'),
                          mona.value('"')))
}
parseCSV('foo,"bar"\n"b""az",quux\n')
// => [['foo', 'bar'], ['b"az', 'quux']]

API

mona is a package composed of multiple other packages, re-exported through a single module. You have the option of installing mona from npm directly, or installing any of the subpackages and using those independently.

This API section is organized such that each parser or function is listed under the subpackage it belongs to, along with the name of the npm package you can find it in.

@mona/parse

This module or one of its siblings is needed in order to actually execute defined parsers. Currently, it exports only a single function: a synchronous parser runner.

<a name="mona-parse"></a>> parse(parser, string[, opts]) -> T

Synchronously executes a parser on a given string, and returns the resulting value.

  • {Parser<T>} parser - The parser to execute.
  • {String} string - String to parse.
  • {Opts} [opts] - Options object.
  • {Boolean} [opts.throwOnError=true] - If truthy, throws a ParserError if the parser fails and returns ParserState instead of its value.
  • {String} [opts.fileName] - filename to use for error messages.
parse(token(), 'a') // => 'a'
parse(integer(), '123') // => 123

@mona/parse-async

This module exports only a single function: an asynchronous parser runner. You need this module or something similar in order to actually execute your parsers.

<a name="mona-parseAsync"></a>> parseAsync(parser, callback[, opts]) -> Handle

Executes a parser asynchronously, returning an object that can be used to manage the parser state.

You can feed new data into the parsing process by calling the returned handle's #data() method. Unless the parser given tries to match eof(), parsing will continue until the handle's #done() method is called.

  • {Function} parser - The parser to execute.
  • {AsyncParserCallback} callback - node-style 2-arg callback executed once per successful application of parser.
  • {Object} [opts] - Options object.
  • {String} [opts.fileName] - filename to use for error messages.
var handle = parseAsync(token(), function(tok) {
 console.log('Got a token: ', tok)
})
handle.data('foo')

// logs:
// > Got a token: f
// > Got a token: o
// > Got a token: o

@mona/core

The core parser package contains essential and dev-utility parsers that are intended to be the core of the rest of the parser libraries. Some of these are very low level, such as bind(). Others are not necessarily meant to be used in production, but can help with debugging, such as log().

<a name="mona-value"></a>> value(val) -> Parser<T>

Always succeeds with val as its value, without consuming any input.

  • {T} val - value to use as this parser's value.
parse(value('foo'), '') // => 'foo'

<a name="mona-bind"></a>> bind(parser, fun) -> Parser<U>

Calls fun on the value from parser. Fails without executing fun if parser fails.

  • {Parser<T>} parser - The parser to execute.

  • {Function(Parser<T>) -> Parser<U>} fun - Function called with the resulting value of parser.

parse(bind(token(), function (x) {
  return value(x + '!')
}), 'a') // => 'a!'

<a name="mona-fail"></a>> fail([msg[, type]]) -> Parser<Fail>

Always fails without consuming input. Automatically includes the line and column positions in the final ParserError.

  • {String} [msg='parser error'] - Message to report with the failure.
  • {String} [type='failure'] - A type to apply to the ParserError.

<a name="mona-label"></a>> label(parser, msg) -> Parser<T>

Label a parser failure by replacing its error messages with msg.

  • {Parser<T>} parser - Parser whose errors to replace.
  • {String} msg - Error message to replace errors with.
parse(token(), '') // => unexpected eof
parse(label(token(), 'thing'), '') // => expected thing

<a name="mona-token"></a>> token([count]) -> Parser<String>

Consumes a single item from the input, or fails with an unexpected eof error if there is no input left.

  • {Integer} [count=1] - number of tokens to consume. Must be > 0.
parse(token(), 'a') // => 'a'

<a name="mona-eof"></a>> eof() -> Parser<true>

Succeeds with a value of true if there is no more input to consume.

parse(eof(), '') // => true

<a name="mona-delay"></a>> delay(constructor, ...args) -> Parser<T>

Delays calling of a parser constructor function until parse-time. Useful for recursive parsers that would otherwise blow the stack at construction time.

  • {Function(...T) -> Parser<T>} constructor - A function that returns a Parser.
  • {...T} args - Arguments to apply to the constructor.
// The following would usually result in an infinite loop:
function foo() {
 return or(x(), foo())
}
// But you can use delay() to remedy this...
function foo() {
 return or(x(), delay(foo))
}

<a name="mona-log"></a>>log(parser, label[, level]) -> Parser<T>

Logs the ParserState resulting from parser with a label.

  • {Parser<T>} parser - Parser to wrap.
  • {String} tag - Tag to use when logging messages.
  • {String} [level='log'] - 'log', 'info', 'debug', 'warn', 'error'.

<a name="mona-map"></a>>map(fun, parser) -> Parser<T>

Transforms the resulting value of a successful application of its

View on GitHub
GitHub Stars158
CategoryDevelopment
Updated2mo ago
Forks11

Languages

JavaScript

Security Score

80/100

Audited on Jan 13, 2026

No findings