0.6.6 • Published 9 months ago

extra-parser v0.6.6

Weekly downloads
-
License
MIT
Repository
github
Last release
9 months ago

extra-parser

A functional parser toolkit.

Install

npm install --save extra-parser
# or
yarn add extra-parser

FAQ

Why are functions asynchronous?

Some parsers make heavy use of recursion, and most JavaScript engines do not support tail-call optimization, which leads to the possibility of stack overflow in programs.

Asynchronous functions are an escape route: developers can change recursive functions to asynchronous recursive functions to get their programs out of stack overflow problems without significantly reducing readability.

API

interface IToken {
  tokenType: string
  value: string
}

interface INode {
  nodeType: string
}

interface ITokenPatternMatch<Token extends IToken> {
  consumed: number
  token: Token
}

interface INodePatternMatch<Node extends INode> {
  consumed: number
  node: Node
}

interface ITokenPattern<Token extends IToken = IToken> {
  (text: string): Awaitable<ITokenPatternMatch<Token> | Falsy>
}

interface INodePattern<Token extends IToken = IToken, Node extends INode = INode> {
  (tokens: ReadonlyArray<Token>): Awaitable<INodePatternMatch<Node> | Falsy>
}

type MapSequenceToPatterns<
  Sequence extends ReadonlyArray<Token | Node>
, Token extends IToken = IToken
, Node extends INode = INode
> = {
  [Index in keyof Sequence]:
    [Sequence[Index]] extends [infer TokenOrNode]
  ? (
      TokenOrNode extends Token
      ? string
    : TokenOrNode extends Node
      ? INodePattern<Token, TokenOrNode>
    : never
    )
  : never
}

type MapSequenceToMatches<
  Sequence extends ReadonlyArray<Token | Node>
, Token extends IToken = IToken
, Node extends INode = INode
> = {
  [Index in keyof Sequence]:
    [Sequence[Index]] extends [infer TokenOrNode]
  ? (
      TokenOrNode extends IToken
      ? Token
    : TokenOrNode extends INode
      ? INodePatternMatch<TokenOrNode>
    : never
    )
  : never
}

tokenize

function tokenize<Token extends IToken = IToken>(
  patterns: Array<ITokenPattern<Token>>
, text: string
): AsyncIterableIterator<Token>

parse

function parse<Token extends IToken = IToken, Node extends INode = INode>(
  patterns: Array<INodePattern<Token, Node>>
, tokens: Token[]
): AsyncIterableIterator<Node>

consumeNode

function consumeNode<
  Token extends IToken = IToken
, Node extends INode = INode
>(
  nodePattern: INodePattern<Token, Node>
, tokens: Token[]
): Promise<INodePatternMatch<Node> | Falsy>

consumeToken

function consumeToken<Token extends IToken = IToken>(
  tokenType: string
, tokens: Token[]
): Token | Falsy

matchAnyOf

function matchAnyOf<
  Token extends IToken = IToken
, Node extends INode = INode
>(
  nodePatterns: ReadonlyArray<INodePattern<Token, Node>>
, tokens: ReadonlyArray<Token>
): Promise<INodePatternMatch<Node> | Falsy>

matchSequence

function matchSequence<
  Sequence extends ReadonlyArray<Token | Node>
, Token extends IToken = IToken
, Node extends INode = INode
>(
  patterns: MapSequenceToPatterns<Sequence, Token, Node>
, tokens: ReadonlyArray<Token>
): Promise<MapSequenceToMatches<Sequence, Token, Node> | Falsy>

matchRepetitions

function matchRepetitions<
  Sequence extends ReadonlyArray<Token | Node>
, Token extends IToken = IToken
, Node extends INode = INode
>(
  patterns: MapSequenceToPatterns<Sequence, Token, Node>
, tokens: ReadonlyArray<Token>
, options?: {
    minimumRepetitions?: number = 1
    maximumRepetitions?: number = Infinity
  }
): Promise<Array<Token | INodePatternMatch<Node>> | Falsy>

createTokenPatternFromRegExp

function createTokenPatternFromRegExp<Token extends IToken>(
  tokenType: Token['tokenType']
, regExp: RegExp
): ITokenPattern<IToken>

createUnaryOperatorExpressionNodePattern

interface IUnaryOperatorExpressionNode<
  NodeType extends string
, RightNode extends INode
> extends INode {
  nodeType: NodeType
  right: RightNode
}

function createUnaryOperatorExpressionNodePattern<
  Token extends IToken
, Node extends IUnaryOperatorExpressionNode<string, RightNode>
, RightNode extends INode
>(params: {
  nodeType: Node['nodeType']
  leftTokenType: string
  rightNodePattern: INodePattern<Token, RightNode>
}): INodePattern<
  Token
, IUnaryOperatorExpressionNode<Node['nodeType'], Node['right']>
>

createBinaryOperatorExpressionNodePattern

interface IBinaryOperatorExpressionNode<
  NodeType extends string
, LeftNode extends INode
, RightNode extends INode
> extends INode {
  nodeType: NodeType
  left: LeftNode
  right: RightNode
}

function createBinaryOperatorExpressionNodePattern<
  Token extends IToken
, Node extends IBinaryOperatorExpressionNode<string, LeftNode, RightNode>
, LeftNode extends INode
, RightNode extends INode
>(params: {
  nodeType: Node['nodeType']
  centerTokenType: string
  leftNodePattern: INodePattern<Token, LeftNode>
  rightNodePattern: INodePattern<Token, RightNode>
}): INodePattern<
  Token
, IBinaryOperatorExpressionNode<Node['nodeType'], Node['left'], Node['right']>
>

createGroupedExpressionNodePattern

function createGroupedExpressionNodePattern<
  Token extends IToken
, CenterNode extends INode
>(params: {
  leftTokenType: string
  rightTokenType: string
  centerNodePattern: INodePattern<Token, CenterNode>
}): INodePattern<Token, CenterNode>

createValueExpressionNodePattern

interface IValueExpressionNode<
  NodeType extends string
, Value
> extends INode {
  nodeType: NodeType
  value: Value
}

function createValueExpressionNodePattern<
  Token extends IToken
, Node extends IValueExpressionNode<string, Value>
, Value
>(params: {
  nodeType: Node['nodeType']
  valueTokenType: string
  transformValue: (value: string) => Value
}): INodePattern<Token, IValueExpressionNode<Node['nodeType'], Node['value']>>
0.6.6

9 months ago

0.6.5

9 months ago

0.6.4

11 months ago

0.6.3

1 year ago

0.6.2

1 year ago

0.6.1

1 year ago

0.6.0

1 year ago

0.5.0

1 year ago

0.4.0

1 year ago

0.3.0

1 year ago

0.2.5

1 year ago

0.2.4

1 year ago

0.2.3

1 year ago

0.2.2

1 year ago

0.2.1

1 year ago

0.2.0

2 years ago

0.1.0

2 years ago