antlr/antlr4 · error · Exception

Empty Stack

Error message

Empty Stack

What it means

Lexer.popMode() raises Exception('Empty Stack') when the lexer mode stack is empty — a popMode action (or 'mode stack' manipulation in a member/embedded action) executed while still in the default mode. The mode stack is only populated by pushMode; pops must be balanced with pushes within the token stream.

Source

Thrown at runtime/Python3/src/antlr4/Lexer.py:183

    #/
    def skip(self):
        self._type = self.SKIP

    def more(self):
        self._type = self.MORE

    def mode(self, m:int):
        self._mode = m

    def pushMode(self, m:int):
        if self._interp.debug:
            print("pushMode " + str(m), file=self._output)
        self._modeStack.append(self._mode)
        self.mode(m)

    def popMode(self):
        if len(self._modeStack)==0:
            raise Exception("Empty Stack")
        if self._interp.debug:
            print("popMode back to "+ self._modeStack[:-1], file=self._output)
        self.mode( self._modeStack.pop() )
        return self._mode

    # Set the char stream and reset the lexer#/
    @property
    def inputStream(self):
        return self._input

    @inputStream.setter
    def inputStream(self, input:InputStream):
        self._input = None
        self._tokenFactorySourcePair = (self, self._input)
        self.reset()
        self._input = input
        self._tokenFactorySourcePair = (self, self._input)

View on GitHub (pinned to 7d5770395b)

Solutions

  1. Fix the grammar: every -> popMode must be reachable only from a mode entered with -> pushMode(<mode>)
  2. Guard pops in embedded Python actions: pop only if len(self._modeStack) > 0, else -> mode(DEFAULT_MODE) via the lexer's mode()
  3. Trace with lexer debug output or a lexer listener to see which token pops an empty stack, then move that rule into the correct mode section

Example fix

// grammar before
STRING_START : '"' -> pushMode(STR);
mode STR;
STRING_END : '"' -> popMode;
ESC : '\\' '"' -> popMode;  // second pop on \\" pops empty stack

// grammar after
STRING_START : '"' -> pushMode(STR);
mode STR;
STRING_END : '"' -> popMode;
ESC_QUOTE : '\\' '"' -> more;  // stay in STR, no pop
Defensive patterns

Strategy: validation

Validate before calling

# Python: in an embedded lexer action, pop only when a mode is pushed
if len(self._modeStack) > 0:
    self.popMode()
else:
    self.mode(Lexer.DEFAULT_MODE)  # or report a grammar bug

Try / catch

try:
    lexer.nextToken()
except Exception as ex:
    if str(ex) == "Empty Stack":
        raise SyntaxError(f"grammar bug: popMode with empty mode stack near char {lexer.column}") from ex
    raise

Prevention

When it happens

Trigger: A lexer grammar rule containing -> popMode that matches while in DEFAULT_MODE (no prior pushMode); two rules with popMode in the same mode where only one push occurred; generated-code paths where a skip/More rule with popMode fires repeatedly on the same construct.

Common situations: Lexer grammars for string interpolation or heredocs where the closing rule pops a mode but the opening rule forgot pushMode (or was skipped); editing modes and forgetting the push side; tokens reachable both inside and outside the pushed mode.

Related errors


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