Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/saiashirwad/parserator/llms.txt

Use this file to discover all available pages before exploring further.

Parsers are composed using combinators - functions that create or combine parsers. Parserator provides a comprehensive set of combinators organized into logical categories.

Character Matching

char

Matches a single specific character.
const char: <T extends string>(ch: T) => Parser<T>
ch
string
required
The character to match (must be a single character)
Example:
const parser = char('a')
parser.run('abc') // Right(['a', {...}])
parser.run('xyz') // Left(error)

string

Matches an exact string in the input.
const string: (str: string) => Parser<string>
str
string
required
The string to match
Example:
const parser = string("hello")
parser.run("hello world") // Right(["hello", {...}])
parser.run("goodbye") // Left(error)

narrowedString

Matches an exact string literal type, preserving the literal type information.
const narrowedString: <const T extends string>(str: T) => Parser<T>
str
string literal
required
The string literal to match
Example:
const parser = narrowedString("hello") // Parser<"hello">
parser.run("hello world") // Right(["hello", {...}])

alphabet

Matches any single alphabetic character (a-z, A-Z).
const alphabet: Parser<string>
Example:
alphabet.run("abc") // Right(["a", {...}])
alphabet.run("123") // Left(error)

digit

Matches any single digit character (0-9).
const digit: Parser<string>
Example:
digit.run("123") // Right(["1", {...}])
digit.run("abc") // Left(error)

anyChar

Matches any single character.
const anyChar: () => Parser<string>
Example:
anyChar().run("hello") // Right(["h", {...}])

notChar

Matches any character except the specified one.
const notChar: (ch: string) => Parser<string>
ch
string
required
The character to exclude (must be a single character)
Example:
const notQuote = notChar('"')
notQuote.parse('a') // Success: 'a'
notQuote.parse('"') // Error

regex

Matches input against a regular expression. The regex must match at the start of the input.
const regex: (re: RegExp) => Parser<string>
re
RegExp
required
The regular expression to match against
Example:
const number = regex(/[0-9]+/)
number.run("123abc") // Right(["123", {...}])

Repetition

many

Matches zero or more occurrences of a parser.
const many: <T>(parser: Parser<T>) => Parser<T[]>
parser
Parser<T>
required
The parser to repeat
Example:
const digits = many(digit)
digits.run("123abc") // Right([["1", "2", "3"], {...}])
digits.run("abc") // Right([[], {...}]) - zero matches is OK

many0

Matches zero or more occurrences (alias for many).
const many0: <S, T>(parser: Parser<T>, separator?: Parser<S>) => Parser<T[]>
parser
Parser<T>
required
The parser to repeat
separator
Parser<S>
Optional separator parser between occurrences

many1

Matches one or more occurrences of a parser.
const many1: <S, T>(parser: Parser<T>, separator?: Parser<S>) => Parser<T[]>
parser
Parser<T>
required
The parser to repeat
separator
Parser<S>
Optional separator parser between occurrences
Example:
const digits = many1(digit)
digits.run("123abc") // Right([["1", "2", "3"], {...}])
digits.run("abc") // Left(error) - at least one required

manyN

Matches at least n occurrences of a parser.
const manyN: <S, T>(parser: Parser<T>, n: number, separator?: Parser<S>) => Parser<T[]>
parser
Parser<T>
required
The parser to repeat
n
number
required
Minimum number of required repetitions
separator
Parser<S>
Optional separator parser between occurrences

manyNExact

Matches exactly n occurrences of a parser.
const manyNExact: <S, T>(par: Parser<T>, n: number, separator?: Parser<S>) => Parser<T[]>
par
Parser<T>
required
The parser to repeat
n
number
required
Exact number of required repetitions
separator
Parser<S>
Optional separator parser between occurrences

count

Parses exactly n occurrences of a parser.
const count: <T>(n: number, par: Parser<T>) => Parser<T[]>
n
number
required
The exact number of occurrences
par
Parser<T>
required
The parser to repeat
Example:
const threeDigits = count(3, digit)
threeDigits.parse("123") // Success: ['1', '2', '3']
threeDigits.parse("12") // Error: not enough matches

