or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-parsy

Easy-to-use parser combinators for parsing in pure Python

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/parsy@1.4.x

To install, run

npx @tessl/cli install tessl/pypi-parsy@1.4.0

0

# Parsy

1

2

A comprehensive Python library for building parser combinators in pure Python. Parsy provides a declarative way to construct complex parsers by combining simple, small parsers together. It offers a monadic parser combinator library for LL(infinity) grammars, inspired by Parsec, Parsnip, and Parsimmon.

3

4

## Package Information

5

6

- **Package Name**: parsy

7

- **Language**: Python

8

- **Installation**: `pip install parsy`

9

- **Python Support**: 3.5+

10

11

## Core Imports

12

13

```python

14

import parsy

15

```

16

17

Common for working with specific parsers:

18

19

```python

20

from parsy import string, regex, generate, seq, alt

21

```

22

23

Import all core functionality:

24

25

```python

26

from parsy import *

27

```

28

29

Version information:

30

31

```python

32

from parsy import __version__

33

```

34

35

## Basic Usage

36

37

```python

38

from parsy import string, regex, generate, seq, alt

39

40

# Simple string parser

41

hello_parser = string('hello')

42

result = hello_parser.parse('hello') # Returns 'hello'

43

44

# Regex parser

45

number_parser = regex(r'\d+').map(int)

46

result = number_parser.parse('123') # Returns 123

47

48

# Combining parsers with sequences

49

greeting_parser = seq(

50

string('hello'),

51

regex(r'\s+'),

52

regex(r'\w+')

53

).combine(lambda hello, space, name: f"{hello} {name}")

54

55

result = greeting_parser.parse('hello world') # Returns 'hello world'

56

57

# Using generator syntax for complex parsing

58

@generate

59

def simple_expression():

60

left = yield number_parser

61

operator = yield regex(r'\s*[+\-*/]\s*')

62

right = yield number_parser

63

return (left, operator.strip(), right)

64

65

result = simple_expression.parse('5 + 3') # Returns (5, '+', 3)

66

```

67

68

## Architecture

69

70

Parsy follows a functional programming approach with these core concepts:

71

72

- **Parser Objects**: Immutable parser instances that can be combined and transformed

73

- **Result Objects**: Containers for parse results with success/failure status and position tracking

74

- **Combinator Functions**: Pure functions that create and combine parsers

75

- **Method Chaining**: Fluent API for parser transformations and combinations

76

77

The library uses monadic composition patterns, allowing parsers to be bound together with proper error propagation and backtracking.

78

79

## Capabilities

80

81

### Core Parser Class

82

83

The fundamental Parser class provides the foundation for all parsing operations, including execution, transformation, and combination methods.

84

85

```python { .api }

86

class Parser:

87

def parse(self, stream): ...

88

def parse_partial(self, stream): ...

89

def bind(self, bind_fn): ...

90

def map(self, map_fn): ...

91

def then(self, other): ...

92

def skip(self, other): ...

93

def many(self): ...

94

def times(self, min, max=None): ...

95

def optional(self): ...

96

```

97

98

[Core Parser Class](./core-parser.md)

99

100

### Basic Parsers

101

102

Fundamental parser constructors for strings, regular expressions, character matching, and success/failure cases.

103

104

```python { .api }

105

def string(s, transform=noop): ...

106

def regex(exp, flags=0, group=0): ...

107

def test_char(func, description): ...

108

def success(val): ...

109

def fail(expected): ...

110

```

111

112

[Basic Parsers](./basic-parsers.md)

113

114

### Parser Combinators

115

116

Functions for combining multiple parsers into more complex parsing logic, including alternatives, sequences, and generator-based composition.

117

118

```python { .api }

119

def alt(*parsers): ...

120

def seq(*parsers, **kw_parsers): ...

121

def generate(fn): ...

122

```

123

124

[Parser Combinators](./combinators.md)

125

126

### Pre-defined Parsers

127

128

Ready-to-use parser constants for common parsing tasks like whitespace, digits, letters, and end-of-input detection.

129

130

```python { .api }

131

any_char: Parser

132

whitespace: Parser

133

letter: Parser

134

digit: Parser

135

decimal_digit: Parser

136

eof: Parser

137

index: Parser

138

line_info: Parser

139

```

140

141

[Pre-defined Parsers](./predefined-parsers.md)

142

143

### Utility Functions

144

145

Helper functions for common operations and transformations.

146

147

```python { .api }

148

def line_info_at(stream, index): ...

149

noop: function

150

```

151

152

[Utility Functions](./utilities.md)

153

154

## Types

155

156

```python { .api }

157

from collections import namedtuple

158

159

class ParseError(RuntimeError):

160

expected: frozenset

161

stream: str

162

index: int

163

164

def line_info(self) -> str: ...

165

166

class Result(namedtuple('Result', 'status index value furthest expected')):

167

"""

168

Result of a parsing operation.

169

170

Attributes:

171

status: bool - True if parsing succeeded, False if failed

172

index: int - Position after successful parse (or -1 for failure)

173

value: Any - Parsed value (or None for failure)

174

furthest: int - Furthest position reached during parsing

175

expected: frozenset - Set of expected values at failure point

176

"""

177

178

@staticmethod

179

def success(index, value): ...

180

@staticmethod

181

def failure(index, expected): ...

182

183

def aggregate(self, other): ...

184

185

class forward_declaration(Parser):

186

"""

187

Forward declaration for recursive parsers.

188

189

An empty parser that can be used as a forward declaration,

190

especially for parsers that need to be defined recursively.

191

You must use .become(parser) before using.

192

"""

193

194

def __init__(self): ...

195

def become(self, other): ...

196

197

# These methods raise ValueError before become() is called:

198

def parse(self, stream): ... # Raises ValueError if become() not called

199

def parse_partial(self, stream): ... # Raises ValueError if become() not called

200

```