/*
* Copyright (C) 2011 Laurent Caillette
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.novelang.parser.antlr;
import org.antlr.runtime.EarlyExitException;
import org.antlr.runtime.FailedPredicateException;
import org.antlr.runtime.MismatchedNotSetException;
import org.antlr.runtime.MismatchedSetException;
import org.antlr.runtime.MismatchedTokenException;
import org.antlr.runtime.MismatchedTreeNodeException;
import org.antlr.runtime.MissingTokenException;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.runtime.UnwantedTokenException;
import org.novelang.parser.unicode.UnicodeNames;
/**
* Copied from {@link org.antlr.runtime.BaseRecognizer}
*
* @author Laurent Caillette
*/
public class AntlrErrorInterpreter {
private AntlrErrorInterpreter() {}
public static String getErrorMessage( final RecognitionException e, final String[] tokenNames ) {
String msg = e.getMessage() ;
if ( e instanceof UnwantedTokenException ) {
final UnwantedTokenException ute = ( UnwantedTokenException ) e ;
String tokenName = "<unknown>" ;
if ( ute.expecting == Token.EOF ) {
tokenName = "EOF" ;
} else {
tokenName = tokenNames[ ute.expecting ] ;
}
msg = "extraneous input " + getTokenErrorDisplay( ute.getUnexpectedToken() ) +
" expecting " + tokenName ;
} else if ( e instanceof MissingTokenException ) {
final MissingTokenException mte = ( MissingTokenException ) e ;
String tokenName = "<unknown>" ;
if ( mte.expecting == Token.EOF ) {
tokenName = "EOF" ;
} else {
tokenName = tokenNames[ mte.expecting ] ;
}
msg = "missing " + tokenName + " at " + getTokenErrorDisplay( e.token ) ;
} else if ( e instanceof MismatchedTokenException ) {
final MismatchedTokenException mte = ( MismatchedTokenException ) e ;
String tokenName = "<unknown>" ;
if ( mte.expecting == Token.EOF ) {
tokenName = "EOF" ;
} else {
tokenName = tokenNames[ mte.expecting ] ;
}
msg = "mismatched input " + getTokenErrorDisplay( e.token ) +
" expecting " + tokenName ;
} else if ( e instanceof MismatchedTreeNodeException ) {
final MismatchedTreeNodeException mtne = ( MismatchedTreeNodeException ) e ;
String tokenName = "<unknown>" ;
if ( mtne.expecting == Token.EOF ) {
tokenName = "EOF" ;
} else {
tokenName = tokenNames[ mtne.expecting ] ;
}
msg = "mismatched tree node: " + mtne.node +
" expecting " + tokenName ;
} else if ( e instanceof NoViableAltException ) {
// NoViableAltException nvae = (NoViableAltException)e ;
// for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>"
// and "(decision="+nvae.decisionNumber+") and
// "state "+nvae.stateNumber
final NoViableAltException noViableAltException = ( NoViableAltException ) e ;
final Token token = noViableAltException.token ;
final char charAtError ;
if( token != null && token.getText() != null && token.getText().length() == 1 ) {
charAtError = token.getText().charAt( 0 ) ;
} else {
charAtError = ( ( char ) noViableAltException.c ) ;
}
msg = "No viable alternative at input '" + charAtError + "' " +
UnicodeNames.getDecoratedName( charAtError ) ;
// msg = "No viable alternative at input " + getTokenErrorDisplay( e.token ) ;
} else if ( e instanceof EarlyExitException ) {
//EarlyExitException eee = (EarlyExitException)e ;
// for development, can add "(decision="+eee.decisionNumber+")"
msg = "required (...)+ loop did not match anything at input " +
getTokenErrorDisplay( e.token ) ;
} else if ( e instanceof MismatchedSetException ) {
final MismatchedSetException mse = ( MismatchedSetException ) e ;
msg = "mismatched input " + getTokenErrorDisplay( e.token ) +
" expecting set " + mse.expecting ;
} else if ( e instanceof MismatchedNotSetException ) {
final MismatchedNotSetException mse = ( MismatchedNotSetException ) e ;
msg = "mismatched input " + getTokenErrorDisplay( e.token ) +
" expecting set " + mse.expecting ;
} else if ( e instanceof FailedPredicateException ) {
final FailedPredicateException fpe = ( FailedPredicateException ) e ;
msg = "rule " + fpe.ruleName + " failed predicate: {" +
fpe.predicateText + "}?" ;
}
return msg ;
}
private static String getTokenErrorDisplay( final Token t ) {
if( t == null ) {
return "<null>" ;
}
String s = t.getText() ;
if ( s == null ) {
if ( t.getType() == Token.EOF ) {
s = "<EOF>" ;
} else {
s = "<" + t.getType() + ">" ;
}
}
if( s.length() == 1 ) {
s = "'" + s + "' " + UnicodeNames.getDecoratedName( s.charAt( 0 ) ) ;
} else {
s = s.replaceAll( "\n", "\\\\n" ) ;
s = s.replaceAll( "\r", "\\\\r" ) ;
s = s.replaceAll( "\t", "\\\\t" ) ;
s = "'" + s + "'" ;
}
return s ;
}
}