Parsley
Parsley is a Python parsing library designed to simplify parsing and pattern matching. It implements the Parsing Expression Grammar (PEG) algorithm, compiling grammar definitions into Python classes where rules become methods. This approach aims to make parsing expressions behave similarly to standard Python expressions. It is an implementation of OMeta, an object-oriented pattern-matching language. The current version is 1.3, released in 2017.
Warnings
- breaking The Parsley project has seen no new releases since version 1.3 in April 2017, and its GitHub repository shows no recent activity. This indicates the project is effectively abandoned, meaning no new features, bug fixes, security updates, or official support for newer Python versions should be expected.
- gotcha Parsley's PEG (Parsing Expression Grammar) parser evaluates alternatives (`|`) strictly in order, unlike traditional LL/LR parsers (e.g., Yacc, PLY) which might use longest match or other lookahead strategies. This can lead to unexpected parsing results if the order of alternatives is not carefully considered, as an earlier, less specific rule might consume input that a later, more specific rule was intended to handle.
- gotcha Although some community efforts (e.g., operating system packages) exist for Python 3 compatibility, the last official release of Parsley (v1.3 in 2017) pre-dates broad adoption and dedicated testing for recent Python 3.x versions. Users might encounter subtle compatibility issues, unaddressed bugs, or missing features when running Parsley on modern Python 3.8+ environments.
- gotcha When using repetition operators (`*` for zero or more, `+` for one or more) with rules that incorporate Python actions (`-> pythonExpression`) for transformation or aggregation, results from chained matches may overwrite previous results instead of accumulating into a list. Parsley does not automatically manage list accumulation in all such scenarios.
Install
-
pip install parsley
Imports
- makeGrammar
import parsley parser_class = parsley.makeGrammar(grammar_source, bindings)
Quickstart
import parsley
grammar_source = """
integer = <digit+>:ds -> int(ds)
sum = integer:left '+' integer:right -> left + right
product = integer:left '*' integer:right -> left * right
expression = sum | product | integer
"""
calculator_grammar = parsley.makeGrammar(grammar_source, {})
# Parse a sum
parser_sum = calculator_grammar("10+20")
result_sum = parser_sum.sum()
print(f"10+20 = {result_sum}") # Expected: 30
# Parse a product
parser_product = calculator_grammar("5*6")
result_product = parser_product.product()
print(f"5*6 = {result_product}") # Expected: 30
# Parse a single integer
parser_int = calculator_grammar("123")
result_int = parser_int.integer()
print(f"123 = {result_int}") # Expected: 123