public void visitErrorNode(ErrorNode node){
  ProgressIndicatorProvider.checkCanceled();
  Token badToken=node.getSymbol();
  boolean isConjuredToken=badToken.getTokenIndex() < 0;
  int nodeStartIndex=badToken.getStartIndex();
  SyntaxError error=tokenToErrorMap.get(nodeStartIndex);
  if (error != null) {
    PsiBuilder.Marker errorMarker=builder.mark();
    if (badToken.getStartIndex() >= 0 && badToken.getType() != Token.EOF && !isConjuredToken) {
      builder.advanceLexer();
    }
    String message=String.format("%s%n",error.getMessage());
    errorMarker.error(message);
  }
 else {
    if (isConjuredToken) {
      PsiBuilder.Marker errorMarker=builder.mark();
      errorMarker.error(badToken.getText());
    }
 else {
      builder.advanceLexer();
    }
  }
}

public void visitErrorNode ( ErrorNode node ) { ProgressIndicatorProvider . checkCanceled ( ) ; Token badToken = node . getSymbol ( ) ; boolean isConjuredToken = badToken . getTokenIndex ( ) < 0 ; int nodeStartIndex = badToken . getStartIndex ( ) ; SyntaxError error = tokenToErrorMap . get ( nodeStartIndex ) ; if ( error != null ) { PsiBuilder . Marker errorMarker = builder . mark ( ) ; if ( badToken . getStartIndex ( ) >= 0 && badToken . getType ( ) != Token . EOF && ! isConjuredToken ) { builder . advanceLexer ( ) ; } String message = String . format ( "%s%n" , error . getMessage ( ) ) ; errorMarker . error ( message ) ; } else { if ( isConjuredToken ) { PsiBuilder . Marker errorMarker = builder . mark ( ) ; errorMarker . error ( badToken . getText ( ) ) ; } else { builder . advanceLexer ( ) ; } } }
summary . for any syntax error thrown by the parser , there will be an errornode in the parse tree and this method will process it . all errors correspond to actual tokens in the input except for missing token errors . there are there are multiple error situations to consider : 1 . extraneous token . the parse tree will have an errornode for token . 2 . token mismatch . the parse tree will have an errornode for token . 3 . missing token . the parse tree will have an errornode but it does not correspond to any bit of the input . we underline the current token . 4 . noviablealt ( input inconsistent with any rule alt ) . the parse tree will have an errornode for token . 5 . tokens consumed to resync the parser during recovery . the parse tree will have an errornode for each token . this is complicated by errors that occur at eof but i have modified error strategy to add error nodes for eof if needed . another complication . during prediction , we might match n tokens and then fail on the n + 1 token , leading to noviablealtexception . but , it ' s offending token is at n + 1 not current token where prediction started ( which we use to find syntax errors ) . so , syntaxerror objects return start not offending token in this case .
