Parsy

2.2 · active · verified Fri Apr 10

Parsy is an easy-to-use parser combinator library for building parsers in pure Python. It provides a straightforward and Pythonic solution for parsing text without external dependencies, focusing on combining small parsers into complex ones. The library is highly mature and stable, with its current version being 2.2. Releases are active, often aligning with Python version lifecycle updates.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates basic parser creation using `string` and `regex` primitives, chaining with `then`, and transforming results with `map`. It also showcases the powerful `@generate` decorator for building parsers that yield intermediate results and return a structured object, which is crucial for complex grammars. Error handling with `ParseError` is also illustrated.

from parsy import string, regex, generate, ParseError
from datetime import date

# Example 1: Simple date parsing using combinators
year = regex(r"[0-9]{4}").map(int)
month = regex(r"[0-9]{2}").map(int)
day = regex(r"[0-9]{2}").map(int)
dash = string('-')

iso_date_parser = year.then(dash).then(month).then(dash).then(day)

try:
    parsed_date_list = iso_date_parser.parse("2023-10-26")
    # The default behavior of .then() chain is to return the value of the *last* parser.
    # To combine results, .map() or @generate is often used.
    print(f"Simple parse result (last element): {parsed_date_list}")
except ParseError as e:
    print(f"Parse Error: {e}")

# Example 2: More complex date parsing using the @generate decorator
# This allows you to combine parsed values into a structured result.
@generate
def full_date_parser():
    y = yield year << dash
    m = yield month << dash
    d = yield day
    return date(y, m, d)

try:
    parsed_date_obj = full_date_parser.parse("2023-10-26")
    print(f"Structured parse result (date object): {parsed_date_obj}")
    assert parsed_date_obj == date(2023, 10, 26)

    # Example of a failure
    full_date_parser.parse("2023/10/26")
except ParseError as e:
    print(f"Parse Error for '2023/10/26': {e}")

# Example 3: Using .map to transform simple results
weekday_parser = string('Mon') | string('Tue') | string('Wed') # ...and so on
weekday_mapping = {'Mon': 'Monday', 'Tue': 'Tuesday', 'Wed': 'Wednesday'}
mapped_weekday_parser = weekday_parser.map(lambda s: weekday_mapping.get(s, s))

try:
    print(f"Mapped weekday: {mapped_weekday_parser.parse('Tue')}")
except ParseError as e:
    print(f"Parse Error: {e}")

view raw JSON →