From 768bfc0cf2e705cd0eeaa0ab11bcd18f453442a0 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 8 Mar 2012 13:24:08 -0600 Subject: [PATCH] Add ProxyErrorListener to allow dispatching error reporting to multiple listeners without manually iterating over the list of listeners. --- .../Java/src/org/antlr/v4/runtime/Lexer.java | 7 +- .../Java/src/org/antlr/v4/runtime/Parser.java | 7 +- .../antlr/v4/runtime/ProxyErrorListener.java | 115 ++++++++++++++++++ .../src/org/antlr/v4/runtime/Recognizer.java | 4 + 4 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 runtime/Java/src/org/antlr/v4/runtime/ProxyErrorListener.java diff --git a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java index 22bfcb405..3bca85c83 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java @@ -309,10 +309,9 @@ public abstract class Lexer extends Recognizer public void notifyListeners(LexerNoViableAltException e) { String msg = "token recognition error at: '"+ _input.substring(_tokenStartCharIndex, _input.index())+"'"; - List> listeners = getErrorListeners(); - for (ANTLRErrorListener listener : listeners) { - listener.error(this, null, _tokenStartLine, _tokenStartCharPositionInLine, msg, e); - } + + ANTLRErrorListener listener = getErrorListenerDispatch(); + listener.error(this, null, _tokenStartLine, _tokenStartCharPositionInLine, msg, e); } public String getCharErrorDisplay(int c) { diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index fee05b775..b967f204f 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -280,10 +280,9 @@ public abstract class Parser extends Recognizer line = ((Token) offendingToken).getLine(); charPositionInLine = ((Token) offendingToken).getCharPositionInLine(); } - List> listeners = getErrorListeners(); - for (ANTLRErrorListener listener : listeners) { - listener.error(this, offendingToken, line, charPositionInLine, msg, e); - } + + ANTLRErrorListener listener = getErrorListenerDispatch(); + listener.error(this, offendingToken, line, charPositionInLine, msg, e); } /** Consume the current symbol and return it. E.g., given the following diff --git a/runtime/Java/src/org/antlr/v4/runtime/ProxyErrorListener.java b/runtime/Java/src/org/antlr/v4/runtime/ProxyErrorListener.java new file mode 100644 index 000000000..fa08c334c --- /dev/null +++ b/runtime/Java/src/org/antlr/v4/runtime/ProxyErrorListener.java @@ -0,0 +1,115 @@ +/* + [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; + +import java.util.Collection; +import org.antlr.v4.runtime.atn.ATNConfigSet; +import org.antlr.v4.runtime.atn.DecisionState; +import org.antlr.v4.runtime.atn.SemanticContext; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.IntervalSet; + +/** + * + * @author Sam Harwell + */ +public class ProxyErrorListener implements ANTLRErrorListener { + private final Collection> delegates; + + public ProxyErrorListener(Collection> delegates) { + this.delegates = delegates; + } + + @Override + public void error(Recognizer recognizer, + T offendingSymbol, + int line, + int charPositionInLine, + String msg, + RecognitionException e) + { + for (ANTLRErrorListener listener : delegates) { + listener.error(recognizer, offendingSymbol, line, charPositionInLine, msg, e); + } + } + + @Override + public void reportAmbiguity(Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + IntervalSet ambigAlts, + ATNConfigSet configs) + { + for (ANTLRErrorListener listener : delegates) { + listener.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, ambigAlts, configs); + } + } + + @Override + public void reportAttemptingFullContext(Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + ATNConfigSet configs) + { + for (ANTLRErrorListener listener : delegates) { + listener.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, configs); + } + } + + @Override + public void reportContextSensitivity(Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + ATNConfigSet configs) + { + for (ANTLRErrorListener listener : delegates) { + listener.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, configs); + } + } + + @Override + public void reportInsufficientPredicates(Parser recognizer, + DFA dfa, + int startIndex, + int stopIndex, + IntervalSet ambigAlts, + DecisionState decState, + SemanticContext[] altToPred, + ATNConfigSet configs, + boolean fullContextParse) + { + for (ANTLRErrorListener listener : delegates) { + listener.reportInsufficientPredicates(recognizer, dfa, startIndex, stopIndex, ambigAlts, decState, altToPred, configs, fullContextParse); + } + } + +} diff --git a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java index 331823698..218da3111 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java @@ -120,6 +120,10 @@ public abstract class Recognizer { return new ArrayList>(_listeners); } + public ANTLRErrorListener getErrorListenerDispatch() { + return new ProxyErrorListener(getErrorListeners()); + } + // subclass needs to override these if there are sempreds or actions // that the ATN interp needs to execute public boolean sempred(@Nullable RuleContext _localctx, int ruleIndex, int actionIndex) {