bite.parsers module

class bite.parsers.ParseError[source]

Bases: Exception

Base class for errors resulting from input that fails to parse.

class bite.parsers.TrailingBytesError[source]

Bases: ParseError

Error raised when the whole input is expected to be consumed by a parser, but trailing bytes where found.

class bite.parsers.UnmetExpectationError(expected: Parser, at_loc: int, buf: ParserBuffer)[source]

Bases: ParseError

Error raised when the input does not match the syntax expected by a parser.

class bite.parsers.And(parsers: Iterable[Parser], *, name: str | None = None)[source]

Apply multiple parsers in sequence.

Each parser must be able to parse the input when applied in sequence.

Parameters:
  • parsers – Parser to apply in sequence.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import And, Literal, parse_bytes

print(asyncio.run(parse_bytes(And([Literal(b'a'), Literal(b'b')]), b'ab')).values)
(b'a', b'b')
async parse(buf: ParserBuffer, loc: int = 0) ParsedList[Any, Any][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.CaselessLiteral(literal: bytes, *, name: str | None = None)[source]

Parses a case-insensitive sequence of bytes.

The literal passed to the CaselessLiteral constructor will be treated as the canconical form, i.e. the value returned from the parse tree node.

Parameters:
  • literal – The canonical form of the bytes to match.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import CaselessLiteral, parse_bytes

print(asyncio.run(parse_bytes(CaselessLiteral(b'abc'), b'AbC')).values)
(b'abc',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedLeaf[bytes][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.CharacterSet(charset: Iterable[int], *, invert: bool = False, name: str | None = None)[source]

Parses a single byte from a given set.

Note

Besides listing each byte in the set explicitly (e.g. b'abc'), you can define a range using something like bytes(range(0x7F, 0x9F + 1)). It is also possible to combine both forms: b'abc' + bytes(range(0x7F, 0x9F + 1)).

Parameters:
  • charset – The set of bytes parsed by this parser.

  • invert – Set to true to match all bytes not given by the charset.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import CharacterSet, parse_bytes

print(asyncio.run(parse_bytes(CharacterSet(b'abc'), b'b')).values)
(b'b',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedLeaf[bytes][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.Combine(parser: Parser[Any, bytes], *, name: str | None = None)[source]

Combine parse tree leaves into a single node.

This parser is helpful to obtain a single byte string when using multiple parsers producing individual segments of this byte string.

Parameters:
  • parser – Parser to obtain the individual segments to combine.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import CharacterSet, Combine, parse_bytes

digits = CharacterSet(b'0123456789')[1, ...]
integer = Combine(digits)

print(asyncio.run(parse_bytes(digits, b'12345')).values)
print(asyncio.run(parse_bytes(integer, b'12345')).values)
(b'1', b'2', b'3', b'4', b'5')
(b'12345',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedLeaf[bytes][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.Counted(count_parser: Parser[Any, int], counted_parser_factory: Callable[[int], Parser[Any, V]], *, name: str | None = None)[source]

Read a count and create a parser from it.

Parameters:
  • count_parser – Parser to read the count. The resulting parse tree must return a single value that can be converted to an int.

  • counted_parser_factory – Callable that gets passed the count and returns a parser that is used to parse the subsequent bytes.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import CharacterSet, Counted, FixedByteCount, parse_bytes

print(asyncio.run(parse_bytes(
    Counted(
        CharacterSet(b'012345689'),
        lambda count: FixedByteCount(count)
    ),
    b'3abcde'
)).values)
(b'abc',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedCounted[V][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.CountedParseTree(count_expr: ParsedNode[Any, int], counted_expr: ParsedNode)[source]

Parse tree children created by the Counted parser.

count_expr: ParsedNode[Any, int][source]

Parse tree of the count expression.

counted_expr: ParsedNode[source]

Parse tree of the expressions counted by the count expression.

property end_loc: int[source]

End index (exclusive) into the input buffer of the segmend parsed by the node.

property start_loc: int[source]

Start index into the input buffer of the segmend parsed by the node.

class bite.parsers.FixedByteCount(count: int, *, name: str | None = None)[source]

Parses a fixed number of bytes.

Parameters:
  • count – How many bytes to read.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import FixedByteCount, parse_bytes

print(asyncio.run(parse_bytes(FixedByteCount(3), b'01234567890')).values)
(b'012',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedLeaf[bytes][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.Forward(*, name: str | None = None)[source]

Forward declaration allowing the definition of recursive rules.

Use the assign() method to set the actual parser definition.

Warning

Rules must not be left-recursive. Otherwise, the parser will recursively call itself causing a stack overflow.

Parameters:

name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import Forward, Literal, Opt, parse_bytes

expr = Forward()
expr.assign(Literal(b'[') + Opt(expr) + Literal(b']'))

print(asyncio.run(parse_bytes(expr, b'[[]]')).values)
(b'[', b'[', b']', b']')
assign(parser: Parser[T, V])[source]

Assign a concrete parser to the forward declaration.

async parse(buf: ParserBuffer, loc: int = 0) ParsedNode[T, V][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

parser: Parser[T, V] | None[source]
class bite.parsers.Literal(literal: bytes, *, name: str | None = None)[source]

Parses an exact sequence of bytes.

Parameters:
  • literal – The bytes to match.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import Literal, parse_bytes

print(asyncio.run(parse_bytes(Literal(b'abc'), b'abc')).values)
(b'abc',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedLeaf[bytes][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.MatchFirst(choices: Iterable[Parser], *, name: str | None = None)[source]

Apply the first parser that succeeds parsing the input.

Parameters:
  • choices – Parsers to try in the given order until one succeeds parsing the input.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import Literal, MatchFirst, parse_bytes

print(asyncio.run(parse_bytes(
    MatchFirst([Literal(b'a'), Literal(b'b'), Literal(b'bb')]),
    b'bb'
)).values)
(b'b',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedMatchFirst[source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.Not(parser: Parser[Any, Any], *, name: str | None = None)[source]

Negative look-ahead.

This parser does not consume any input bytes, but will only succeed parsing if the following input bytes are not parsed by the given parser.

Parameters:
  • parser – Parser that is supposed to not match the input.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import FixedByteCount, Literal, Not, parse_bytes

expr = Not(Literal(b'a')) + FixedByteCount(1)

print(asyncio.run(parse_bytes(expr, b'b')).values)
(b'b',)
asyncio.run(parse_bytes(expr, b'a'))
Traceback (most recent call last):
    ...
bite.parsers.UnmetExpectationError: expected Not(b'a') at position 0
async parse(buf: ParserBuffer, loc: int = 0) ParsedNil[source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.OneOrMore(parser: Parser[T, V], *, name: str | None = None)[source]

Require a parser to apply one or more times.

This is parser is equivalent to the Repeat parser with min_repeats=1.

Parameters:
  • parser – Parser for a single application.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import Literal, OneOrMore, parse_bytes

asyncio.run(parse_bytes(OneOrMore(Literal(b'a')), b''))
Traceback (most recent call last):
    ...
bite.parsers.UnmetExpectationError: expected b'a' at position 0
print(asyncio.run(parse_bytes(OneOrMore(Literal(b'a')), b'a')).values)
print(asyncio.run(parse_bytes(OneOrMore(Literal(b'a')), b'aaa')).values)
(b'a',)
(b'a', b'a', b'a')
async parse(buf: ParserBuffer, loc: int = 0) ParsedList[source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.Opt(parser: Parser[T, V], *, name: str | None = None)[source]

Make a parser optional.

This is parser is equivalent to the Repeat parser with min_repeats=0 and max_repeats=1.

Parameters:
  • parser – Parser to apply optionally.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import Literal, Opt, parse_bytes

print(asyncio.run(parse_bytes(Opt(Literal(b'a')), b'')).values)
print(asyncio.run(parse_bytes(Opt(Literal(b'a')), b'a')).values)
()
(b'a',)
async parse(buf: ParserBuffer, loc: int = 0) ParsedList[source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.ParsedBaseNode(name: str | None, parse_tree: T)[source]

Implementation of common fields to all parse tree nodes.

name: str | None[source]

Name of the node.

parse_tree: T[source]

Children of the node.

class bite.parsers.ParsedCounted(name: str | None, parse_tree: bite.parsers.CountedParseTree)[source]
property end_loc: int[source]

End index (exclusive) into the input buffer of the segmend parsed by the node.

name: str | None[source]

Name of the node.

parse_tree: CountedParseTree[source]

Children of the node.

property start_loc: int[source]

Start index into the input buffer of the segmend parsed by the node.

property values: Iterable[V][source]

Values of the CountedParseTree.counted_expr of the parse_tree.

class bite.parsers.ParsedLeaf(name: str | None, parse_tree: T, start_loc: int, end_loc: int)[source]

A leaf node in a parse tree.

end_loc: int[source]

End index (exclusive) into the input buffer of the segmend parsed by the node.

name: str | None[source]

Name of the node.

parse_tree: T[source]

Children of the node.

start_loc: int[source]

Start index into the input buffer of the segmend parsed by the node.

property values: Tuple[T][source]

Value of the node.

Returns:

A single element tuple with the parse_tree.

class bite.parsers.ParsedList(name: str | None, parse_tree: T, loc: int)[source]
property end_loc: int[source]

End index (exclusive) into the input buffer of the segmend parsed by the node. Will be equal to start_loc if the parsed list is empty.

loc: int[source]

Index into the input buffer of the location where this parsed expression starts.

name: str | None[source]

Name of the node.

parse_tree: T[source]

Children of the node.

property start_loc: int[source]

Start index into the input buffer of the segmend parsed by the node.

property values: Tuple[V, ...][source]

Values of the children of this parse tree node.

class bite.parsers.ParsedMatchFirst(name: str | None, parse_tree: T, choice_index: int)[source]
choice_index: int[source]

Index into MatchFirst.parsers of the parsed variant.

property end_loc: int[source]

End index (exclusive) into the input buffer of the segmend parsed by the node.

name: str | None[source]

Name of the node.

parse_tree: T[source]

Children of the node.

property start_loc: int[source]

Start index into the input buffer of the segmend parsed by the node.

property values: Iterable[V][source]

Values of the parsed child nodes.

class bite.parsers.ParsedNil(name: str | None, loc: int)[source]

A leaf node in a parse tree representing a zero-length segment.

Such zero-length segments can be generated by look-aheads which do not actually consume any input.

property end_loc: int[source]

End index (exclusive) into the input buffer of the segmend parsed by the node. Will always be equal to start_loc.

loc: int[source]

Index into the input buffer to where the node was generated.

name: str | None[source]

Name of the node.

property parse_tree: None[source]

Children of the node. Will always return None.

property start_loc: int[source]

Start index into the input buffer of the segmend parsed by the node.

property values: Tuple[source]

Value of the node. Will always return the empty tuple ().

class bite.parsers.ParsedNode(*args, **kwargs)[source]

A single node in a parse tree.

property end_loc: int[source]

End index (exclusive) into the input buffer of the segmend parsed by the node.

property name: str | None[source]

Name of the node.

property parse_tree: T_co[source]

Children of the node.

property start_loc: int[source]

Start index into the input buffer of the segmend parsed by the node.

property values: Iterable[V][source]

Value of the node.

By default this will be a single element tuple with a bytes object for the parse tree leaves and a flattened list of the children’s values for other nodes. However, it can be overridden to produce any other type.

bite.parsers.ParsedOneOrMore[source]

alias of ParsedList

bite.parsers.ParsedOpt[source]

alias of ParsedList

bite.parsers.ParsedRepeat[source]

alias of ParsedList

bite.parsers.ParsedZeroOrMore[source]

alias of ParsedList

class bite.parsers.Parser(name=None)[source]

Abstract base class for parsers.

Implementors must at least override the parse() method.

The following operator implementations are provided:

  • + (And): Apply parsers in sequence.

  • | (MatchFirst): Apply the first parser that succeeds parsing the input.

  • ~ (Not): Negative look-ahead.

  • [x, y] (Repeat): Apply a parser repeatedly. `` x`` must be a non-negative integer. y must be either a positive integer or the ellipsis ... to allow for unlimited repetitions.

Parameters:

name – Name to assign to the resulting parse tree node.

async parse(buf: ParserBuffer, loc: int = 0) ParsedNode[T, V][source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.Repeat(parser: Parser[T, V], min_repeats: int = 0, max_repeats: int | None = None, *, name: str | None = None)[source]

Apply a parser repeatedly.

Parameters:
  • parser – Parser to apply repeatedly.

  • min_repeats – Minimun number of applications of the parser.

  • max_repeats – Maximum number of applications of the parser. If None, infinitly many applications are allowed.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import Literal, parse_bytes, Repeat

repeat = Repeat(Literal(b'a'), min_repeats=1, max_repeats=2)

print(asyncio.run(parse_bytes(repeat, b'')).values)
Traceback (most recent call last):
    ...
bite.parsers.UnmetExpectationError: expected b'a' at position 0
print(asyncio.run(parse_bytes(repeat, b'a')).values)
(b'a',)
print(asyncio.run(parse_bytes(repeat, b'aa')).values)
(b'a', b'a')
print(asyncio.run(parse_bytes(repeat, b'aaa')).values)
(b'a', b'a')
async parse(buf: ParserBuffer, loc: int = 0) ParsedList[source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202:

class bite.parsers.ZeroOrMore(parser: Parser[T, V], *, name: str | None = None)[source]

Require a parser to apply zero or more times.

This is parser is equivalent to the Repeat parser with min_repeats=0.

Parameters:
  • parser – Parser for a single application.

  • name – Name to assign to the resulting parse tree node.

Examples

import asyncio
from bite import Literal, parse_bytes, ZeroOrMore

print(asyncio.run(parse_bytes(ZeroOrMore(Literal(b'a')), b'')).values)
print(asyncio.run(parse_bytes(ZeroOrMore(Literal(b'a')), b'aaa')).values)
()
(b'a', b'a', b'a')
async parse(buf: ParserBuffer, loc: int = 0) ParsedList[source]

Try to parse the provided input.

Starts parsing from the given location and does not need to consume all provided input.

Parameters:
  • buf – Buffer providing access to the input.

  • loc – Index into the buffer from where to start parsing.

Returns:

If parsing is successful, a parse tree representing the parse result is returned.

Raises:
  • UnmetExpectationError – If parsing was unsuccessful, because the input does not match what is expected from this parser.

  • # noqa – DAR202: