Skip to content

pegen: leader selection for left-recursive SCCs takes factorial time #158847

Description

@jonbaldie

Feature or enhancement

Proposal:

When pegen picks a leader for a left-recursive SCC, compute_left_recursives calls sccutils.find_cycles_in_scc from every node. That function walks every path through the SCC, so the work grows factorially with the SCC's size.

CPython's own grammar doesn't notice, because its biggest left-recursive SCC has two rules. But a third-party grammar with a handful of mutually left-recursive rules makes generation fall over:

mutually left-recursive rules parser generation
10 30 ms
14 2.5 s
9, with no valid leader (error path) 0.48 s

On a fully connected 8-rule SCC, that's about 1.07 million name comparisons before it reports "no leadership candidate".

A leader is a rule that sits on every cycle in the SCC. So you can test each candidate directly: remove it and check whether the rest is acyclic (a topological sort). That's O(V·(V+E)) per SCC, it picks the same leader (smallest name), and it raises the same error. The 14-rule case drops to about 8 ms, and the generated Parser/parser.c doesn't change.

I have a patch with tests ready.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    performancePerformance or resource usage
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    on Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagetopic-parsertype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions