Skip to content

rdf: avoid quadratic prefixed-name retries - #3234

Open
Baltsat wants to merge 1 commit into
pygments:masterfrom
Baltsat:fix/3226-rdf-linear-time
Open

Baltsat wants to merge 1 commit into
pygments:masterfrom
Baltsat:fix/3226-rdf-linear-time

Conversation

@Baltsat

@Baltsat Baltsat commented Jul 27, 2026

Copy link
Copy Markdown

Fixes #3226.

Root cause

The RDF prefixed-name regex was retried at every position in a colonless prefix-character run. Each failed attempt rescanned the remaining suffix, producing quadratic work in the SPARQL, Turtle, and ShExC lexers.

Change

The shared RDF lexer now remembers the end of a failed colonless prefix run and skips only prefixed-name attempts that are already known to be impossible. All other lexer rules and the existing token stream remain unchanged.

The regression measures matcher work rather than wall-clock time. On the unpatched base, the three lexers process 8,255–8,256 candidate units for a 128-character input; after the fix, each processes 128. The test also preserves the exact pre-existing Error/Keyword token stream.

Validation

  • focused RDF regression and fixture suite: 19 passed
  • full test suite: 5,345 passed, 15 skipped
  • scripts/check_crlf.py pygments external
  • scripts/detect_missing_analyse_text.py --skip-no-aliases
  • ruff check --ignore UP031 .
  • scripts/check_sources.py
  • scripts/count_token_references.py
  • regexlint pygments.lexers
  • git diff --check
  • production-only revert: the retained regression failed for all three lexers, then passed after restoring the fix
  • exact token snapshots matched across repository fixtures, targeted valid/cross-boundary cases, and 9,000 deterministic generated cases

Licensing and assistance

I agree that this contribution is licensed under the repository's BSD-2-Clause license.

OpenAI Codex assisted with investigation, implementation, testing, and review. I am accountable for the submitted change.

Skip impossible matcher retries inside colonless prefix runs while preserving exact tokenization.

Fixes pygments#3226

Signed-off-by: Konstantin Baltsat <[email protected]>
Assisted-by: OpenAI Codex
Copilot AI review requested due to automatic review settings July 27, 2026 01:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Baltsat

Baltsat commented Sep 17, 2026

Copy link
Copy Markdown
Author

Hi — this remains clean against the current base. The patch avoids repeated full-string rescans in the RDF prefixed-name path and keeps the existing tokenization behavior. Could a maintainer take a look when convenient? I can add a focused benchmark if that would help the review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Super-linear (quadratic) execution time in SparqlLexer/TurtleLexer/ShExCLexer on adversarial input

2 participants