private function caseStatement($terminator) {
    static $terminators = [T_CASE, T_DEFAULT];
    if ($this->currentType === T_CASE) {
      $node = new CaseNode();
      $this->mustMatch(T_CASE, $node);
      $node->addChild($this->expr(), 'matchOn');
      if (!$this->tryMatch(':', $node, NULL, TRUE, TRUE) && !$this->tryMatch(';', $node, NULL, TRUE, TRUE)) {
        throw new ParserException(
          $this->filename,
          $this->iterator->getLineNumber(),
          $this->iterator->getColumnNumber(),
          'expected :');
      }
      if ($this->currentType !== $terminator && !in_array($this->currentType, $terminators)) {
        $this->matchHidden($node);
        $node->addChild($this->innerCaseStatementList($terminator), 'body');
      }
      return $node;
    }
    elseif ($this->currentType === T_DEFAULT) {
      $node = new DefaultNode();
      $this->mustMatch(T_DEFAULT, $node);
      if (!$this->tryMatch(':', $node, NULL, TRUE, TRUE) && !$this->tryMatch(';', $node, NULL, TRUE, TRUE)) {
        throw new ParserException(
          $this->filename,
          $this->iterator->getLineNumber(),
          $this->iterator->getColumnNumber(),
          'expected :');
      }
      if ($this->currentType !== $terminator && !in_array($this->currentType, $terminators)) {
        $this->matchHidden($node);
        $node->addChild($this->innerCaseStatementList($terminator), 'body');
      }
      return $node;
    }
    throw new ParserException(
      $this->filename,
      $this->iterator->getLineNumber(),
      $this->iterator->getColumnNumber(),
      "expected case or default");
  }