Skip to main content

Project: License

Package: PyPI - Python Version PyPI - Version PyPI - Downloads

Development: uv ruff ty pytest CI Code Coverage GitHub commit activity

Contents

Overview

dbrownell_ParserLib is a Python library that provides utility functionality for creating parsers, with a primary focus on ANTLR (Another Tool for Language Recognition) integration. The library simplifies the process of building parsers that produce strongly-typed abstract syntax trees (ASTs) with comprehensive source location tracking.

Key Features

  • ANTLR Integration: Streamlined wrapper around ANTLR for Python, handling grammar compilation and parser generation
  • AST Representation: Element-based AST nodes with automatic parent-child relationship management
  • Source Location Tracking: Every AST node tracks its source file location (filename, line, column ranges) for detailed error reporting
  • Visitor Pattern: Flexible visitor pattern implementation with fine-grained traversal control
  • Error Handling: Rich error objects that associate messages with source locations and extract Python exception tracebacks
  • Multi-threaded Parsing: Built-in support for parsing multiple files concurrently
  • Workspace Support: Parse translation units organized across multiple workspace roots
  • Whitespace Handling: A single visitor mixin supports both insignificant and significant whitespace grammars (e.g., Python-like indentation); grammars that define INDENT/DEDENT tokens are detected automatically
  • Multiline String Extraction: Extract multiline string content that must be vertically aligned with its opening token, with detailed errors on misalignment

How to use dbrownell_ParserLib

The typical workflow for creating a parser with this library involves the following steps. For detailed examples, see the test files in the repository, particularly the end-to-end tests that demonstrate complete parsing workflows.

1. Define an ANTLR Grammar

Create a .g4 grammar file defining your language syntax:

grammar Calculator;

expr : expr ('*'|'/') expr   # BinaryOp
     | expr ('+'|'-') expr   # BinaryOp
     | INT                   # Number
     ;

INT : [0-9]+ ;
WS : [ \t\n\r]+ -> skip ;

2. Build the Grammar

Use BuildAntlrGrammar to generate the lexer and parser:

from pathlib import Path

from dbrownell_ParserLib.antlr.build_antlr_grammar import BuildAntlrGrammar


BuildAntlrGrammar(
    dm,  # DoneManager instance
    Path("Calculator.g4"),
    Path("output_dir"),
)

3. Create Custom Visitor

Implement a visitor that converts ANTLR parse trees to Element objects:

from dataclasses import dataclass

from dbrownell_ParserLib.antlr.antlr_visitor_mixin import AntlrVisitorMixin
from dbrownell_ParserLib.element import Element
from dbrownell_ParserLib.terminal_element import TerminalElement

from CalculatorVisitor import CalculatorVisitor as GeneratedVisitor


@dataclass(eq=False)
class BinaryExpression(Element):
    left: Element
    operator: TerminalElement[str]
    right: Element

    def _GenerateAcceptDetails(self):
        yield "left", self.left
        yield "operator", self.operator
        yield "right", self.right


class CalculatorVisitor(AntlrVisitorMixin, GeneratedVisitor):
    def visitBinaryOp(self, ctx):
        operator = TerminalElement[str](self.CreateRegion(ctx.children[1]), ctx.children[1].getText())

        children = self.GetChildren(ctx)
        assert len(children) == 2, children

        self._stack.append(
            BinaryExpression(
                self.CreateRegion(ctx),
                children[0],
                operator,
                children[1],
            )
        )

    def visitNumber(self, ctx):
        self._stack.append(
            TerminalElement[int](self.CreateRegion(ctx), int(ctx.getText()))
        )

4. Create Parser Instance

Use CreateAntlrParser to build a callable parser. Grammars that define INDENT and DEDENT tokens (significant whitespace) are detected automatically; no additional configuration is required.

from dbrownell_ParserLib.antlr.antlr_parser import CreateAntlrParser


parser = CreateAntlrParser(
    CalculatorLexer,
    CalculatorParser,
    CalculatorVisitor,
    lambda p: p.expr(),  # Entry point rule
)

5. Parse Files

Parse single files, multiple files, or entire workspaces:

from dbrownell_ParserLib.errors import Error


# Parse a single file
results = parser(dm, Path("input.txt"), None)

# Parse multiple files
results = parser(dm, [Path("file1.txt"), Path("file2.txt")], None)

# Check results
for filepath, result in results.items():
    if isinstance(result, Error):
        print(f"Parse error in {filepath}: {result}")
    else:
        # result is the visitor containing the parsed AST
        ast = result._stack[0]
        # Process the AST

6. Traverse the AST

Use the visitor pattern to process your AST:

from contextlib import contextmanager

from dbrownell_ParserLib.visitors import ElementVisitorHelper, VisitResult


class EvaluatorVisitor(ElementVisitorHelper):
    @contextmanager
    def OnBinaryExpression(self, element):
        # Process binary expressions
        yield VisitResult.Continue


ast.Accept(EvaluatorVisitor())

Installation

Installation Method Command
Via uv uv add dbrownell_ParserLib
Via pip pip install dbrownell_ParserLib

Verifying Signed Artifacts

Artifacts are signed and verified using py-minisign and the public key in the file ./minisign_key.pub.

To verify that an artifact is valid, visit the latest release and download the .minisign signature file that corresponds to the artifact, then run the following command, replacing <filename> with the name of the artifact to be verified:

uv run --with py-minisign python -c "import minisign; minisign.PublicKey.from_file('minisign_key.pub').verify_file('<filename>'); print('The file has been verified.')"

Development

Please visit Contributing and Development for information on contributing to this project.

Additional Information

Additional information can be found at these locations.

Title Document Description
Code of Conduct CODE_OF_CONDUCT.md Information about the norms, rules, and responsibilities we adhere to when participating in this open source community.
Contributing CONTRIBUTING.md Information about contributing to this project.
Development DEVELOPMENT.md Information about development activities involved in making changes to this project.
Governance GOVERNANCE.md Information about how this project is governed.
Maintainers MAINTAINERS.md Information about individuals who maintain this project.
Security SECURITY.md Information about how to privately report security issues associated with this project.

License

dbrownell_ParserLib is licensed under the MIT license.

Metadata

Release files for dbrownell-parserlib 0.13.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dbrownell-parserlib 0.13.5
File Size Uploaded
dbrownell_parserlib-0.13.5.tar.gz 2.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for dbrownell-parserlib 0.13.5
File Interpreter ABI Platform
dbrownell_parserlib-0.13.5-py3-none-any.whl Python 3 none any Details

Total release size: 4.0 MB

Release files / dbrownell_parserlib-0.13.5.tar.gz

Download URL dbrownell_parserlib-0.13.5.tar.gz
Size 2.0 MB
Tags Source
SHA-256 checksum
How to use checksums
1541a1c09d55ecf27d681bac163564edefcdf3a4c8529233090c836ba76b97f0
BLAKE2b-256 checksum
How to use checksums
b102fac85250b474008158500c13e4e8a05f82b73483e3634cc29e902eb755ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / dbrownell_parserlib-0.13.5-py3-none-any.whl

Download URL dbrownell_parserlib-0.13.5-py3-none-any.whl
Size 2.0 MB
Tags Python 3
SHA-256 checksum
How to use checksums
fc1a58982e26a9c7895838fcbfca5934cb16e9e5e3e543780e68a08a20296937
BLAKE2b-256 checksum
How to use checksums
e4b35a3a8243ef78616239f4d9b16139278548b1fffc9d79ce302284f5e01095
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.13.5 This release

2 release files

0.13.2

2 release files

0.13.1

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page