https://github.com/brundonsmith/monch
A tasty TypeScript parser-combinators library
https://github.com/brundonsmith/monch
deno nodejs parser-combinators parsing typescript
Last synced: 10 months ago
JSON representation
A tasty TypeScript parser-combinators library
- Host: GitHub
- URL: https://github.com/brundonsmith/monch
- Owner: brundonsmith
- Created: 2023-04-30T19:55:34.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2023-05-05T22:11:44.000Z (about 3 years ago)
- Last Synced: 2025-08-16T23:52:57.369Z (10 months ago)
- Topics: deno, nodejs, parser-combinators, parsing, typescript
- Language: TypeScript
- Homepage:
- Size: 16.6 KB
- Stars: 10
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Monch
A tasty TypeScript parser-combinator library, inspired by Rust's
[nom crate](https://github.com/rust-bakery/nom)
## Features
- Small and practical (but easy to extend!)
- Zero dependencies
- Rich type inference for parsed value types and error types
- Works on Node, Deno, Bun, and even the browser
## Installation
```
npm install monch-parse
```
or
```
import { } from 'https://deno.land/x/monch@v1.0.2/index.ts'
```
## Usage
```typescript
// JSON parser
const nil = map(
exact('null'),
() => null
)
const boolean = map(
oneOf(
exact('true'),
exact('false')
),
s => s === 'true'
)
const number = map(
tuple(
take1(numericChar),
optional(
tuple(
exact("."),
required(take1(numericChar), () => `Expected numbers after decimal point`)
)
),
),
([front, back]) => {
let numberString = front
if (back != null) {
const [_decimal, fractionDigits] = back
numberString += `.${fractionDigits}`
}
return Number(numberString)
}
)
const string = map(
tuple(
exact('"'),
take0(filter(char, ch => ch !== '"')),
required(exact('"'), () => `Expected closing quote '"'`)
),
([_0, contents, _1]) => contents
)
const commaWithWhitespace = tuple(
whitespace,
exact(','),
whitespace
)
const array: Parser = input => map(
tuple(
exact('['),
whitespace,
manySep0(
jsonValue,
commaWithWhitespace
),
whitespace,
required(exact(']'), () => `Expected closing bracket ']'`)
),
([_0, _1, elements, _2, _3]) => elements
)(input)
const object: Parser, string> = input => map(
tuple(
exact('{'),
whitespace,
manySep0(
map(
tuple(
string,
whitespace,
required(exact(':'), () => `Expected ':' after object key`),
whitespace,
required(jsonValue, () => `Expected value after ':'`)
),
([key, _0, _1, _2, value]) => [key, value] as const
),
commaWithWhitespace
),
whitespace,
required(exact('}'), () => `Expected closing curly brace '}'`)
),
([_0, _1, entries, _2, _3]) => Object.fromEntries(entries)
)(input)
const jsonValue: Parser = input => oneOf(
nil,
boolean,
number,
string,
array,
object
)(input)
```
```typescript
// Calling the parser
const json = {
"foo": "bar",
"blah": 123.4,
"stuff": true,
"other": [
1,
2,
null,
false
]
}
const jsonString = JSON.stringify(json)
const parserInput = input(jsonString)
assertEquals(
jsonValue(parserInput),
{
kind: 'success',
input: { code: jsonString, index: jsonString.length },
src: { code: jsonString, start: 0, end: jsonString.length },
parsed: json
}
)
```