antlr/antlr4 · error · Exception

stop cannot be null or empty

Error message

stop cannot be null or empty

What it means

Thrown by ParseTreePatternMatcher.setDelimiters() in the Python3 runtime when the stop delimiter is None or the empty string. The stop delimiter closes tags like <ID>, so an empty one leaves tags unterminated and the split() step cannot work. The API contract explicitly forbids null or empty delimiters.

Source

Thrown at runtime/Python3/src/antlr4/tree/ParseTreePatternMatcher.py:119

        self.start = "<"
        self.stop = ">"
        self.escape = "\\"  # e.g., \< and \> must escape BOTH!

    # Set the delimiters used for marking rule and token tags within concrete
    # syntax used by the tree pattern parser.
    #
    # @param start The start delimiter.
    # @param stop The stop delimiter.
    # @param escapeLeft The escape sequence to use for escaping a start or stop delimiter.
    #
    # @exception IllegalArgumentException if {@code start} is {@code null} or empty.
    # @exception IllegalArgumentException if {@code stop} is {@code null} or empty.
    #
    def setDelimiters(self, start:str, stop:str, escapeLeft:str):
        if start is None or len(start)==0:
            raise Exception("start cannot be null or empty")
        if stop is None or len(stop)==0:
            raise Exception("stop cannot be null or empty")
        self.start = start
        self.stop = stop
        self.escape = escapeLeft

    # Does {@code pattern} matched as rule {@code patternRuleIndex} match {@code tree}?#
    def matchesRuleIndex(self, tree:ParseTree, pattern:str, patternRuleIndex:int):
        p = self.compileTreePattern(pattern, patternRuleIndex)
        return self.matches(tree, p)

    # Does {@code pattern} matched as rule patternRuleIndex match tree? Pass in a
    #  compiled pattern instead of a string representation of a tree pattern.
    #
    def matchesPattern(self, tree:ParseTree, pattern:ParseTreePattern):
        mismatchedNode = self.matchImpl(tree, pattern.patternTree, dict())
        return mismatchedNode is None

    #
    # Compare {@code pattern} matched as rule {@code patternRuleIndex} against

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Pass a non-empty stop string, e.g. setDelimiters('<<', '>>', '\\')
  2. Validate both delimiters are non-empty before calling setDelimiters
  3. Keep start and stop distinct so split() can pair them correctly

Example fix

# before
matcher.setDelimiters('<<', '', '\\')

# after
matcher.setDelimiters('<<', '>>', '\\')
Defensive patterns

Strategy: validation

Validate before calling

if not stop:
    raise ValueError('stop delimiter must be a non-empty string')
matcher.setDelimiters(start, stop, escape)

Type guard

def is_non_empty_str(s) -> bool:
    return isinstance(s, str) and len(s) > 0

Prevention

When it happens

Trigger: Calling matcher.setDelimiters('<', '', '\\') or passing None as the second argument.

Common situations: Symmetric attempt to reconfigure delimiters with a partially filled config, or a copy/paste that only set the start delimiter.

Related errors


AI-assisted analysis of antlr/antlr4@7d5770395b (2026-08-14). Data as JSON: /api/errors/5fdefda21c27fcf4. Report an issue: GitHub.