skipMany0

Skips zero or more occurrences of a parser without collecting results.
const skipMany0: <T>(parser: Parser<T>) => Parser<undefined>
parser
Parser<T>
required
The parser to skip

skipMany1

Skips one or more occurrences of a parser without collecting results.
const skipMany1: <T>(parser: Parser<T>) => Parser<undefined>
parser
Parser<T>
required
The parser to skip (requires at least one match)

skipManyN

Skips exactly n occurrences of a parser.
const skipManyN: <T>(parser: Parser<T>, n: number) => Parser<undefined>
parser
Parser<T>
required
The parser to skip
n
number
required
Number of required repetitions to skip

Alternatives

or

Tries multiple parsers in order until one succeeds. Supports commit-aware parsing for better error messages.
const or: <Parsers extends Parser<any>[]>(
  ...parsers: Parsers
) => Parser<Parsers[number] extends Parser<infer T> ? T : never>
parsers
Parser<any>[]
required
Array of parsers to try in order
Example:
const value = or(
  numberLiteral,
  stringLiteral,
  booleanLiteral
)
With commit for better errors:
const statement = or(
  parser(function* () {
    yield* keyword("if")
    yield* commit()  // No backtracking after this
    yield* char('(').expect("opening parenthesis")
    // ...
  }),
  whileStatement,
  assignment
)

optional

Makes a parser optional. Returns undefined if the parser fails.
const optional: <T>(parser: Parser<T>) => Parser<T | undefined>
parser
Parser<T>
required
The parser to make optional
Example:
const sign = optional(char('-'))
sign.run('-5') // Right(['-', {...}])
sign.run('5') // Right([undefined, {...}])

Sequences

sequence

Runs multiple parsers in sequence and returns all results as a tuple.
const sequence: <const T extends any[]>(
  parsers: T
) => Parser<SequenceOutput<T>>
parsers
Parser[]
required
Array of parsers to run in sequence
Example:
const parser = sequence([digit, char('-'), digit])
parser.run('1-2') // Right([['1', '-', '2'], {...}])

sepBy

Matches zero or more occurrences of elements separated by a separator.
const sepBy: <S, T>(parser: Parser<T>, sepParser: Parser<S>) => Parser<T[]>
parser
Parser<T>
required
Parser for the elements
sepParser
Parser<S>
required
Parser for the separator between elements
Example:
const parser = sepBy(digit, char(','))
parser.run("1,2,3") // Right([["1", "2", "3"], {...}])
parser.run("") // Right([[], {...}])

sepBy1

Matches one or more occurrences separated by a separator. Requires at least one match.
const sepBy1: <S, T>(par: Parser<T>, sepParser: Parser<S>) => Parser<T[]>
par
Parser<T>
required
Parser for the elements
sepParser
Parser<S>
required
Parser for the separator
Example:
const numbers = sepBy1(number, char(','))
numbers.parse("1,2,3") // Success: [1, 2, 3]
numbers.parse("") // Error: Expected at least one element

sepEndBy

Parses a list with optional trailing separator.
const sepEndBy: <S, T>(par: Parser<T>, sep: Parser<S>) => Parser<T[]>
par
Parser<T>
required
Parser for list elements
sep
Parser<S>
required
Parser for separators
Example:
const list = sepEndBy(number, char(','))
list.parse("1,2,3") // Success: [1, 2, 3]
list.parse("1,2,3,") // Success: [1, 2, 3] (trailing comma OK)

between

Matches content between two delimiters.
const between: <T>(
  start: Parser<any>,
  end: Parser<any>,
  par: Parser<T>
) => Parser<T>
start
Parser<any>
required
Opening delimiter parser
end
Parser<any>
required
Closing delimiter parser
par
Parser<T>
required
Parser for content between delimiters
Example:
const parser = between(char('('), char(')'), digit)
parser.run('(5)') // Right(['5', {...}])
parser.run('5') // Left(error)

zip

