diff --git a/runtime/Java/src/org/antlr/v4/runtime/ConsoleErrorListener.java b/runtime/Java/src/org/antlr/v4/runtime/ConsoleErrorListener.java new file mode 100644 index 000000000..2fa89eecd --- /dev/null +++ b/runtime/Java/src/org/antlr/v4/runtime/ConsoleErrorListener.java @@ -0,0 +1,49 @@ +/* + [The "BSD license"] + Copyright (c) 2012 Terence Parr + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.antlr.v4.runtime; + +/** + * + * @author Sam Harwell + */ +public class ConsoleErrorListener implements ANTLRErrorListener { + public static final ConsoleErrorListener INSTANCE = new ConsoleErrorListener(); + + @Override + public void error(Recognizer recognizer, + T offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) + { + System.err.println("line " + line + ":" + charPositionInLine + " " + msg); + } + +} diff --git a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java index 8cde9907e..22bfcb405 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java @@ -310,14 +310,8 @@ public abstract class Lexer extends Recognizer String msg = "token recognition error at: '"+ _input.substring(_tokenStartCharIndex, _input.index())+"'"; List> listeners = getErrorListeners(); - if ( listeners.isEmpty() ) { - System.err.println("line "+ _tokenStartLine +":"+ - _tokenStartCharPositionInLine +" "+ - msg); - return; - } - for (ANTLRErrorListener pl : listeners) { - pl.error(this, null, _tokenStartLine, _tokenStartCharPositionInLine, msg, e); + for (ANTLRErrorListener listener : listeners) { + listener.error(this, null, _tokenStartLine, _tokenStartCharPositionInLine, msg, e); } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index b5940bf0a..fee05b775 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -281,12 +281,8 @@ public abstract class Parser extends Recognizer charPositionInLine = ((Token) offendingToken).getCharPositionInLine(); } List> listeners = getErrorListeners(); - if ( listeners.isEmpty() ) { - System.err.println("line "+line+":"+charPositionInLine+" "+msg); - return; - } - for (ANTLRErrorListener pl : listeners) { - pl.error(this, offendingToken, line, charPositionInLine, msg, e); + for (ANTLRErrorListener listener : listeners) { + listener.error(this, offendingToken, line, charPositionInLine, msg, e); } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java index 6498c694d..331823698 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java @@ -35,13 +35,15 @@ import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.misc.Nullable; import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; public abstract class Recognizer { public static final int EOF=-1; - private List> _listeners; + @NotNull + private List> _listeners = + new CopyOnWriteArrayList>() {{ add(ConsoleErrorListener.INSTANCE); }}; protected ATNInterpreter _interp; @@ -94,25 +96,27 @@ public abstract class Recognizer { return "'"+s+"'"; } - public void addErrorListener(ANTLRErrorListener pl) { - if ( _listeners ==null ) { - _listeners = - Collections.synchronizedList(new ArrayList>(2)); - } - if ( pl!=null ) _listeners.add(pl); - } - - public void removeErrorListener(ANTLRErrorListener pl) { - if ( _listeners!=null ) _listeners.remove(pl); - } - - public void removeErrorListeners() { if ( _listeners!=null ) _listeners.clear(); } - - public @NotNull List> getErrorListeners() { - if (_listeners == null) { - return Collections.emptyList(); + /** + * @throws NullPointerException if {@code listener} is {@code null}. + */ + public void addErrorListener(@NotNull ANTLRErrorListener listener) { + if (listener == null) { + throw new NullPointerException("listener cannot be null."); } + _listeners.add(listener); + } + + public void removeErrorListener(@NotNull ANTLRErrorListener listener) { + _listeners.remove(listener); + } + + public void removeErrorListeners() { + _listeners.clear(); + } + + @NotNull + public List> getErrorListeners() { return new ArrayList>(_listeners); }