diff --git a/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorListener.java b/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorListener.java index cfe812406..243031bea 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorListener.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorListener.java @@ -32,7 +32,7 @@ package org.antlr.v4.runtime; import com.sun.istack.internal.Nullable; /** How to emit recognition errors */ -public interface ANTLRErrorListener { +public interface ANTLRErrorListener { /** Upon syntax error, notify any interested parties. This is not how to * recover from errors or compute error messages. The parser * ANTLRErrorStrategy specifies how to recover from syntax errors @@ -48,7 +48,7 @@ public interface ANTLRErrorListener { * @param recognizer * What parser got the error. From this object, you * can access the context as well as the input stream. - * @param offendingToken + * @param offendingSymbol * The offending token in the input token stream, unless recognizer * is a lexer (then it's null) * If no viable alternative error, e has token @@ -66,8 +66,8 @@ public interface ANTLRErrorListener { * the parser was able to recover in line without exiting the * surrounding rule. */ - public void error(Recognizer recognizer, - @Nullable Token offendingToken, + public void error(Recognizer recognizer, + @Nullable TSymbol offendingSymbol, int line, int charPositionInLine, String msg, diff --git a/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java index f391e735b..e424f0ff8 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java @@ -21,9 +21,9 @@ package org.antlr.v4.runtime; * * TODO: what to do about lexers */ -public interface ANTLRErrorStrategy { +public interface ANTLRErrorStrategy { /** Report any kind of RecognitionException. */ - void reportError(BaseRecognizer recognizer, + void reportError(BaseRecognizer recognizer, RecognitionException e) throws RecognitionException; @@ -43,7 +43,7 @@ public interface ANTLRErrorStrategy { * "inserting" tokens, we need to specify what that implicitly created * token is. We use object, because it could be a tree node. */ - Object recoverInline(BaseRecognizer recognizer) + TSymbol recoverInline(BaseRecognizer recognizer) throws RecognitionException; /** Resynchronize the parser by consuming tokens until we find one @@ -51,7 +51,7 @@ public interface ANTLRErrorStrategy { * the current rule. The exception contains info you might want to * use to recover better. */ - void recover(BaseRecognizer recognizer, + void recover(BaseRecognizer recognizer, RecognitionException e); /** Make sure that the current lookahead symbol is consistent with @@ -81,14 +81,14 @@ public interface ANTLRErrorStrategy { * turn off this functionality by simply overriding this method as * a blank { }. */ - void sync(BaseRecognizer recognizer); + void sync(BaseRecognizer recognizer); /** Notify handler that parser has entered an error state. The * parser currently doesn't call this--the handler itself calls this * in report error methods. But, for symmetry with endErrorCondition, * this method is in the interface. */ - void beginErrorCondition(BaseRecognizer recognizer); + void beginErrorCondition(BaseRecognizer recognizer); /** Is the parser in the process of recovering from an error? Upon * a syntax error, the parser enters recovery mode and stays there until @@ -96,11 +96,11 @@ public interface ANTLRErrorStrategy { * avoid sending out spurious error messages. We only want one error * message per syntax error */ - boolean inErrorRecoveryMode(BaseRecognizer recognizer); + boolean inErrorRecoveryMode(BaseRecognizer recognizer); /** Reset the error handler. Call this when the parser * matches a valid token (indicating no longer in recovery mode) * and from its own reset method. */ - void endErrorCondition(BaseRecognizer recognizer); + void endErrorCondition(BaseRecognizer recognizer); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/BaseRecognizer.java b/runtime/Java/src/org/antlr/v4/runtime/BaseRecognizer.java index 68d3351f9..d50cdc588 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/BaseRecognizer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/BaseRecognizer.java @@ -41,7 +41,7 @@ import java.util.*; * * TODO: rename since lexer not under. or reorg parser/treeparser; treeparser under parser? */ -public abstract class BaseRecognizer extends Recognizer { +public abstract class BaseRecognizer extends Recognizer> { public static final String NEXT_TOKEN_RULE_NAME = "nextToken"; /** The RuleContext object for the currently executing rule. This @@ -49,7 +49,7 @@ public abstract class BaseRecognizer extends Recognizer { * When somebody calls the start rule, this gets set to the * root context. */ - protected ParserRuleContext _ctx; + protected ParserRuleContext _ctx; protected boolean buildParseTrees; protected boolean traceATNStates; @@ -80,9 +80,9 @@ public abstract class BaseRecognizer extends Recognizer { * to the set of symbols that can follow rule ref. * TODO: mv into Parser etc... to get more precise return value/efficiency */ - public Object match(int ttype) throws RecognitionException { + public TSymbol match(int ttype) throws RecognitionException { // System.out.println("match "+((TokenStream)input).LT(1)+" vs expected "+ttype); - Object currentSymbol = getCurrentInputSymbol(); + TSymbol currentSymbol = getCurrentInputSymbol(); if ( getInputStream().LA(1)==ttype ) { _errHandler.endErrorCondition(this); consume(); @@ -147,6 +147,9 @@ public abstract class BaseRecognizer extends Recognizer { return syntaxErrors; } + @Override + public abstract ObjectStream getInputStream(); + /** Match needs to return the current input symbol, which gets put * into the label for the associated token ref; e.g., x=ID. Token * and tree parsers need to return different objects. Rather than test @@ -154,27 +157,32 @@ public abstract class BaseRecognizer extends Recognizer { * a simple method to ask the recognizer to tell me what the current * input symbol is. */ - protected Object getCurrentInputSymbol() { return null; } + public abstract TSymbol getCurrentInputSymbol(); public void notifyListeners(String msg) { - notifyListeners((Token)getCurrentInputSymbol(), msg, null); + notifyListeners(getCurrentInputSymbol(), msg, null); } - public void notifyListeners(Token offendingToken, String msg, + public void notifyListeners(TSymbol offendingToken, String msg, @Nullable RecognitionException e) { - int line = offendingToken.getLine(); - int charPositionInLine = offendingToken.getCharPositionInLine(); - if ( _listeners==null || _listeners.size()==0 ) { + int line = -1; + int charPositionInLine = -1; + if (offendingToken instanceof Token) { + line = ((Token) offendingToken).getLine(); + charPositionInLine = ((Token) offendingToken).getCharPositionInLine(); + } + ANTLRErrorListener[] listeners = getListeners(); + if ( listeners.length == 0 ) { System.err.println("line "+line+":"+charPositionInLine+" "+msg); return; } - for (ANTLRErrorListener pl : _listeners) { + for (ANTLRErrorListener pl : listeners) { pl.error(this, offendingToken, line, charPositionInLine, msg, e); } } - public void enterOuterAlt(ParserRuleContext localctx, int altNum) { + public void enterOuterAlt(ParserRuleContext localctx, int altNum) { // if we have new localctx, make sure we replace existing ctx // that is previous child of parse tree if ( buildParseTrees && _ctx != localctx ) { @@ -197,8 +205,8 @@ public abstract class BaseRecognizer extends Recognizer { * If the parser is creating parse trees, the current symbol * would also be added as a child to the current context (node). */ - public Object consume() { - Object o = getCurrentInputSymbol(); + public TSymbol consume() { + TSymbol o = getCurrentInputSymbol(); getInputStream().consume(); if ( buildParseTrees ) { // TODO: tree parsers? @@ -219,22 +227,22 @@ public abstract class BaseRecognizer extends Recognizer { } } - public abstract void enterRule(ParserRuleContext localctx, int ruleIndex); + public abstract void enterRule(ParserRuleContext localctx, int ruleIndex); public void exitRule(int ruleIndex) { - _ctx = (ParserRuleContext)_ctx.parent; + _ctx = (ParserRuleContext)_ctx.parent; } - public ParserRuleContext getInvokingContext(int ruleIndex) { - ParserRuleContext p = _ctx; + public ParserRuleContext getInvokingContext(int ruleIndex) { + ParserRuleContext p = _ctx; while ( p!=null ) { if ( p.getRuleIndex() == ruleIndex ) return p; - p = (ParserRuleContext)p.parent; + p = (ParserRuleContext)p.parent; } return null; } - public ParserRuleContext getContext() { + public ParserRuleContext getContext() { return _ctx; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRErrorStrategy.java index e52a42e92..dd3c00a79 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRErrorStrategy.java @@ -29,13 +29,17 @@ package org.antlr.v4.runtime; +import com.sun.istack.internal.NotNull; import org.antlr.v4.runtime.atn.*; import org.antlr.v4.runtime.misc.IntervalSet; +import org.antlr.v4.runtime.tree.AST; +import org.antlr.v4.runtime.tree.ASTAdaptor; +import org.antlr.v4.runtime.tree.Tree; /** This is the default error handling mechanism for ANTLR parsers * and tree parsers. */ -public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { +public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { /** This is true after we see an error and before having successfully * matched a token. Prevents generation of more than one error message * per error. @@ -53,24 +57,24 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { protected IntervalSet lastErrorStates; @Override - public void beginErrorCondition(BaseRecognizer recognizer) { + public void beginErrorCondition(BaseRecognizer recognizer) { errorRecoveryMode = true; } @Override - public boolean inErrorRecoveryMode(BaseRecognizer recognizer) { + public boolean inErrorRecoveryMode(BaseRecognizer recognizer) { return errorRecoveryMode; } @Override - public void endErrorCondition(BaseRecognizer recognizer) { + public void endErrorCondition(BaseRecognizer recognizer) { errorRecoveryMode = false; lastErrorStates = null; lastErrorIndex = -1; } @Override - public void reportError(BaseRecognizer recognizer, + public void reportError(BaseRecognizer recognizer, RecognitionException e) throws RecognitionException { @@ -94,7 +98,7 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { else { System.err.println("unknown recognition error type: "+e.getClass().getName()); if ( recognizer!=null ) { - recognizer.notifyListeners(e.offendingToken, e.getMessage(), e); + recognizer.notifyListeners((TSymbol)e.offendingNode, e.getMessage(), e); } } } @@ -103,7 +107,7 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { * token that the match() routine could not recover from. */ @Override - public void recover(BaseRecognizer recognizer, RecognitionException e) { + public void recover(BaseRecognizer recognizer, RecognitionException e) { // System.out.println("recover in "+recognizer.getRuleInvocationStack()+ // " index="+recognizer.getInputStream().index()+ // ", lastErrorIndex="+ @@ -143,7 +147,7 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { * We opt to stay in the loop as long as possible. */ @Override - public void sync(BaseRecognizer recognizer) { + public void sync(BaseRecognizer recognizer) { ATNState s = recognizer._interp.atn.states.get(recognizer._ctx.s); // System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName()); // If already recovering, don't try to sync @@ -154,10 +158,10 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { // System.err.println("sync expecting: "+expecting); // TODO: subclass this class for treeparsers - TokenStream tokens = (TokenStream)recognizer.getInputStream(); - Token la = tokens.LT(1); + ObjectStream tokens = recognizer.getInputStream(); + int la = tokens.LA(1); // Return but don't end recovery. only do that upon valid token match - if ( la.getType()==Token.EOF || expecting.contains(la.getType()) ) return; + if ( la==Token.EOF || expecting.contains(la) ) return; if ( s instanceof PlusBlockStartState || s instanceof StarLoopEntryState || @@ -179,40 +183,45 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { // do nothing if we can't identify the exact kind of ATN state } - public void reportNoViableAlternative(BaseRecognizer recognizer, + public void reportNoViableAlternative(BaseRecognizer recognizer, NoViableAltException e) throws RecognitionException { - TokenStream tokens = (TokenStream)recognizer.getInputStream(); - String input = tokens.toString(e.startToken, e.offendingToken); + ObjectStream tokens = recognizer.getInputStream(); + String input; + if (tokens instanceof TokenStream) { + input = ((TokenStream)tokens).toString(e.startToken, e.offendingToken); + } else { + input = ""; + } String msg = "no viable alternative at input "+escapeWSAndQuote(input); - recognizer.notifyListeners(e.offendingToken, msg, e); + recognizer.notifyListeners((TSymbol)e.offendingNode, msg, e); } - public void reportInputMismatch(BaseRecognizer recognizer, + public void reportInputMismatch(BaseRecognizer recognizer, InputMismatchException e) throws RecognitionException { - String msg = "mismatched input "+getTokenErrorDisplay(e.offendingToken)+ + String msg = "mismatched input "+getTokenErrorDisplay((TSymbol)e.offendingNode)+ " expecting "+e.getExpectedTokens().toString(recognizer.getTokenNames()); - recognizer.notifyListeners(e.offendingToken, msg, e); + recognizer.notifyListeners((TSymbol)e.offendingNode, msg, e); } - public void reportFailedPredicate(BaseRecognizer recognizer, + public void reportFailedPredicate(BaseRecognizer recognizer, FailedPredicateException e) throws RecognitionException { String ruleName = recognizer.getRuleNames()[recognizer._ctx.getRuleIndex()]; String msg = "rule "+ruleName+" "+e.msg; - recognizer.notifyListeners(e.offendingToken, msg, e); + recognizer.notifyListeners((TSymbol)e.offendingNode, msg, e); } - public void reportUnwantedToken(BaseRecognizer recognizer) { + public void reportUnwantedToken(BaseRecognizer recognizer) { if (errorRecoveryMode) return; recognizer.syntaxErrors++; beginErrorCondition(recognizer); - Token t = (Token)recognizer.getCurrentInputSymbol(); + TSymbol t = recognizer.getCurrentInputSymbol(); String tokenName = getTokenErrorDisplay(t); IntervalSet expecting = getExpectedTokens(recognizer); String msg = "extraneous input "+tokenName+" expecting "+ @@ -220,12 +229,12 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { recognizer.notifyListeners(t, msg, null); } - public void reportMissingToken(BaseRecognizer recognizer) { + public void reportMissingToken(BaseRecognizer recognizer) { if (errorRecoveryMode) return; recognizer.syntaxErrors++; beginErrorCondition(recognizer); - Token t = (Token)recognizer.getCurrentInputSymbol(); + TSymbol t = recognizer.getCurrentInputSymbol(); IntervalSet expecting = getExpectedTokens(recognizer); String msg = "missing "+expecting.toString(recognizer.getTokenNames())+ " at "+getTokenErrorDisplay(t); @@ -263,11 +272,11 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { * reference in rule atom. It can assume that you forgot the ')'. */ @Override - public Object recoverInline(BaseRecognizer recognizer) + public TSymbol recoverInline(BaseRecognizer recognizer) throws RecognitionException { // SINGLE TOKEN DELETION - Object matchedSymbol = singleTokenDeletion(recognizer); + TSymbol matchedSymbol = singleTokenDeletion(recognizer); if ( matchedSymbol!=null ) { // we have deleted the extra token. // now, move past ttype token as if all were ok @@ -285,8 +294,8 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { } // if next token is what we are looking for then "delete" this token - public boolean singleTokenInsertion(BaseRecognizer recognizer) { - Object currentSymbol = recognizer.getCurrentInputSymbol(); + public boolean singleTokenInsertion(BaseRecognizer recognizer) { + int currentSymbolType = recognizer.getInputStream().LA(1); // if current token is consistent with what could come after current // ATN state, then we know we're missing a token; error recovery // is free to conjure up and insert the missing token @@ -294,14 +303,14 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { ATNState next = currentState.transition(0).target; IntervalSet expectingAtLL2 = recognizer._interp.atn.nextTokens(next, recognizer._ctx); // System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames())); - if ( expectingAtLL2.contains(((Token)currentSymbol).getType()) ) { + if ( expectingAtLL2.contains(currentSymbolType) ) { reportMissingToken(recognizer); return true; } return false; } - public Object singleTokenDeletion(BaseRecognizer recognizer) { + public TSymbol singleTokenDeletion(BaseRecognizer recognizer) { int nextTokenType = recognizer.getInputStream().LA(2); IntervalSet expecting = getExpectedTokens(recognizer); if ( expecting.contains(nextTokenType) ) { @@ -314,7 +323,7 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { */ recognizer.consume(); // simply delete extra token // we want to return the token we're actually matching - Object matchedSymbol = recognizer.getCurrentInputSymbol(); + TSymbol matchedSymbol = recognizer.getCurrentInputSymbol(); endErrorCondition(recognizer); // we know current token is correct return matchedSymbol; } @@ -340,14 +349,19 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { * If you change what tokens must be created by the lexer, * override this method to create the appropriate tokens. */ - protected Object getMissingSymbol(BaseRecognizer recognizer) { + protected TSymbol getMissingSymbol(BaseRecognizer recognizer) { + TSymbol currentSymbol = recognizer.getCurrentInputSymbol(); + if (!(currentSymbol instanceof Token)) { + throw new UnsupportedOperationException("This error strategy only supports Token symbols."); + } + IntervalSet expecting = getExpectedTokens(recognizer); int expectedTokenType = expecting.getMinElement(); // get any element - String tokenText = null; + String tokenText; if ( expectedTokenType== Token.EOF ) tokenText = ""; else tokenText = ""; CommonToken t = new CommonToken(expectedTokenType, tokenText); - Token current = (Token)recognizer.getCurrentInputSymbol(); + Token current = (Token)currentSymbol; if ( current.getType() == Token.EOF ) { current = ((TokenStream)recognizer.getInputStream()).LT(-1); } @@ -356,10 +370,10 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { t.channel = Token.DEFAULT_CHANNEL; t.source = current.getTokenSource(); t.index = -1; // indicate we conjured this up because it has no index - return t; + return (TSymbol)t; } - public IntervalSet getExpectedTokens(BaseRecognizer recognizer) { + public IntervalSet getExpectedTokens(BaseRecognizer recognizer) { return recognizer.getExpectedTokens(); } @@ -371,20 +385,40 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { * your token objects because you don't have to go modify your lexer * so that it creates a new Java type. */ - public String getTokenErrorDisplay(Token t) { + public String getTokenErrorDisplay(TSymbol t) { if ( t==null ) return ""; - String s = t.getText(); + String s = getSymbolText(t); if ( s==null ) { - if ( t.getType()==Token.EOF ) { + if ( getSymbolType(t)==Token.EOF ) { s = ""; } else { - s = "<"+t.getType()+">"; + s = "<"+getSymbolType(t)+">"; } } return escapeWSAndQuote(s); } + protected String getSymbolText(@NotNull TSymbol symbol) { + if (symbol instanceof Token) { + return ((Token)symbol).getText(); + } else if (symbol instanceof AST) { + return ((AST)symbol).getText(); + } else { + return symbol.toString(); + } + } + + protected int getSymbolType(@NotNull TSymbol symbol) { + if (symbol instanceof Token) { + return ((Token)symbol).getType(); + } else if (symbol instanceof AST) { + return ((AST)symbol).getType(); + } else { + return Token.INVALID_TYPE; + } + } + protected String escapeWSAndQuote(String s) { // if ( s==null ) return s; s = s.replaceAll("\n","\\\\n"); @@ -485,7 +519,7 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { * Like Grosch I implement context-sensitive FOLLOW sets that are combined * at run-time upon error to avoid overhead during parsing. */ - protected IntervalSet getErrorRecoverySet(BaseRecognizer recognizer) { + protected IntervalSet getErrorRecoverySet(BaseRecognizer recognizer) { ATN atn = recognizer._interp.atn; RuleContext ctx = recognizer._ctx; IntervalSet recoverSet = new IntervalSet(); @@ -502,7 +536,7 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy { } /** Consume tokens until one matches the given token set */ - public void consumeUntil(BaseRecognizer recognizer, IntervalSet set) { + public void consumeUntil(BaseRecognizer recognizer, IntervalSet set) { // System.err.println("consumeUntil("+set.toString(recognizer.getTokenNames())+")"); int ttype = recognizer.getInputStream().LA(1); while (ttype != Token.EOF && !set.contains(ttype) ) { diff --git a/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRTreeGrammarErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRTreeGrammarErrorStrategy.java index 286369af8..6b8ee1349 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRTreeGrammarErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/DefaultANTLRTreeGrammarErrorStrategy.java @@ -34,18 +34,18 @@ import org.antlr.v4.runtime.tree.gui.TreeViewer; import java.util.*; -public class DefaultANTLRTreeGrammarErrorStrategy extends DefaultANTLRErrorStrategy { +public class DefaultANTLRTreeGrammarErrorStrategy extends DefaultANTLRErrorStrategy { @Override - public void beginErrorCondition(BaseRecognizer recognizer) { + public void beginErrorCondition(BaseRecognizer recognizer) { } @Override - public void reportError(BaseRecognizer recognizer, RecognitionException e) + public void reportError(BaseRecognizer recognizer, RecognitionException e) throws RecognitionException { super.reportError(recognizer, e); TreeParser parser = (TreeParser)recognizer; - ASTNodeStream input = parser.getInputStream(); + ASTNodeStream input = parser.getInputStream(); Object root = input.getTreeSource(); // If instanceof Tree, we can show in TreeViewer if ( root instanceof Tree ) { @@ -67,15 +67,15 @@ public class DefaultANTLRTreeGrammarErrorStrategy extends DefaultANTLRErrorSt } @Override - public void reportNoViableAlternative(BaseRecognizer recognizer, + public void reportNoViableAlternative(BaseRecognizer recognizer, NoViableAltException e) throws RecognitionException { TreeParser parser = (TreeParser)recognizer; - ASTNodeStream input = parser.getInputStream(); + ASTNodeStream input = parser.getInputStream(); List unmatchedNodes = getNodeList(input, (NoViableTreeGrammarAltException)e); - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); ASTAdaptor adap = input.getTreeAdaptor(); for (int i = 0; i < unmatchedNodes.size(); i++) { if ( i>0 ) buf.append(" "); @@ -84,10 +84,10 @@ public class DefaultANTLRTreeGrammarErrorStrategy extends DefaultANTLRErrorSt } String s = buf.toString(); String msg = "no viable alternative at node(s) "+escapeWSAndQuote(s); - recognizer.notifyListeners(e.offendingToken, msg, e); + recognizer.notifyListeners((T)e.offendingNode, msg, e); } - protected List getNodeList(ASTNodeStream input, + protected List getNodeList(ASTNodeStream input, NoViableTreeGrammarAltException nva) { List unmatchedNodes; @@ -113,27 +113,27 @@ public class DefaultANTLRTreeGrammarErrorStrategy extends DefaultANTLRErrorSt } @Override - public Object recoverInline(BaseRecognizer recognizer) throws RecognitionException { + public T recoverInline(BaseRecognizer recognizer) throws RecognitionException { InputMismatchException e = new InputMismatchException(recognizer); reportError(recognizer, e); throw e; } @Override - public void recover(BaseRecognizer recognizer, RecognitionException e) { + public void recover(BaseRecognizer recognizer, RecognitionException e) { throw new RuntimeException(e); } @Override - public void sync(BaseRecognizer recognizer) { + public void sync(BaseRecognizer recognizer) { } @Override - public boolean inErrorRecoveryMode(BaseRecognizer recognizer) { + public boolean inErrorRecoveryMode(BaseRecognizer recognizer) { return false; } @Override - public void endErrorCondition(BaseRecognizer recognizer) { + public void endErrorCondition(BaseRecognizer recognizer) { } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java b/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java index a48e75063..41c4608ee 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/FailedPredicateException.java @@ -42,11 +42,11 @@ public class FailedPredicateException extends RecognitionException { public int predIndex; public String msg; - public FailedPredicateException(BaseRecognizer recognizer) { + public FailedPredicateException(BaseRecognizer recognizer) { this(recognizer, null); } - public FailedPredicateException(BaseRecognizer recognizer, @Nullable String msg) { + public FailedPredicateException(BaseRecognizer recognizer, @Nullable String msg) { super(recognizer, recognizer.getInputStream(), recognizer._ctx); ATNState s = recognizer._interp.atn.states.get(recognizer._ctx.s); PredicateTransition trans = (PredicateTransition)s.transition(0); @@ -54,8 +54,8 @@ public class FailedPredicateException extends RecognitionException { predIndex = trans.predIndex; this.msg = msg; Object la = recognizer.getCurrentInputSymbol(); + this.offendingNode = la; if ( la instanceof AST) { - this.offendingNode = la; this.offendingToken = ((AST)la).getPayload(); } else { diff --git a/runtime/Java/src/org/antlr/v4/runtime/InputMismatchException.java b/runtime/Java/src/org/antlr/v4/runtime/InputMismatchException.java index a8af6751a..2a0c4c800 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/InputMismatchException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/InputMismatchException.java @@ -6,11 +6,11 @@ import org.antlr.v4.runtime.tree.AST; * when the current input does not match the expected token or tree node. */ public class InputMismatchException extends RecognitionException { - public InputMismatchException(BaseRecognizer recognizer) { + public InputMismatchException(BaseRecognizer recognizer) { super(recognizer, recognizer.getInputStream(), recognizer._ctx); Object la = recognizer.getCurrentInputSymbol(); + this.offendingNode = la; if ( la instanceof AST ) { - this.offendingNode = la; this.offendingToken = ((AST)la).getPayload(); } else { diff --git a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java index e0c72a413..23f32ae67 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java @@ -38,7 +38,7 @@ import java.util.EmptyStackException; * uses simplified match() and error recovery mechanisms in the interest * of speed. */ -public abstract class Lexer extends Recognizer +public abstract class Lexer extends Recognizer implements TokenSource { public static final int DEFAULT_MODE = 0; @@ -313,13 +313,14 @@ public abstract class Lexer extends Recognizer public void notifyListeners(LexerNoViableAltException e) { String msg = "token recognition error at: '"+ input.substring(tokenStartCharIndex,input.index())+"'"; - if ( _listeners==null || _listeners.size()==0 ) { + ANTLRErrorListener[] listeners = getListeners(); + if ( listeners.length == 0 ) { System.err.println("line "+tokenStartLine+":"+ tokenStartCharPositionInLine+" "+ msg); return; } - for (ANTLRErrorListener pl : _listeners) { + for (ANTLRErrorListener pl : listeners) { pl.error(this, null, tokenStartLine, tokenStartCharPositionInLine, msg, e); } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java b/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java index 53addfbfb..60ac61012 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java @@ -45,24 +45,27 @@ public class NoViableAltException extends RecognitionException { */ public Token startToken; - public NoViableAltException(BaseRecognizer recognizer) { // LL(1) error + public NoViableAltException(BaseRecognizer recognizer) { // LL(1) error this(recognizer,recognizer.getInputStream(), - (Token)recognizer.getCurrentInputSymbol(), - (Token)recognizer.getCurrentInputSymbol(), + recognizer.getCurrentInputSymbol(), + recognizer.getCurrentInputSymbol(), + recognizer.getCurrentInputSymbol(), null, recognizer._ctx); } - public NoViableAltException(BaseRecognizer recognizer, - IntStream input, + public NoViableAltException(BaseRecognizer recognizer, + ObjectStream input, Token startToken, Token offendingToken, + T offendingNode, OrderedHashSet deadEndConfigs, RuleContext ctx) { super(recognizer, input, ctx); this.deadEndConfigs = deadEndConfigs; this.startToken = startToken; + this.offendingNode = offendingNode; this.offendingToken = offendingToken; } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/NoViableTreeGrammarAltException.java b/runtime/Java/src/org/antlr/v4/runtime/NoViableTreeGrammarAltException.java index 54d664d8b..2128e20b0 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/NoViableTreeGrammarAltException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/NoViableTreeGrammarAltException.java @@ -32,31 +32,31 @@ package org.antlr.v4.runtime; import org.antlr.v4.runtime.atn.ATNConfig; import org.antlr.v4.runtime.misc.OrderedHashSet; import org.antlr.v4.runtime.tree.ASTNodeStream; +import org.antlr.v4.runtime.tree.TreeParser; public class NoViableTreeGrammarAltException extends NoViableAltException { protected Object startNode; - protected Object offendingNode; - public NoViableTreeGrammarAltException(BaseRecognizer recognizer) { + public NoViableTreeGrammarAltException(TreeParser recognizer) { this(recognizer, - (ASTNodeStream)recognizer.getInputStream(), + recognizer.getInputStream(), recognizer.getCurrentInputSymbol(), recognizer.getCurrentInputSymbol(), null, recognizer._ctx); } - public NoViableTreeGrammarAltException(BaseRecognizer recognizer, - ASTNodeStream input, - Object startNode, - Object offendingNode, + public NoViableTreeGrammarAltException(BaseRecognizer recognizer, + ASTNodeStream input, + T startNode, + T offendingNode, OrderedHashSet deadEndConfigs, RuleContext ctx) { super(recognizer, input, input.getTreeAdaptor().getToken(startNode), input.getTreeAdaptor().getToken(offendingNode), + offendingNode, deadEndConfigs, ctx); this.startNode = startNode; - this.offendingNode = offendingNode; } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index 134b8b26e..7d9391944 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -29,15 +29,10 @@ package org.antlr.v4.runtime; -import org.antlr.v4.runtime.tree.ASTAdaptor; -import org.antlr.v4.runtime.tree.CommonASTAdaptor; - /** A parser for TokenStreams. "parser grammars" result in a subclass * of this. */ -public class Parser extends BaseRecognizer { - public ASTAdaptor _adaptor = new CommonASTAdaptor(); - +public class Parser extends BaseRecognizer { protected TokenStream _input; public Parser(TokenStream input) { @@ -60,7 +55,7 @@ public class Parser extends BaseRecognizer { * to get trace facilities. */ @Override - public void enterRule(ParserRuleContext localctx, int ruleIndex) { + public void enterRule(ParserRuleContext localctx, int ruleIndex) { _ctx = localctx; _ctx.start = _input.LT(1); _ctx.ruleIndex = ruleIndex; @@ -69,12 +64,12 @@ public class Parser extends BaseRecognizer { @Override public Token match(int ttype) throws RecognitionException { - return (Token)super.match(ttype); + return super.match(ttype); } @Override - protected Object getCurrentInputSymbol() { - return ((TokenStream)_input).LT(1); + public Token getCurrentInputSymbol() { + return _input.LT(1); } @Override @@ -91,7 +86,7 @@ public class Parser extends BaseRecognizer { } public TokenStream getTokenStream() { - return ((TokenStream)_input); + return _input; } @Override diff --git a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java index 57d8d9b87..d49ba5103 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java @@ -48,9 +48,8 @@ import org.stringtemplate.v4.ST; * group values such as this aggregate. The getters/setters are there to * satisfy the superclass interface. */ -public class ParserRuleContext extends RuleContext { - public Token start, stop; - public Object tree; +public class ParserRuleContext extends RuleContext { + public SymbolType start, stop; public ST st; /** Set during parsing to identify which rule parser is in. */ @@ -63,7 +62,7 @@ public class ParserRuleContext extends RuleContext { /** COPY a ctx */ - public void copyFrom(ParserRuleContext ctx) { + public void copyFrom(ParserRuleContext ctx) { // from RuleContext this.parent = ctx.parent; this.s = ctx.s; @@ -71,7 +70,6 @@ public class ParserRuleContext extends RuleContext { this.start = ctx.start; this.stop = ctx.stop; - this.tree = ctx.tree; this.st = ctx.st; this.ruleIndex = ctx.ruleIndex; } @@ -83,8 +81,7 @@ public class ParserRuleContext extends RuleContext { @Override public int getRuleIndex() { return ruleIndex; } - public Object getTree() { return tree; } public ST getTemplate() { return st; } - public Token getStart() { return start; } - public Token getStop() { return stop; } + public SymbolType getStart() { return start; } + public SymbolType getStop() { return stop; } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java b/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java index 0f06d9288..1ec3574fc 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/RecognitionException.java @@ -38,7 +38,7 @@ import org.antlr.v4.runtime.misc.IntervalSet; */ public class RecognitionException extends RuntimeException { /** Who threw the exception? */ - protected Recognizer recognizer; + protected Recognizer recognizer; // TODO: make a dummy recognizer for the interpreter to use? // Next two (ctx,input) should be what is in recognizer, but @@ -64,7 +64,7 @@ public class RecognitionException extends RuntimeException { protected int offendingState; - public RecognitionException(Recognizer recognizer, IntStream input, + public RecognitionException(Recognizer recognizer, IntStream input, RuleContext ctx) { this.recognizer = recognizer; @@ -82,8 +82,9 @@ public class RecognitionException extends RuntimeException { public int getOffendingState() { return offendingState; } public IntervalSet getExpectedTokens() { + // TODO: do we really need this type check? if ( recognizer!=null && recognizer instanceof BaseRecognizer) { - return ((BaseRecognizer)recognizer)._interp.atn.nextTokens(ctx); + return recognizer._interp.atn.nextTokens(ctx); } return null; } @@ -100,7 +101,7 @@ public class RecognitionException extends RuntimeException { return offendingToken; } - public Recognizer getRecognizer() { + public Recognizer getRecognizer() { return recognizer; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java index 45c68b1a3..786f97a59 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Recognizer.java @@ -29,15 +29,21 @@ package org.antlr.v4.runtime; +import com.sun.istack.internal.NotNull; +import com.sun.istack.internal.Nullable; import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNSimulator; import java.util.*; -public abstract class Recognizer { +public abstract class Recognizer { public static final int EOF=-1; - protected ANTLRErrorStrategy _errHandler = new DefaultANTLRErrorStrategy(); - protected List _listeners; + protected ANTLRErrorStrategy _errHandler = new DefaultANTLRErrorStrategy(); + + private List> _listeners; + + private static final ANTLRErrorListener[] EMPTY_LISTENERS = new ANTLRErrorListener[0]; protected ATNInterpreter _interp; @@ -194,32 +200,38 @@ public abstract class Recognizer { return "'"+s+"'"; } - public void addListener(ANTLRErrorListener pl) { + public void addListener(ANTLRErrorListener pl) { if ( _listeners ==null ) { _listeners = - Collections.synchronizedList(new ArrayList(2)); + Collections.synchronizedList(new ArrayList>(2)); } if ( pl!=null ) _listeners.add(pl); } - public void removeListener(ANTLRErrorListener pl) { _listeners.remove(pl); } + public void removeListener(ANTLRErrorListener pl) { _listeners.remove(pl); } public void removeListeners() { _listeners.clear(); } - public List getListeners() { return _listeners; } + public @NotNull ANTLRErrorListener[] getListeners() { + if (_listeners == null) { + return EMPTY_LISTENERS; + } - public ANTLRErrorStrategy getErrorHandler() { return _errHandler; } + return _listeners.toArray(EMPTY_LISTENERS); + } - public void setErrorHandler(ANTLRErrorStrategy h) { this._errHandler = h; } + public ANTLRErrorStrategy getErrorHandler() { return _errHandler; } + + public void setErrorHandler(ANTLRErrorStrategy h) { this._errHandler = h; } // subclass needs to override these if there are sempreds or actions // that the ATN interp needs to execute - public boolean sempred(RuleContext _localctx, int ruleIndex, int actionIndex) { + public boolean sempred(@Nullable RuleContext _localctx, int ruleIndex, int actionIndex) { return true; } /** In lexer, both indexes are same; one action per rule. */ - public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { + public void action(@Nullable RuleContext _localctx, int ruleIndex, int actionIndex) { } /** Create context for a rule reference IN fromRuleIndex using parent _localctx. diff --git a/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java index b642313f3..baaf37247 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java @@ -310,18 +310,18 @@ public class RuleContext implements ParseTree.RuleNode { return new Interval(start, stop); } - public void inspect(BaseRecognizer parser) { + public void inspect(BaseRecognizer parser) { TreeViewer viewer = new TreeViewer(parser, this); viewer.open(); } - public void save(BaseRecognizer parser, String fileName) + public void save(BaseRecognizer parser, String fileName) throws IOException, PrintException { Trees.writePS(this, parser, fileName); } - public void save(BaseRecognizer parser, String fileName, + public void save(BaseRecognizer parser, String fileName, String fontName, int fontSize) throws IOException { @@ -332,25 +332,25 @@ public class RuleContext implements ParseTree.RuleNode { * (root child1 .. childN). Print just a node if this is a leaf. * We have to know the recognizer so we can get rule names. */ - public String toStringTree(BaseRecognizer recog) { + public String toStringTree(BaseRecognizer recog) { return Trees.toStringTree(this, recog); } @Override public String toStringTree() { return toStringTree(null); } - public void enterRule(ParseTreeListener listener) { } - public void exitRule(ParseTreeListener listener) { } + public void enterRule(ParseTreeListener listener) { } + public void exitRule(ParseTreeListener listener) { } public String toString() { return toString(null); } - public String toString(BaseRecognizer recog) { + public String toString(BaseRecognizer recog) { return toString(recog, RuleContext.EMPTY); } - public String toString(BaseRecognizer recog, RuleContext stop) { + public String toString(BaseRecognizer recog, RuleContext stop) { StringBuilder buf = new StringBuilder(); RuleContext p = this; buf.append("["); diff --git a/runtime/Java/src/org/antlr/v4/runtime/TreeParserRuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/TreeParserRuleContext.java index 78102306c..61e0079c6 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/TreeParserRuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/TreeParserRuleContext.java @@ -1,19 +1,6 @@ package org.antlr.v4.runtime; -import org.stringtemplate.v4.ST; - -public class TreeParserRuleContext extends ParserRuleContext { - // TODO: heh, these are duplicates of the fields above! - public Object start, stop; - public Object tree; - public ST st; - - /** Set during parsing to identify which rule parser is in. */ - public int ruleIndex; - - /** Set during parsing to identify which alt of rule parser is in. */ - public int altNum; - +public class TreeParserRuleContext extends ParserRuleContext { public TreeParserRuleContext() { super(); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java index c19123752..7fd0753eb 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java @@ -142,7 +142,7 @@ public class ATNConfig { return toString(null, true); } - public String toString(Recognizer recog, boolean showAlt) { + public String toString(Recognizer recog, boolean showAlt) { StringBuilder buf = new StringBuilder(); // if ( state.ruleIndex>=0 ) { // if ( recog!=null ) buf.append(recog.getRuleNames()[state.ruleIndex]+":"); diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java index e9792460f..43fb6583e 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java @@ -37,7 +37,7 @@ import org.stringtemplate.v4.misc.MultiMap; import java.util.*; -public class ParserATNSimulator extends ATNSimulator { +public class ParserATNSimulator extends ATNSimulator { public static boolean debug = false; public static boolean dfa_debug = false; @@ -47,7 +47,7 @@ public class ParserATNSimulator extends ATNSimulator { public static int retry_with_context_indicates_no_conflict = 0; - protected BaseRecognizer parser; + protected BaseRecognizer parser; public Map ctxToDFAs; public Map[] decisionToDFAPerCtx; // TODO: USE THIS ONE @@ -73,7 +73,7 @@ public class ParserATNSimulator extends ATNSimulator { decisionToDFA = new DFA[atn.getNumberOfDecisions()]; } - public ParserATNSimulator(BaseRecognizer parser, ATN atn) { + public ParserATNSimulator(BaseRecognizer parser, ATN atn) { super(atn); this.parser = parser; ctxToDFAs = new HashMap(); @@ -83,7 +83,7 @@ public class ParserATNSimulator extends ATNSimulator { // System.out.println(dot.getDOT(atn.rules.get(1), parser.getRuleNames())); } - public int adaptivePredict(ObjectStream input, int decision, RuleContext outerContext) { + public int adaptivePredict(ObjectStream input, int decision, RuleContext outerContext) { predict_calls++; DFA dfa = decisionToDFA[decision]; if ( dfa==null || dfa.s0==null ) { @@ -108,7 +108,7 @@ public class ParserATNSimulator extends ATNSimulator { } } - public int predictATN(DFA dfa, ObjectStream input, + public int predictATN(DFA dfa, ObjectStream input, RuleContext outerContext, boolean useContext) { @@ -146,7 +146,7 @@ public class ParserATNSimulator extends ATNSimulator { } // doesn't create DFA when matching - public int matchATN(ObjectStream input, ATNState startState) { + public int matchATN(ObjectStream input, ATNState startState) { DFA dfa = new DFA(startState); if ( outerContext==null ) outerContext = RuleContext.EMPTY; RuleContext ctx = RuleContext.EMPTY; @@ -154,7 +154,7 @@ public class ParserATNSimulator extends ATNSimulator { return execATN(input, dfa, input.index(), s0_closure, false); } - public int execDFA(ObjectStream input, DFA dfa, DFAState s0, RuleContext outerContext) { + public int execDFA(ObjectStream input, DFA dfa, DFAState s0, RuleContext outerContext) { // dump(dfa); if ( outerContext==null ) outerContext = RuleContext.EMPTY; this.outerContext = outerContext; @@ -241,17 +241,17 @@ public class ParserATNSimulator extends ATNSimulator { return prevAcceptState.prediction; } - public String getInputString(ObjectStream input, int start) { + public String getInputString(ObjectStream input, int start) { if ( input instanceof TokenStream ) { return ((TokenStream)input).toString(start,input.index()); } else if ( input instanceof ASTNodeStream) { - return ((ASTNodeStream)input).toString(start,input.index()); + return ((ASTNodeStream)input).toString(input.get(start),input.LT(1)); } return "n/a"; } - public int execATN(ObjectStream input, + public int execATN(ObjectStream input, DFA dfa, int startIndex, OrderedHashSet s0, @@ -405,7 +405,7 @@ public class ParserATNSimulator extends ATNSimulator { return exitAlt; } - public int retryWithContext(ObjectStream input, + public int retryWithContext(ObjectStream input, DFA dfa, int startIndex, RuleContext originalContext, @@ -823,7 +823,7 @@ public class ParserATNSimulator extends ATNSimulator { return String.valueOf(t); } - public String getLookaheadName(ObjectStream input) { + public String getLookaheadName(ObjectStream input) { return getTokenName(input.LA(1)); } @@ -849,16 +849,16 @@ public class ParserATNSimulator extends ATNSimulator { } } - public int throwNoViableAlt(ObjectStream input, RuleContext outerContext, + public int throwNoViableAlt(ObjectStream input, RuleContext outerContext, OrderedHashSet configs, int startIndex) { if ( parser instanceof TreeParser) { - Object startNode = null; + TSymbol startNode = null; if ( input instanceof BufferedASTNodeStream ) { startNode = input.get(startIndex); } throw new NoViableTreeGrammarAltException(parser, - (ASTNodeStream)input, + (ASTNodeStream)input, startNode, input.LT(1), configs, outerContext); @@ -867,6 +867,7 @@ public class ParserATNSimulator extends ATNSimulator { throw new NoViableAltException(parser, input, (Token)input.get(startIndex), (Token)input.LT(1), + input.LT(1), configs, outerContext); } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/ASTContext.java b/runtime/Java/src/org/antlr/v4/runtime/tree/ASTContext.java new file mode 100644 index 000000000..3503bd03e --- /dev/null +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/ASTContext.java @@ -0,0 +1,34 @@ +/* + [The "BSD license"] + Copyright (c) 2011 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.tree; + +public interface ASTContext { + T getTree(); +} diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/BaseAST.java b/runtime/Java/src/org/antlr/v4/runtime/tree/BaseAST.java index 07062e52e..ada0fe66c 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/BaseAST.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/BaseAST.java @@ -258,18 +258,18 @@ public abstract class BaseAST implements AST { */ public List getAncestors() { return Trees.getAncestors(this); } - public void inspect(BaseRecognizer parser) { + public void inspect(BaseRecognizer parser) { TreeViewer viewer = new TreeViewer(parser, this); viewer.open(); } - public void save(BaseRecognizer parser, String fileName) + public void save(BaseRecognizer parser, String fileName) throws IOException { Trees.writePS(this, parser, fileName); } - public void save(BaseRecognizer parser, String fileName, + public void save(BaseRecognizer parser, String fileName, String fontName, int fontSize) throws IOException { diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeListener.java b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeListener.java index cff13b965..7813c54a9 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeListener.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeListener.java @@ -32,8 +32,8 @@ package org.antlr.v4.runtime.tree; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; -public interface ParseTreeListener { +public interface ParseTreeListener { void visitToken(Token token); - void enterEveryRule(ParserRuleContext ctx); - void exitEveryRule(ParserRuleContext ctx); + void enterEveryRule(ParserRuleContext ctx); + void exitEveryRule(ParserRuleContext ctx); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeWalker.java b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeWalker.java index 57c096dfb..16ba01b54 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeWalker.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeWalker.java @@ -34,7 +34,7 @@ import org.antlr.v4.runtime.ParserRuleContext; public class ParseTreeWalker { public static final ParseTreeWalker DEFAULT = new ParseTreeWalker(); - public void walk(ParseTreeListener listener, ParseTree t) { + public void walk(ParseTreeListener listener, ParseTree t) { if ( t instanceof ParseTree.TokenNode) { visitToken(listener, (ParseTree.TokenNode) t); return; @@ -48,7 +48,7 @@ public class ParseTreeWalker { exitRule(listener, r); } - protected void visitToken(ParseTreeListener listener, ParseTree.TokenNode t) { + protected void visitToken(ParseTreeListener listener, ParseTree.TokenNode t) { listener.visitToken(t.getToken()); } @@ -57,14 +57,14 @@ public class ParseTreeWalker { * First we trigger the generic and then the rule specific. * We to them in reverse order upon finishing the node. */ - protected void enterRule(ParseTreeListener listener, ParseTree.RuleNode r) { - ParserRuleContext ctx = (ParserRuleContext)r.getRuleContext(); - listener.enterEveryRule((ParserRuleContext) r.getRuleContext()); + protected void enterRule(ParseTreeListener listener, ParseTree.RuleNode r) { + ParserRuleContext ctx = (ParserRuleContext)r.getRuleContext(); + listener.enterEveryRule((ParserRuleContext) r.getRuleContext()); ctx.enterRule(listener); } - protected void exitRule(ParseTreeListener listener, ParseTree.RuleNode r) { - ParserRuleContext ctx = (ParserRuleContext)r.getRuleContext(); + protected void exitRule(ParseTreeListener listener, ParseTree.RuleNode r) { + ParserRuleContext ctx = (ParserRuleContext)r.getRuleContext(); ctx.exitRule(listener); listener.exitEveryRule(ctx); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeFilter.java b/runtime/Java/src/org/antlr/v4/runtime/tree/TreeFilter.java index 38a8b29c8..9f18c7d0a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeFilter.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/TreeFilter.java @@ -75,7 +75,7 @@ or both. In our case, we need to call @m applyOnce in both. On the way down, we'll look for @r vmult patterns. On the way up, we'll look for @r mult0 patterns. */ -public class TreeFilter extends TreeParser { +public class TreeFilter extends TreeParser { public interface fptr { public void rule() throws RecognitionException; } @@ -94,15 +94,15 @@ public class TreeFilter extends TreeParser { try { // share TreeParser object but not parsing-related state _input = new CommonASTNodeStream(originalAdaptor, t); - ((CommonASTNodeStream) _input).setTokenStream(originalTokenStream); + ((CommonASTNodeStream) _input).setTokenStream(originalTokenStream); whichRule.rule(); } catch (RecognitionException e) { } } public void downup(T t) { - TreeVisitor v = new TreeVisitor(new CommonASTAdaptor()); - TreeVisitorAction actions = new TreeVisitorAction() { + TreeVisitor v = new TreeVisitor((ASTAdaptor)new CommonASTAdaptor()); + TreeVisitorAction actions = new TreeVisitorAction() { @Override public T pre(T t) { applyOnce(t, topdown_fptr); return t; } @Override diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeParser.java b/runtime/Java/src/org/antlr/v4/runtime/tree/TreeParser.java index 9dda63caf..f5952cce6 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeParser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/TreeParser.java @@ -37,7 +37,7 @@ import java.util.regex.*; * of this. All the error reporting and recovery is shared with Parser via * the BaseRecognizer superclass. */ -public class TreeParser extends BaseRecognizer { +public class TreeParser extends BaseRecognizer { public static final int DOWN = Token.DOWN; public static final int UP = Token.UP; @@ -65,7 +65,7 @@ public class TreeParser extends BaseRecognizer { } @Override - protected T getCurrentInputSymbol() { return _input.LT(1); } + public T getCurrentInputSymbol() { return _input.LT(1); } @Override public ASTNodeStream getInputStream() { return _input; } @@ -79,13 +79,14 @@ public class TreeParser extends BaseRecognizer { * * This is flexible because users do not have to regenerate parsers * to get trace facilities. + * + * TODO: this shouldn't be needed now that ParserRuleContext is generic. */ @Override - public void enterRule(ParserRuleContext localctx, int ruleIndex) { - TreeParserRuleContext tctx = (TreeParserRuleContext)localctx; - _ctx = tctx; - tctx.start = _input.LT(1); - tctx.ruleIndex = ruleIndex; + public void enterRule(ParserRuleContext localctx, int ruleIndex) { + _ctx = localctx; + _ctx.start = _input.LT(1); + _ctx.ruleIndex = ruleIndex; } @Override diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/TreePatternParser.java b/runtime/Java/src/org/antlr/v4/runtime/tree/TreePatternParser.java index 4573d9134..6b73ecc32 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/TreePatternParser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/TreePatternParser.java @@ -34,22 +34,23 @@ import org.antlr.v4.runtime.*; public class TreePatternParser { protected TreePatternLexer tokenizer; protected int ttype; - protected TreeWizard wizard; - protected ASTAdaptor adaptor; + protected TreeWizard wizard; + // TODO: would be nice to use ASTAdaptor... + protected ASTAdaptor adaptor; - public TreePatternParser(TreePatternLexer tokenizer, TreeWizard wizard, ASTAdaptor adaptor) { + public TreePatternParser(TreePatternLexer tokenizer, TreeWizard wizard, ASTAdaptor adaptor) { this.tokenizer = tokenizer; this.wizard = wizard; this.adaptor = adaptor; ttype = tokenizer.nextToken(); // kickstart } - public Object pattern() { + public TreeWizard.TreePattern pattern() { if ( ttype==TreePatternLexer.BEGIN ) { return parseTree(); } else if ( ttype==TreePatternLexer.ID ) { - Object node = parseNode(); + TreeWizard.TreePattern node = parseNode(); if ( ttype==TreePatternLexer.EOF ) { return node; } @@ -58,12 +59,12 @@ public class TreePatternParser { return null; } - public Object parseTree() { + public TreeWizard.TreePattern parseTree() { if ( ttype != TreePatternLexer.BEGIN ) { throw new RuntimeException("no BEGIN"); } ttype = tokenizer.nextToken(); - Object root = parseNode(); + TreeWizard.TreePattern root = parseNode(); if ( root==null ) { return null; } @@ -73,11 +74,11 @@ public class TreePatternParser { ttype==TreePatternLexer.DOT ) { if ( ttype==TreePatternLexer.BEGIN ) { - Object subtree = parseTree(); + TreeWizard.TreePattern subtree = parseTree(); adaptor.addChild(root, subtree); } else { - Object child = parseNode(); + TreeWizard.TreePattern child = parseNode(); if ( child==null ) { return null; } @@ -91,7 +92,7 @@ public class TreePatternParser { return root; } - public Object parseNode() { + public TreeWizard.TreePattern parseNode() { // "%label:" prefix String label = null; if ( ttype == TreePatternLexer.PERCENT ) { @@ -126,7 +127,7 @@ public class TreePatternParser { String tokenName = tokenizer.sval.toString(); ttype = tokenizer.nextToken(); if ( tokenName.equals("nil") ) { - return adaptor.nil(); + return (TreeWizard.TreePattern)adaptor.nil(); } String text = tokenName; // check for arg @@ -142,13 +143,13 @@ public class TreePatternParser { if ( treeNodeType== Token.INVALID_TYPE ) { return null; } - Object node; - node = adaptor.create(treeNodeType, text); + TreeWizard.TreePattern node; + node = (TreeWizard.TreePattern)adaptor.create(treeNodeType, text); if ( label!=null && node.getClass()==TreeWizard.TreePattern.class ) { - ((TreeWizard.TreePattern)node).label = label; + node.label = label; } if ( arg!=null && node.getClass()==TreeWizard.TreePattern.class ) { - ((TreeWizard.TreePattern)node).hasTextArg = true; + node.hasTextArg = true; } return node; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeVisitor.java b/runtime/Java/src/org/antlr/v4/runtime/tree/TreeVisitor.java index 8ecc11001..921e99d61 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/TreeVisitor.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/TreeVisitor.java @@ -32,13 +32,14 @@ package org.antlr.v4.runtime.tree; /** Do a depth first walk of a tree, applying pre() and post() actions * as we discover and finish nodes. */ -public class TreeVisitor { - protected ASTAdaptor adaptor; +public class TreeVisitor { + protected ASTAdaptor adaptor; - public TreeVisitor(ASTAdaptor adaptor) { + public TreeVisitor(ASTAdaptor adaptor) { this.adaptor = adaptor; } - public TreeVisitor() { this(new CommonASTAdaptor()); } + + public TreeVisitor() { this((ASTAdaptor)new CommonASTAdaptor()); } /** Visit every node in tree t and trigger an action for each node * before/after having visited all of its children. @@ -50,16 +51,16 @@ public class TreeVisitor { * * Return result of applying post action to this node. */ - public Object visit(Object t, TreeVisitorAction action) { + public T visit(T t, TreeVisitorAction action) { // System.out.println("visit "+((Tree)t).toStringTree()); boolean isNil = adaptor.isNil(t); if ( action!=null && !isNil ) { t = action.pre(t); // if rewritten, walk children of new t } for (int i=0; i { + protected ASTAdaptor adaptor; + protected Map tokenNameToTypeMap; - public interface ContextVisitor { + public interface ContextVisitor { // TODO: should this be called visit or something else? - public void visit(Object t, Object parent, int childIndex, Map labels); + public void visit(T t, Object parent, int childIndex, @Nullable Map labels); } - public static abstract class Visitor implements ContextVisitor { - public void visit(Object t, Object parent, int childIndex, Map labels) { + public static abstract class Visitor implements ContextVisitor { + @Override + public void visit(T t, Object parent, int childIndex, Map labels) { visit(t); } - public abstract void visit(Object t); + public abstract void visit(T t); } /** When using %label:TOKENNAME in a tree for parse(), we must @@ -118,35 +120,35 @@ public class TreeWizard { protected Set tokenTypesToReverseIndex = null; */ - public TreeWizard(ASTAdaptor adaptor) { + public TreeWizard(ASTAdaptor adaptor) { this.adaptor = adaptor; } - public TreeWizard(ASTAdaptor adaptor, Map tokenNameToTypeMap) { + public TreeWizard(ASTAdaptor adaptor, Map tokenNameToTypeMap) { this.adaptor = adaptor; this.tokenNameToTypeMap = tokenNameToTypeMap; } - public TreeWizard(ASTAdaptor adaptor, String[] tokenNames) { + public TreeWizard(ASTAdaptor adaptor, String[] tokenNames) { this.adaptor = adaptor; this.tokenNameToTypeMap = computeTokenTypes(tokenNames); } public TreeWizard(String[] tokenNames) { - this(new CommonASTAdaptor(), tokenNames); + this((ASTAdaptor)new TreePatternASTAdaptor(), tokenNames); } /** Compute a Map that is an inverted index of * tokenNames (which maps int token types to names). */ - public Map computeTokenTypes(String[] tokenNames) { - Map m = new HashMap(); + public Map computeTokenTypes(String[] tokenNames) { + Map m = new HashMap(); if ( tokenNames==null ) { return m; } for (int ttype = Token.MIN_TOKEN_TYPE; ttype < tokenNames.length; ttype++) { String name = tokenNames[ttype]; - m.put(name, new Integer(ttype)); + m.put(name, ttype); } return m; } @@ -156,9 +158,9 @@ public class TreeWizard { if ( tokenNameToTypeMap==null ) { return Token.INVALID_TYPE; } - Integer ttypeI = (Integer)tokenNameToTypeMap.get(tokenName); + Integer ttypeI = tokenNameToTypeMap.get(tokenName); if ( ttypeI!=null ) { - return ttypeI.intValue(); + return ttypeI; } return Token.INVALID_TYPE; } @@ -170,36 +172,37 @@ public class TreeWizard { * * TODO: save this index so that find and visit are faster */ - public Map index(Object t) { - Map m = new HashMap(); + public Map> index(T t) { + Map> m = new HashMap>(); _index(t, m); return m; } /** Do the work for index */ - protected void _index(Object t, Map m) { + protected void _index(T t, Map> m) { if ( t==null ) { return; } int ttype = adaptor.getType(t); - List elements = (List)m.get(new Integer(ttype)); + List elements = m.get(ttype); if ( elements==null ) { - elements = new ArrayList(); - m.put(new Integer(ttype), elements); + elements = new ArrayList(); + m.put(ttype, elements); } elements.add(t); int n = adaptor.getChildCount(t); for (int i=0; i find(T t, int ttype) { + final List nodes = new ArrayList(); + visit(t, ttype, new TreeWizard.Visitor() { + @Override + public void visit(T t) { nodes.add(t); } }); @@ -207,13 +210,13 @@ public class TreeWizard { } /** Return a List of subtrees matching pattern. */ - public List find(Object t, String pattern) { - final List subtrees = new ArrayList(); + public List find(T t, String pattern) { + final List subtrees = new ArrayList(); // Create a TreePattern from the pattern TreePatternLexer tokenizer = new TreePatternLexer(pattern); TreePatternParser parser = new TreePatternParser(tokenizer, this, new TreePatternASTAdaptor()); - final TreePattern tpattern = (TreePattern)parser.pattern(); + final TreePattern tpattern = parser.pattern(); // don't allow invalid patterns if ( tpattern==null || tpattern.isNil() || @@ -222,8 +225,9 @@ public class TreeWizard { return null; } int rootTokenType = tpattern.getType(); - visit(t, rootTokenType, new TreeWizard.ContextVisitor() { - public void visit(Object t, Object parent, int childIndex, Map labels) { + visit(t, rootTokenType, new TreeWizard.ContextVisitor() { + @Override + public void visit(T t, Object parent, int childIndex, Map labels) { if ( _parse(t, tpattern, null) ) { subtrees.add(t); } @@ -232,11 +236,11 @@ public class TreeWizard { return subtrees; } - public Object findFirst(Object t, int ttype) { + public T findFirst(T t, int ttype) { return null; } - public Object findFirst(Object t, String pattern) { + public T findFirst(T t, String pattern) { return null; } @@ -245,12 +249,12 @@ public class TreeWizard { * of the visitor action method is never set (it's null) since using * a token type rather than a pattern doesn't let us set a label. */ - public void visit(Object t, int ttype, ContextVisitor visitor) { + public void visit(T t, int ttype, ContextVisitor visitor) { _visit(t, null, 0, ttype, visitor); } /** Do the recursive work for visit */ - protected void _visit(Object t, Object parent, int childIndex, int ttype, ContextVisitor visitor) { + protected void _visit(T t, @Nullable Object parent, int childIndex, int ttype, ContextVisitor visitor) { if ( t==null ) { return; } @@ -259,7 +263,7 @@ public class TreeWizard { } int n = adaptor.getChildCount(t); for (int i=0; i visitor) { // Create a TreePattern from the pattern TreePatternLexer tokenizer = new TreePatternLexer(pattern); TreePatternParser parser = new TreePatternParser(tokenizer, this, new TreePatternASTAdaptor()); - final TreePattern tpattern = (TreePattern)parser.pattern(); + final TreePattern tpattern = parser.pattern(); // don't allow invalid patterns if ( tpattern==null || tpattern.isNil() || @@ -282,10 +286,11 @@ public class TreeWizard { { return; } - final Map labels = new HashMap(); // reused for each _parse + final Map labels = new HashMap(); // reused for each _parse int rootTokenType = tpattern.getType(); - visit(t, rootTokenType, new TreeWizard.ContextVisitor() { - public void visit(Object t, Object parent, int childIndex, Map unusedlabels) { + visit(t, rootTokenType, new TreeWizard.ContextVisitor() { + @Override + public void visit(T t, Object parent, int childIndex, Map unusedlabels) { // the unusedlabels arg is null as visit on token type doesn't set. labels.clear(); if ( _parse(t, tpattern, labels) ) { @@ -306,11 +311,11 @@ public class TreeWizard { * * TODO: what's a better way to indicate bad pattern? Exceptions are a hassle */ - public boolean parse(Object t, String pattern, Map labels) { + public boolean parse(T t, String pattern, @Nullable Map labels) { TreePatternLexer tokenizer = new TreePatternLexer(pattern); TreePatternParser parser = new TreePatternParser(tokenizer, this, new TreePatternASTAdaptor()); - TreePattern tpattern = (TreePattern)parser.pattern(); + TreePattern tpattern = parser.pattern(); /* System.out.println("t="+((Tree)t).toStringTree()); System.out.println("scant="+tpattern.toStringTree()); @@ -319,7 +324,7 @@ public class TreeWizard { return matched; } - public boolean parse(Object t, String pattern) { + public boolean parse(T t, String pattern) { return parse(t, pattern, null); } @@ -328,7 +333,7 @@ public class TreeWizard { * text arguments on nodes. Fill labels map with pointers to nodes * in tree matched against nodes in pattern with labels. */ - protected boolean _parse(Object t1, TreePattern tpattern, Map labels) { + protected boolean _parse(T t1, TreePattern tpattern, @Nullable Map labels) { // make sure both are non-null if ( t1==null || tpattern==null ) { return false; @@ -352,7 +357,7 @@ public class TreeWizard { return false; } for (int i=0; i boolean equals(T t1, T t2, ASTAdaptor adaptor) { return _equals(t1, t2, adaptor); } /** Compare type, structure, and text of two trees, assuming adaptor in * this instance of a TreeWizard. */ - public boolean equals(Object t1, Object t2) { + public boolean equals(T t1, T t2) { return _equals(t1, t2, adaptor); } - protected static boolean _equals(Object t1, Object t2, ASTAdaptor adaptor) { + protected static boolean _equals(T t1, T t2, ASTAdaptor adaptor) { // make sure both are non-null if ( t1==null || t2==null ) { return false; @@ -420,8 +425,8 @@ public class TreeWizard { return false; } for (int i=0; i recog, String fontName, int fontSize) { TreePostScriptGenerator psgen = @@ -52,11 +52,11 @@ public class Trees { return psgen.getPS(); } - public static String getPS(Tree t, BaseRecognizer recog) { + public static String getPS(Tree t, BaseRecognizer recog) { return getPS(t, recog, "Helvetica", 11); } - public static void writePS(Tree t, BaseRecognizer recog, + public static void writePS(Tree t, BaseRecognizer recog, String fileName, String fontName, int fontSize) throws IOException @@ -68,7 +68,7 @@ public class Trees { bw.close(); } - public static void writePS(Tree t, BaseRecognizer recog, String fileName) + public static void writePS(Tree t, BaseRecognizer recog, String fileName) throws IOException { writePS(t, recog, fileName, "Helvetica", 11); @@ -78,7 +78,7 @@ public class Trees { * node payloads to get the text for the nodes. Detect * parse trees and extract data appropriately. */ - public static String toStringTree(Tree t, BaseRecognizer recog) { + public static String toStringTree(Tree t, BaseRecognizer recog) { if ( t.getChildCount()==0 ) return getNodeText(t, recog); StringBuilder buf = new StringBuilder(); boolean nilRoot = t instanceof AST && ((AST)t).isNil(); @@ -97,7 +97,7 @@ public class Trees { return buf.toString(); } - public static String getNodeText(Tree t, BaseRecognizer recog) { + public static String getNodeText(Tree t, BaseRecognizer recog) { if ( t instanceof AST ) { return t.toString(); } @@ -174,7 +174,7 @@ public class Trees { int replacingHowMany = stopChildIndex - startChildIndex + 1; int replacingWithHowMany; BaseAST newTree = (BaseAST)t; - List newChildren = null; + List newChildren; // normalize to a list of children to add: newChildren if ( newTree.isNil() ) { newChildren = newTree.children; @@ -190,7 +190,7 @@ public class Trees { if ( delta == 0 ) { int j = 0; // index into new children for (int i=startChildIndex; i<=stopChildIndex; i++) { - BaseAST child = (BaseAST)newChildren.get(j); + BaseAST child = newChildren.get(j); tree.setChild(i, child); child.setParent(tree); child.setChildIndex(i); @@ -223,18 +223,18 @@ public class Trees { //System.out.println("out="+toStringTree()); } - public static AST dupTree(ASTAdaptor adaptor, AST t, AST parent) { + public static T dupTree(ASTAdaptor adaptor, T t, T parent) { if ( t==null ) { return null; } - AST newTree = (AST)adaptor.dupNode(t); + T newTree = adaptor.dupNode(t); // ensure new subtree root has parent/child index set adaptor.setChildIndex(newTree, adaptor.getChildIndex(t)); // same index in new tree adaptor.setParent(newTree, parent); int n = adaptor.getChildCount(t); for (int i = 0; i < n; i++) { - AST child = (AST)adaptor.getChild(t, i); - Object newSubTree = dupTree(adaptor, child, t); + T child = adaptor.getChild(t, i); + T newSubTree = dupTree(adaptor, child, t); adaptor.addChild(newTree, newSubTree); } return newTree; @@ -253,12 +253,12 @@ public class Trees { } int n = t.getChildCount(); for (int i = 0; i < n; i++) { - setUnknownTokenBoundaries((CommonAST) t.getChild(i)); + setUnknownTokenBoundaries(t.getChild(i)); } if ( t.startIndex>=0 && t.stopIndex>=0 ) return; // already set if ( t.getChildCount() > 0 ) { - CommonAST firstChild = (CommonAST)t.getChild(0); - CommonAST lastChild = (CommonAST)t.getChild(t.getChildCount()-1); + CommonAST firstChild = t.getChild(0); + CommonAST lastChild = t.getChild(t.getChildCount()-1); t.startIndex = firstChild.getTokenStartIndex(); t.stopIndex = lastChild.getTokenStopIndex(); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreePostScriptGenerator.java b/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreePostScriptGenerator.java index 3624fafab..f39b31f6f 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreePostScriptGenerator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreePostScriptGenerator.java @@ -68,11 +68,11 @@ public class TreePostScriptGenerator { protected PostScriptDocument doc; - public TreePostScriptGenerator(BaseRecognizer parser, Tree root) { + public TreePostScriptGenerator(BaseRecognizer parser, Tree root) { this(parser, root, "CourierNew", 11); } - public TreePostScriptGenerator(BaseRecognizer parser, Tree root, + public TreePostScriptGenerator(BaseRecognizer parser, Tree root, String fontName, int fontSize) { this.root = root; diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeViewer.java b/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeViewer.java index ddf82fbdd..8dd0d45fe 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeViewer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeViewer.java @@ -45,8 +45,9 @@ public class TreeViewer extends JComponent { public static final Color LIGHT_RED = new Color(244, 213, 211); public static class DefaultTreeTextProvider implements TreeTextProvider { - BaseRecognizer parser; - public DefaultTreeTextProvider(BaseRecognizer parser) { + BaseRecognizer parser; + + public DefaultTreeTextProvider(BaseRecognizer parser) { this.parser = parser; } @@ -105,9 +106,9 @@ public class TreeViewer extends JComponent { protected Color borderColor = Color.white; protected Color textColor = Color.black; - protected BaseRecognizer parser; + protected BaseRecognizer parser; - public TreeViewer(BaseRecognizer parser, Tree tree) { + public TreeViewer(BaseRecognizer parser, Tree tree) { this.parser = parser; setTreeTextProvider(new DefaultTreeTextProvider(parser)); this.treeLayout = diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 815afbe4e..6d7c100a3 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -53,8 +53,8 @@ public class BlankListener implements .Context ctx) { \} @Override public void exitRule(.Context ctx) { \}}; separator="\n"> - @Override public void enterEveryRule(ParserRuleContext ctx) { } - @Override public void exitEveryRule(ParserRuleContext ctx) { } + @Override public void enterEveryRule(ParserRuleContext\< > ctx) { } + @Override public void exitEveryRule(ParserRuleContext\< > ctx) { } @Override public void visitToken(Token token) { } } >> @@ -459,6 +459,16 @@ setState(); if (!()) throw new FailedPredicateException(this, ); >> +ParserASTExtensionMembers(s) ::= << +public ASTAdaptor\< > _adaptor = (ASTAdaptor)new CommonASTAdaptor(); +>> + +ParserASTContextInterface(s) ::= "ASTContext\< >" +ParserASTTreeFieldDecl(s) ::= " tree" +ParserASTContextMembers(s) ::= << +@Override public getTree() { return tree; } +>> + DefaultParserSuperClass(s) ::= "Parser" DefaultTreeParserSuperClass(s) ::= "TreeParser\<>" @@ -539,7 +549,7 @@ ListLabelName(label) ::= "