Runs two parsers in sequence and returns both results as a tuple.
const zip: <A, B>(parserA: Parser<A>, parserB: Parser<B>) => Parser<[A, B]>
parserA
Parser<A>
required
First parser
parserB
Parser<B>
required
Second parser

then / zipRight

Runs two parsers in sequence, keeping only the second result.
const then: <A, B>(parserA: Parser<A>, parserB: Parser<B>) => Parser<B>
const zipRight: <A, B>(parserA: Parser<A>, parserB: Parser<B>) => Parser<B>
parserA
Parser<A>
required
First parser (result discarded)
parserB
Parser<B>
required
Second parser (result kept)

thenDiscard / zipLeft

Runs two parsers in sequence, keeping only the first result.
const thenDiscard: <A, B>(parserA: Parser<A>, parserB: Parser<B>) => Parser<A>
const zipLeft: <A, B>(parserA: Parser<A>, parserB: Parser<B>) => Parser<A>
parserA
Parser<A>
required
First parser (result kept)
parserB
Parser<B>
required
Second parser (result discarded)

Lookahead

lookahead

Looks ahead in the input without consuming any input.
const lookahead: <T>(par: Parser<T>) => Parser<T | undefined>
par
Parser<T>
required
The parser to look ahead with
Example:
const parser = lookahead(char('a'))
parser.run('abc') // Right(['a', {...}])
// Input position remains at 'abc', 'a' is not consumed

notFollowedBy

Succeeds only if the given parser fails to match.
const notFollowedBy: <T>(par: Parser<T>) => Parser<boolean>
par
Parser<T>
required
The parser that should not match
Example:
const notA = notFollowedBy(char('a'))
notA.run('bcd') // Right([true, {...}]) - Succeeds because 'a' is not found
notA.run('abc') // Left(error) - Fails because 'a' is found

Control Flow

commit / cut

Commits to the current parsing path, preventing backtracking. After calling commit(), if parsing fails, the parser won’t try alternatives in or combinators.
const commit: () => Parser<void>
const cut: () => Parser<void>  // Alias using Prolog-style naming
Example:
const ifStatement = parser(function* () {
  yield* keyword("if")
  yield* commit()  // No backtracking after this point
  yield* char('(').expect("opening parenthesis after 'if'")
  const condition = yield* expression
  yield* char(')').expect("closing parenthesis")
  const body = yield* block
  return { type: "if", condition, body }
})

atomic

Creates an atomic parser that either fully succeeds or resets to the original state.
const atomic: <T>(parser: Parser<T>) => Parser<T>
parser
Parser<T>
required
The parser to make atomic
Example:
const functionCall = atomic(
  parser(function* () {
    const name = yield* identifier
    yield* char('(')
    const args = yield* sepBy(expression, char(','))
    yield* char(')')
    return { name, args }
  })
)

Utilities

skipUntil

Skips input until the given parser succeeds.
const skipUntil: <T>(parser: Parser<T>) => Parser<undefined>
parser
Parser<T>
required
The parser to look for

takeUntil

Takes input until the given parser succeeds.
const takeUntil: <T>(parser: Parser<T>) => Parser<string>
parser
Parser<T>
required
The parser to look for

takeUpto

Takes input until the given parser would succeed, without consuming the parser.
const takeUpto: <T>(parser: Parser<T>) => Parser<string>
parser
Parser<T>
required
The parser to look for (not consumed)

parseUntilChar

Takes input until the given character is found.
const parseUntilChar: (char: string) => Parser<string>
char
string
required
The character to look for
Example:
const untilQuote = parseUntilChar('"')
untilQuote.run('hello"world') // Right(['hello', {...}])

skipSpaces

Skips any number of space characters.
const skipSpaces: Parser<undefined>
Example:
skipSpaces.run('   hello') // Right([undefined, {...}]) - positioned at 'hello'

eof

Succeeds only at the end of input.
const eof: Parser<void>
Example:
const parser = string("hello").then(eof)
parser.parse("hello") // Success
parser.parse("hello world") // Error: Expected end of input

position

Returns the current source position.
const position: Parser<SourcePosition>
Example:
const pos = yield* position
// pos: { offset: number, line: number, column: number }