From e80cae365d00298859d8557c83dc88e038443b84 Mon Sep 17 00:00:00 2001 From: Vladislav Mamon Date: Mon, 15 Nov 2021 16:29:24 +0500 Subject: [PATCH] docs(readme): add `installation` and `example` sections --- .prettierignore | 3 ++ README.md | 129 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 129 insertions(+), 3 deletions(-) diff --git a/.prettierignore b/.prettierignore index 9c62828..9d71e0b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,6 @@ node_modules coverage dist + +# Ignore Markdown at the root. +/*.md diff --git a/README.md b/README.md index 1a157d9..41465d1 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,138 @@ -# ⑉ sigma +# `𝝨` sigma [![Build/Test](https://img.shields.io/github/workflow/status/norskeld/sigma/test?style=flat&colorA=black)](https://github.com/norskeld/sigma/actions) [![Coverage](https://img.shields.io/coveralls/github/norskeld/sigma?style=flat&colorA=black)](https://coveralls.io/github/norskeld/sigma) [![NPM](https://img.shields.io/npm/v/@nrsk/sigma?style=flat&colorA=black&colorB=CC3534)](https://npm.im/@nrsk/sigma) [![Semantic Release](https://img.shields.io/badge/semantic_release-black)](https://github.com/semantic-release/semantic-release) -> TypeScript [parser combinator] library for building fast and convenient parsers. Best suited for parsing \*[BNF]-like grammars. +TypeScript [parser combinator] library for building fast and convenient parsers. + +## Note + +> This library is still in active development, and although it can already parse complex stuff and +> in fact do that *orders of magnitude* faster than some other parser combinator libraries, it still +> lacks Unicode support, common parsers and documentation. + +## Installation + +Just use your favorite package manager! + +```bash +npm i @nrsk/sigma +``` + +## Example + +Below is an example of parsing nested tuples like `(1, 2, (3, 4))` into an AST. + +```ts +import { choice, defer, list, map, opt, regexp, string, tmid } from '@nrsk/sigma/combinators' +import { run } from '@nrsk/sigma' + +/* AST. */ + +interface NumberNode { + type: 'number' + value: number +} + +interface ListNode { + type: 'list' + value: Array +} + +/* Mapping functions to turn parsed string values into AST nodes. */ + +function toNumber(value: string): NumberNode { + return { + type: 'number', + value: +value + } +} + +function toList(value: Array): ListNode { + return { + type: 'list', + value + } +} + +/* Parsers. */ + +// Non-Terminals. +const Space = regexp(/\s+/g, 'whitespace') +const Integer = regexp(/\d+/g, 'integer') + +// Terminals. +const OperParen = string('(') +const CloseParen = string(')') +const Comma = tmid(opt(Space), string(','), opt(Space)) + +// Composites. Deferred initialization allows us to use recursion and mutual calls between parsers. +const TupleNumber = defer() +const TupleElement = defer() +const TupleList = defer() + +TupleNumber.with( + map( + Integer, + toNumber + ) +) + +TupleElement.with( + choice( + TupleList, + TupleNumber + ) +) + +TupleList.with( + map( + tmid( + OperParen, + list(TupleElement, Comma), + CloseParen + ), + toList + ) +) +``` + +Then we simply `.run` the root parser, feeding it `.with` text: + +```ts +> run(TupleList).with('(1, 2, (3, 4))') +``` + +And in the end we get the following output with the AST, which can then be manipulated if needed: + +```ts +{ + kind: 'success', + state: { + input: '(1, 2, (3, 4))', + index: 14 + }, + value: { + type: 'list', + value: [ + { type: 'number', value: 1 }, + { type: 'number', value: 2 }, + { + type: 'list', + value: [ + { type: 'number', value: 3 }, + { type: 'number', value: 4 } + ] + } + ] + } +} +``` ## License [MIT](LICENSE). [parser combinator]: https://en.wikipedia.org/wiki/Parser_combinator -[bnf]: https://en.wikipedia.org/wiki/Backus-Naur_form