Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ryohey/tspc

A Strongly-typed parser combinator written in TypeScript.
https://github.com/ryohey/tspc

parser parser-combinators typescript

Last synced: 4 months ago
JSON representation

A Strongly-typed parser combinator written in TypeScript.

Awesome Lists containing this project

README

        

# tspc

A Strongly-typed parser combinator written in TypeScript, heavily inspired by [fnparse.js](https://github.com/anatoo/fnparse.js).

## Installation

```sh
npm install tspc
```

## Example

```ts
const part = map(many(num), (arr) => parseInt(arr.join("")))
const ipString = seq(part, token("."), part, token("."), part, token("."), part)
const ipParser = map(ipString, ([a, _, b, __, c, ___, d]) => [a, b, c, d])
ipParser("192.168.0.1", 0).value // [192, 168, 0, 1]
```

## What is tspc

It is a simple and very flexible parser combinator, capable of converting parsed results not only to strings, but also to complex arrays and objects.

```ts
// Parse hex color or color name
// returns color value in number
const parser = or(
map(seq(token("#"), map(regexp(/[0-9a-f]/), str => parseInt(str, 16)), arr => arr[1]),
map(token("red"), () => 0xff0000)
)
parser("#c0ffee", 0).value // 0xc0ffee
parser("red", 0).value // 0xff0000
parser("hello", 0).success // false
console.log(parser("hello", 0).error) // prints parsing error
```

## Strongly Typed

Careful design ensures that type information is kept complete, so even complex parsers can automatically determine the type of the result.

```ts
const attr = (name: string) =>
map(
seq(token(name), token('="'), regexp(/[a-zA-Z0-9]/), token('"')), // Parser
(result) => ({ [name]: result[2] })
) // Parser
const aTagParser = map(
seq(token("")), // Parser"]>
(result) => ({
tagName: name,
attributes: result[1],
})
) // Parser
```

## Generic

Parser input is not limited to strings. Any type that can represent the parse position numerically, such as an array of numbers, can be used.

```ts
const
```

## Core API

### Parser

The type for parser functions. Parser takes a input and the reading position.

```ts
type Parser = (target: T, position: number) => Result

type Result =
| {
success: true
position: number
value: T
}
| {
success: false
position: number
error: string
}
```

### `or`

Parser that succeeds if any of the given parsers succeeds.

```ts
const bit = or(token("0"), token("1"))
```

### `many`

Parser that iterates until the given parser fails and returns as an array.

```ts
const binary = many(bit) // Parser
```

### `seq`

Returns Parser from the sequence of Parsers.

```ts
const parser = seq(token("0b"), binary)
```

### `map`

Convert the result of the given parser.

```ts
const parser = map(binary, (str) => parseInt(str, 2)) // Parser
```

### `opt`

Parser that returns a given parser as a success even if it fails. The value will be nullable.

```ts
const parser = seq(token("http"), opt("s"), token("://")) // Parser
```

### `vec`

Repeats the given parser a specified number of times. Unlike `many`, if parsing fails before the specified number of times, it fails.

```ts
const byte = vec(bit, 8)
```

### `seqMap`

Parser that generates and applies a parser from the results of a given parser.

```ts
// Parser that reads the remaining byte sequence for the number read in the first byte
const parser = seqMap(byte, (size) => vec(byte, size))
```

### `transform`

Parser that passes the result of the first parser as input to the second parser.

```ts
const parser = transform(byteToStringParser, jsonParser)
```

### `lazy`

Parser that returns the parser generated by the given closure. Typically used to create a recursive parser.

### `fail`

Parser that always fails.

### `pass`

Parser that always succeeds.

### `terminate`

Parser that always succeeds. Unlike `pass`, it does not advance the position.

## String API

### `token`

Parser that succeeds if it matches the given string.

```ts
const parser = token("hello")
parser("hello, world!", 0).value // "hello"
```

### `regexp`

Parser that succeeds if it matches the given regular expression.

```ts
const parser = regexp(/[a-zA-Z]+/)
parser("hello, world!", 0).value // "hello"
```

### `num`

Parser matching a single numeric character.

```ts
num("31415") // "3"
```

### `uint`

Parser to match positive decimal integers. Results are number.

```ts
uint("926535").value // 926535
```

### `int`

Parser to match decimal integers. Results are number.

```ts
int("-12345").value // -12345
```