Skip to main content

Grammar2Regex

Grammar2Regex converts context-free grammars to regular expressions. Left- and right-linear grammars are always converted precisely. Furthermore, some grammars with a regular language but a more general shape can also be converted. For example, a rule <N> ::= a<A><N> is not right-linear due to the occurrence of <A>; but if <A> does not reach <N> and everything else is regular, we obtain a precise regular expression by computing the regular expression for <A> and inserting it into the rule for <N>.

For grammars with a non-regular language or a suboptimal shape, we "unwind" problematic expansion elements. This step loses information, but enables us to compute under-approximating regular expressions for arbitrary context-free grammars. Grammar2Regex returns expressions either in a custom ADT format suitable for further processing or as ReRef objects of the z3 SMT solver.

Example

Consider the following grammar of XML attribute or tag name identifiers:

import string
from typing import Dict, List
from fuzzingbook.Grammars import srange

xml_id_grammar: Dict[str, List[str]] = {
    "<start>": ["<id>"],
    "<id>": [
        "<id-no-prefix>",
        "<id-with-prefix>"
    ],
    "<id-no-prefix>": [
        "<id-start-char>",
        "<id-start-char><id-chars>",
    ],
    "<id-with-prefix>": ["<id-no-prefix>:<id-no-prefix>"],
    "<id-start-char>": srange("_" + string.ascii_letters),
    "<id-chars>": ["<id-char>", "<id-char><id-chars>"],
    "<id-char>": ["<id-start-char>"] + srange("-." + string.digits),
}

Our chosen grammar format is the one from the Fuzzing Book.

This grammar can be precisely converted into a regular expression:

from grammar_to_regex.cfg2regex import RegexConverter

converter = RegexConverter(xml_id_grammar, compress_unions=True)
print(converter.to_regex('<start>', convert_to_z3=False))

which yields an object of type grammar_to_regex.regex.Regex, in pretty print:

((["-" .. "."] | ["0" .. "9"] | ["A" .. "Z"] | "_" | ["a" .. "z"])* • (["-" .. "."] | ["0" .. "9"] | ["A" .. "Z"] | "_" | ["a" .. "z"]))

You can also obtain an output in the regular expression format of the z3 SMT solver if you need this for further processing (simply omit the convert_to_z3=False or set that parameter to True).

Installation

Grammar2Regex requires Python 3.10.

To install Grammar2Regex, run

pip install grammar_to_regex

To install it locally for testing, check this repository out and run

pip install -e .[test]

License and Maintainer

This project is licensed under the GNU GENERAL PUBLIC LICENSE v3. It is maintained by Dominic Steinhöfel.

Metadata

Release files for grammar-to-regex 1.0.1

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

Source distribution (sdist)

Source distribution for grammar-to-regex 1.0.1
File Size Uploaded Provenance
grammar_to_regex-1.0.1.tar.gz 54.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for grammar-to-regex 1.0.1
File Interpreter ABI Platform
grammar_to_regex-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 92.4 kB

Release files / grammar_to_regex-1.0.1.tar.gz

Download URL grammar_to_regex-1.0.1.tar.gz
Size 54.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5894c44c5a1594324edecd825997b001d59154c94fb584bf23aaea37e8834f79
BLAKE2b-256 checksum
How to use checksums
6387bfbb7a15cd4099a3796ce320dc3c254ace1042504f770890b293980468d7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.14

Release files / grammar_to_regex-1.0.1-py3-none-any.whl

Download URL grammar_to_regex-1.0.1-py3-none-any.whl
Size 38.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5c0cdbe47581d69567f9ecf0f6198eda34c47f3383504ca1778bfddf50c196d7
BLAKE2b-256 checksum
How to use checksums
78c8bf3e49e8ef17e7662301ced74ae8f9eef344c2c3b8a97f4344c62f58223e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.14

Security for grammar-to-regex 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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