forked from jasder/antlr
v4: Add TSymbol generic type parameter to Recognizer, BaseRecognizer, ParserATNSimulator, ParserRuleContext, ParseTreeListener, ANTLRErrorStrategy, ANTLRErrorListener, TreeParserRuleContext
Move ParserRuleContext.tree/getTree to the generated contexts, implement ASTContext<T> for strongly typed getTree() method [git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9379]
This commit is contained in:
parent
73907aacd3
commit
65f8b9f124
|
@ -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<TSymbol> {
|
||||
/** 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<TSymbol, ?> recognizer,
|
||||
@Nullable TSymbol offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
|
|
|
@ -21,9 +21,9 @@ package org.antlr.v4.runtime;
|
|||
*
|
||||
* TODO: what to do about lexers
|
||||
*/
|
||||
public interface ANTLRErrorStrategy {
|
||||
public interface ANTLRErrorStrategy<TSymbol> {
|
||||
/** Report any kind of RecognitionException. */
|
||||
void reportError(BaseRecognizer recognizer,
|
||||
void reportError(BaseRecognizer<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> recognizer);
|
||||
}
|
||||
|
|
|
@ -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<ParserATNSimulator> {
|
||||
public abstract class BaseRecognizer<TSymbol> extends Recognizer<TSymbol, ParserATNSimulator<TSymbol>> {
|
||||
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<ParserATNSimulator> {
|
|||
* When somebody calls the start rule, this gets set to the
|
||||
* root context.
|
||||
*/
|
||||
protected ParserRuleContext _ctx;
|
||||
protected ParserRuleContext<TSymbol> _ctx;
|
||||
|
||||
protected boolean buildParseTrees;
|
||||
protected boolean traceATNStates;
|
||||
|
@ -80,9 +80,9 @@ public abstract class BaseRecognizer extends Recognizer<ParserATNSimulator> {
|
|||
* 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<ParserATNSimulator> {
|
|||
return syntaxErrors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract ObjectStream<TSymbol> 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<ParserATNSimulator> {
|
|||
* 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<TSymbol>[] listeners = getListeners();
|
||||
if ( listeners.length == 0 ) {
|
||||
System.err.println("line "+line+":"+charPositionInLine+" "+msg);
|
||||
return;
|
||||
}
|
||||
for (ANTLRErrorListener pl : _listeners) {
|
||||
for (ANTLRErrorListener<TSymbol> pl : listeners) {
|
||||
pl.error(this, offendingToken, line, charPositionInLine, msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void enterOuterAlt(ParserRuleContext localctx, int altNum) {
|
||||
public void enterOuterAlt(ParserRuleContext<TSymbol> 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<ParserATNSimulator> {
|
|||
* 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<ParserATNSimulator> {
|
|||
}
|
||||
}
|
||||
|
||||
public abstract void enterRule(ParserRuleContext localctx, int ruleIndex);
|
||||
public abstract void enterRule(ParserRuleContext<TSymbol> localctx, int ruleIndex);
|
||||
|
||||
public void exitRule(int ruleIndex) {
|
||||
_ctx = (ParserRuleContext)_ctx.parent;
|
||||
_ctx = (ParserRuleContext<TSymbol>)_ctx.parent;
|
||||
}
|
||||
|
||||
public ParserRuleContext getInvokingContext(int ruleIndex) {
|
||||
ParserRuleContext p = _ctx;
|
||||
public ParserRuleContext<TSymbol> getInvokingContext(int ruleIndex) {
|
||||
ParserRuleContext<TSymbol> p = _ctx;
|
||||
while ( p!=null ) {
|
||||
if ( p.getRuleIndex() == ruleIndex ) return p;
|
||||
p = (ParserRuleContext)p.parent;
|
||||
p = (ParserRuleContext<TSymbol>)p.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ParserRuleContext getContext() {
|
||||
public ParserRuleContext<TSymbol> getContext() {
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<TSymbol> implements ANTLRErrorStrategy<TSymbol> {
|
||||
/** 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<TSymbol> recognizer) {
|
||||
errorRecoveryMode = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inErrorRecoveryMode(BaseRecognizer recognizer) {
|
||||
public boolean inErrorRecoveryMode(BaseRecognizer<TSymbol> recognizer) {
|
||||
return errorRecoveryMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endErrorCondition(BaseRecognizer recognizer) {
|
||||
public void endErrorCondition(BaseRecognizer<TSymbol> recognizer) {
|
||||
errorRecoveryMode = false;
|
||||
lastErrorStates = null;
|
||||
lastErrorIndex = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportError(BaseRecognizer recognizer,
|
||||
public void reportError(BaseRecognizer<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> recognizer,
|
||||
NoViableAltException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
TokenStream tokens = (TokenStream)recognizer.getInputStream();
|
||||
String input = tokens.toString(e.startToken, e.offendingToken);
|
||||
ObjectStream<TSymbol> tokens = recognizer.getInputStream();
|
||||
String input;
|
||||
if (tokens instanceof TokenStream) {
|
||||
input = ((TokenStream)tokens).toString(e.startToken, e.offendingToken);
|
||||
} else {
|
||||
input = "<unknown 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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 = "<missing EOF>";
|
||||
else tokenText = "<missing "+recognizer.getTokenNames()[expectedTokenType]+">";
|
||||
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<TSymbol> 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 "<no token>";
|
||||
String s = t.getText();
|
||||
String s = getSymbolText(t);
|
||||
if ( s==null ) {
|
||||
if ( t.getType()==Token.EOF ) {
|
||||
if ( getSymbolType(t)==Token.EOF ) {
|
||||
s = "<EOF>";
|
||||
}
|
||||
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<TSymbol> 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<TSymbol> recognizer, IntervalSet set) {
|
||||
// System.err.println("consumeUntil("+set.toString(recognizer.getTokenNames())+")");
|
||||
int ttype = recognizer.getInputStream().LA(1);
|
||||
while (ttype != Token.EOF && !set.contains(ttype) ) {
|
||||
|
|
|
@ -34,18 +34,18 @@ import org.antlr.v4.runtime.tree.gui.TreeViewer;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
public class DefaultANTLRTreeGrammarErrorStrategy<T> extends DefaultANTLRErrorStrategy {
|
||||
public class DefaultANTLRTreeGrammarErrorStrategy<T> extends DefaultANTLRErrorStrategy<T> {
|
||||
@Override
|
||||
public void beginErrorCondition(BaseRecognizer recognizer) {
|
||||
public void beginErrorCondition(BaseRecognizer<T> recognizer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportError(BaseRecognizer recognizer, RecognitionException e)
|
||||
public void reportError(BaseRecognizer<T> recognizer, RecognitionException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
super.reportError(recognizer, e);
|
||||
TreeParser<T> parser = (TreeParser<T>)recognizer;
|
||||
ASTNodeStream input = parser.getInputStream();
|
||||
ASTNodeStream<T> 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<T> extends DefaultANTLRErrorSt
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportNoViableAlternative(BaseRecognizer recognizer,
|
||||
public void reportNoViableAlternative(BaseRecognizer<T> recognizer,
|
||||
NoViableAltException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
TreeParser<T> parser = (TreeParser<T>)recognizer;
|
||||
ASTNodeStream input = parser.getInputStream();
|
||||
ASTNodeStream<T> input = parser.getInputStream();
|
||||
List<T> unmatchedNodes =
|
||||
getNodeList(input, (NoViableTreeGrammarAltException)e);
|
||||
StringBuffer buf = new StringBuffer();
|
||||
StringBuilder buf = new StringBuilder();
|
||||
ASTAdaptor<T> adap = input.getTreeAdaptor();
|
||||
for (int i = 0; i < unmatchedNodes.size(); i++) {
|
||||
if ( i>0 ) buf.append(" ");
|
||||
|
@ -84,10 +84,10 @@ public class DefaultANTLRTreeGrammarErrorStrategy<T> 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<T> getNodeList(ASTNodeStream input,
|
||||
protected List<T> getNodeList(ASTNodeStream<T> input,
|
||||
NoViableTreeGrammarAltException nva)
|
||||
{
|
||||
List<T> unmatchedNodes;
|
||||
|
@ -113,27 +113,27 @@ public class DefaultANTLRTreeGrammarErrorStrategy<T> extends DefaultANTLRErrorSt
|
|||
}
|
||||
|
||||
@Override
|
||||
public Object recoverInline(BaseRecognizer recognizer) throws RecognitionException {
|
||||
public T recoverInline(BaseRecognizer<T> 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<T> recognizer, RecognitionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sync(BaseRecognizer recognizer) {
|
||||
public void sync(BaseRecognizer<T> recognizer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inErrorRecoveryMode(BaseRecognizer recognizer) {
|
||||
public boolean inErrorRecoveryMode(BaseRecognizer<T> recognizer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endErrorCondition(BaseRecognizer recognizer) {
|
||||
public void endErrorCondition(BaseRecognizer<T> recognizer) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<LexerATNSimulator>
|
||||
public abstract class Lexer extends Recognizer<Integer, LexerATNSimulator>
|
||||
implements TokenSource
|
||||
{
|
||||
public static final int DEFAULT_MODE = 0;
|
||||
|
@ -313,13 +313,14 @@ public abstract class Lexer extends Recognizer<LexerATNSimulator>
|
|||
public void notifyListeners(LexerNoViableAltException e) {
|
||||
String msg = "token recognition error at: '"+
|
||||
input.substring(tokenStartCharIndex,input.index())+"'";
|
||||
if ( _listeners==null || _listeners.size()==0 ) {
|
||||
ANTLRErrorListener<Integer>[] listeners = getListeners();
|
||||
if ( listeners.length == 0 ) {
|
||||
System.err.println("line "+tokenStartLine+":"+
|
||||
tokenStartCharPositionInLine+" "+
|
||||
msg);
|
||||
return;
|
||||
}
|
||||
for (ANTLRErrorListener pl : _listeners) {
|
||||
for (ANTLRErrorListener<Integer> pl : listeners) {
|
||||
pl.error(this, null, tokenStartLine, tokenStartCharPositionInLine, msg, e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,24 +45,27 @@ public class NoViableAltException extends RecognitionException {
|
|||
*/
|
||||
public Token startToken;
|
||||
|
||||
public NoViableAltException(BaseRecognizer recognizer) { // LL(1) error
|
||||
public <T extends Token> NoViableAltException(BaseRecognizer<T> 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 <T> NoViableAltException(BaseRecognizer<T> recognizer,
|
||||
ObjectStream<T> input,
|
||||
Token startToken,
|
||||
Token offendingToken,
|
||||
T offendingNode,
|
||||
OrderedHashSet<ATNConfig> deadEndConfigs,
|
||||
RuleContext ctx)
|
||||
{
|
||||
super(recognizer, input, ctx);
|
||||
this.deadEndConfigs = deadEndConfigs;
|
||||
this.startToken = startToken;
|
||||
this.offendingNode = offendingNode;
|
||||
this.offendingToken = offendingToken;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <T> NoViableTreeGrammarAltException(TreeParser<T> recognizer) {
|
||||
this(recognizer,
|
||||
(ASTNodeStream<Object>)recognizer.getInputStream(),
|
||||
recognizer.getInputStream(),
|
||||
recognizer.getCurrentInputSymbol(),
|
||||
recognizer.getCurrentInputSymbol(),
|
||||
null,
|
||||
recognizer._ctx);
|
||||
}
|
||||
|
||||
public NoViableTreeGrammarAltException(BaseRecognizer recognizer,
|
||||
ASTNodeStream<Object> input,
|
||||
Object startNode,
|
||||
Object offendingNode,
|
||||
public <T> NoViableTreeGrammarAltException(BaseRecognizer<T> recognizer,
|
||||
ASTNodeStream<T> input,
|
||||
T startNode,
|
||||
T offendingNode,
|
||||
OrderedHashSet<ATNConfig> deadEndConfigs,
|
||||
RuleContext ctx) {
|
||||
super(recognizer, input,
|
||||
input.getTreeAdaptor().getToken(startNode),
|
||||
input.getTreeAdaptor().getToken(offendingNode),
|
||||
offendingNode,
|
||||
deadEndConfigs, ctx);
|
||||
this.startNode = startNode;
|
||||
this.offendingNode = offendingNode;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Token> {
|
||||
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<Token> 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
|
||||
|
|
|
@ -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<SymbolType> 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<SymbolType> 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; }
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ATNInterpreter> {
|
||||
public abstract class Recognizer<TSymbol, ATNInterpreter extends ATNSimulator> {
|
||||
public static final int EOF=-1;
|
||||
|
||||
protected ANTLRErrorStrategy _errHandler = new DefaultANTLRErrorStrategy();
|
||||
protected List<ANTLRErrorListener> _listeners;
|
||||
protected ANTLRErrorStrategy<TSymbol> _errHandler = new DefaultANTLRErrorStrategy();
|
||||
|
||||
private List<ANTLRErrorListener<TSymbol>> _listeners;
|
||||
|
||||
private static final ANTLRErrorListener[] EMPTY_LISTENERS = new ANTLRErrorListener[0];
|
||||
|
||||
protected ATNInterpreter _interp;
|
||||
|
||||
|
@ -194,32 +200,38 @@ public abstract class Recognizer<ATNInterpreter> {
|
|||
return "'"+s+"'";
|
||||
}
|
||||
|
||||
public void addListener(ANTLRErrorListener pl) {
|
||||
public void addListener(ANTLRErrorListener<TSymbol> pl) {
|
||||
if ( _listeners ==null ) {
|
||||
_listeners =
|
||||
Collections.synchronizedList(new ArrayList<ANTLRErrorListener>(2));
|
||||
Collections.synchronizedList(new ArrayList<ANTLRErrorListener<TSymbol>>(2));
|
||||
}
|
||||
if ( pl!=null ) _listeners.add(pl);
|
||||
}
|
||||
|
||||
public void removeListener(ANTLRErrorListener pl) { _listeners.remove(pl); }
|
||||
public void removeListener(ANTLRErrorListener<TSymbol> pl) { _listeners.remove(pl); }
|
||||
|
||||
public void removeListeners() { _listeners.clear(); }
|
||||
|
||||
public List<ANTLRErrorListener> getListeners() { return _listeners; }
|
||||
public @NotNull ANTLRErrorListener<TSymbol>[] 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<TSymbol> getErrorHandler() { return _errHandler; }
|
||||
|
||||
public void setErrorHandler(ANTLRErrorStrategy<TSymbol> 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.
|
||||
|
|
|
@ -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("[");
|
||||
|
|
|
@ -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<T> extends ParserRuleContext<T> {
|
||||
public TreeParserRuleContext() {
|
||||
super();
|
||||
}
|
||||
|
|
|
@ -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]+":");
|
||||
|
|
|
@ -37,7 +37,7 @@ import org.stringtemplate.v4.misc.MultiMap;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
public class ParserATNSimulator extends ATNSimulator {
|
||||
public class ParserATNSimulator<TSymbol> 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<TSymbol> parser;
|
||||
|
||||
public Map<RuleContext, DFA[]> ctxToDFAs;
|
||||
public Map<RuleContext, DFA>[] 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<TSymbol> parser, ATN atn) {
|
||||
super(atn);
|
||||
this.parser = parser;
|
||||
ctxToDFAs = new HashMap<RuleContext, DFA[]>();
|
||||
|
@ -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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol> 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<TSymbol>)input).toString(input.get(start),input.LT(1));
|
||||
}
|
||||
return "n/a";
|
||||
}
|
||||
|
||||
public int execATN(ObjectStream input,
|
||||
public int execATN(ObjectStream<TSymbol> input,
|
||||
DFA dfa,
|
||||
int startIndex,
|
||||
OrderedHashSet<ATNConfig> s0,
|
||||
|
@ -405,7 +405,7 @@ public class ParserATNSimulator extends ATNSimulator {
|
|||
return exitAlt;
|
||||
}
|
||||
|
||||
public int retryWithContext(ObjectStream input,
|
||||
public int retryWithContext(ObjectStream<TSymbol> 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<TSymbol> 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<TSymbol> input, RuleContext outerContext,
|
||||
OrderedHashSet<ATNConfig> 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<Object>)input,
|
||||
(ASTNodeStream<TSymbol>)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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
T getTree();
|
||||
}
|
|
@ -258,18 +258,18 @@ public abstract class BaseAST implements AST {
|
|||
*/
|
||||
public List<? extends Tree> 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
|
||||
{
|
||||
|
|
|
@ -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<TSymbol> {
|
||||
void visitToken(Token token);
|
||||
void enterEveryRule(ParserRuleContext ctx);
|
||||
void exitEveryRule(ParserRuleContext ctx);
|
||||
void enterEveryRule(ParserRuleContext<TSymbol> ctx);
|
||||
void exitEveryRule(ParserRuleContext<TSymbol> ctx);
|
||||
}
|
||||
|
|
|
@ -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 <TSymbol> void walk(ParseTreeListener<TSymbol> 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 <TSymbol> void visitToken(ParseTreeListener<TSymbol> 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 <TSymbol> void enterRule(ParseTreeListener<TSymbol> listener, ParseTree.RuleNode r) {
|
||||
ParserRuleContext<TSymbol> ctx = (ParserRuleContext<TSymbol>)r.getRuleContext();
|
||||
listener.enterEveryRule((ParserRuleContext<TSymbol>) r.getRuleContext());
|
||||
ctx.enterRule(listener);
|
||||
}
|
||||
|
||||
protected void exitRule(ParseTreeListener listener, ParseTree.RuleNode r) {
|
||||
ParserRuleContext ctx = (ParserRuleContext)r.getRuleContext();
|
||||
protected <TSymbol> void exitRule(ParseTreeListener<TSymbol> listener, ParseTree.RuleNode r) {
|
||||
ParserRuleContext<TSymbol> ctx = (ParserRuleContext<TSymbol>)r.getRuleContext();
|
||||
ctx.exitRule(listener);
|
||||
listener.exitEveryRule(ctx);
|
||||
}
|
||||
|
|
|
@ -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<T> extends TreeParser {
|
||||
public class TreeFilter<T> extends TreeParser<T> {
|
||||
public interface fptr {
|
||||
public void rule() throws RecognitionException;
|
||||
}
|
||||
|
@ -94,15 +94,15 @@ public class TreeFilter<T> extends TreeParser {
|
|||
try {
|
||||
// share TreeParser object but not parsing-related state
|
||||
_input = new CommonASTNodeStream<T>(originalAdaptor, t);
|
||||
((CommonASTNodeStream) _input).setTokenStream(originalTokenStream);
|
||||
((CommonASTNodeStream<T>) _input).setTokenStream(originalTokenStream);
|
||||
whichRule.rule();
|
||||
}
|
||||
catch (RecognitionException e) { }
|
||||
}
|
||||
|
||||
public void downup(T t) {
|
||||
TreeVisitor v = new TreeVisitor(new CommonASTAdaptor());
|
||||
TreeVisitorAction actions = new TreeVisitorAction<T>() {
|
||||
TreeVisitor<T> v = new TreeVisitor<T>((ASTAdaptor<T>)new CommonASTAdaptor());
|
||||
TreeVisitorAction<T> actions = new TreeVisitorAction<T>() {
|
||||
@Override
|
||||
public T pre(T t) { applyOnce(t, topdown_fptr); return t; }
|
||||
@Override
|
||||
|
|
|
@ -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<T> extends BaseRecognizer {
|
||||
public class TreeParser<T> extends BaseRecognizer<T> {
|
||||
public static final int DOWN = Token.DOWN;
|
||||
public static final int UP = Token.UP;
|
||||
|
||||
|
@ -65,7 +65,7 @@ public class TreeParser<T> extends BaseRecognizer {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected T getCurrentInputSymbol() { return _input.LT(1); }
|
||||
public T getCurrentInputSymbol() { return _input.LT(1); }
|
||||
|
||||
@Override
|
||||
public ASTNodeStream<T> getInputStream() { return _input; }
|
||||
|
@ -79,13 +79,14 @@ public class TreeParser<T> 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<T> localctx, int ruleIndex) {
|
||||
_ctx = localctx;
|
||||
_ctx.start = _input.LT(1);
|
||||
_ctx.ruleIndex = ruleIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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<TreeWizard.TreePattern>...
|
||||
protected ASTAdaptor<CommonAST> adaptor;
|
||||
|
||||
public TreePatternParser(TreePatternLexer tokenizer, TreeWizard wizard, ASTAdaptor adaptor) {
|
||||
public TreePatternParser(TreePatternLexer tokenizer, TreeWizard<?> wizard, ASTAdaptor<CommonAST> 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;
|
||||
}
|
||||
|
|
|
@ -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<T> {
|
||||
protected ASTAdaptor<T> adaptor;
|
||||
|
||||
public TreeVisitor(ASTAdaptor adaptor) {
|
||||
public TreeVisitor(ASTAdaptor<T> adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
public TreeVisitor() { this(new CommonASTAdaptor()); }
|
||||
|
||||
public TreeVisitor() { this((ASTAdaptor<T>)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<T> 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<adaptor.getChildCount(t); i++) {
|
||||
Object child = adaptor.getChild(t, i);
|
||||
Object visitResult = visit(child, action);
|
||||
Object childAfterVisit = adaptor.getChild(t, i);
|
||||
T child = adaptor.getChild(t, i);
|
||||
T visitResult = visit(child, action);
|
||||
T childAfterVisit = adaptor.getChild(t, i);
|
||||
if ( visitResult != childAfterVisit ) { // result & child differ?
|
||||
adaptor.setChild(t, i, visitResult);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
package org.antlr.v4.runtime.tree;
|
||||
|
||||
|
||||
import com.sun.istack.internal.Nullable;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -49,20 +50,21 @@ import java.util.*;
|
|||
* patterns like "(A B C)". You can create a tree from that pattern or
|
||||
* match subtrees against it.
|
||||
*/
|
||||
public class TreeWizard {
|
||||
protected ASTAdaptor adaptor;
|
||||
protected Map tokenNameToTypeMap;
|
||||
public class TreeWizard<T> {
|
||||
protected ASTAdaptor<T> adaptor;
|
||||
protected Map<String, Integer> tokenNameToTypeMap;
|
||||
|
||||
public interface ContextVisitor {
|
||||
public interface ContextVisitor<T> {
|
||||
// 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<String, T> labels);
|
||||
}
|
||||
|
||||
public static abstract class Visitor implements ContextVisitor {
|
||||
public void visit(Object t, Object parent, int childIndex, Map labels) {
|
||||
public static abstract class Visitor<T> implements ContextVisitor<T> {
|
||||
@Override
|
||||
public void visit(T t, Object parent, int childIndex, Map<String, T> 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<T> adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
|
||||
public TreeWizard(ASTAdaptor adaptor, Map tokenNameToTypeMap) {
|
||||
public TreeWizard(ASTAdaptor<T> adaptor, Map<String, Integer> tokenNameToTypeMap) {
|
||||
this.adaptor = adaptor;
|
||||
this.tokenNameToTypeMap = tokenNameToTypeMap;
|
||||
}
|
||||
|
||||
public TreeWizard(ASTAdaptor adaptor, String[] tokenNames) {
|
||||
public TreeWizard(ASTAdaptor<T> adaptor, String[] tokenNames) {
|
||||
this.adaptor = adaptor;
|
||||
this.tokenNameToTypeMap = computeTokenTypes(tokenNames);
|
||||
}
|
||||
|
||||
public TreeWizard(String[] tokenNames) {
|
||||
this(new CommonASTAdaptor(), tokenNames);
|
||||
this((ASTAdaptor<T>)new TreePatternASTAdaptor(), tokenNames);
|
||||
}
|
||||
|
||||
/** Compute a Map<String, Integer> 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<String, Integer> computeTokenTypes(String[] tokenNames) {
|
||||
Map<String, Integer> m = new HashMap<String, Integer>();
|
||||
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<Integer, List<T>> index(T t) {
|
||||
Map<Integer, List<T>> m = new HashMap<Integer, List<T>>();
|
||||
_index(t, m);
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Do the work for index */
|
||||
protected void _index(Object t, Map m) {
|
||||
protected void _index(T t, Map<Integer, List<T>> m) {
|
||||
if ( t==null ) {
|
||||
return;
|
||||
}
|
||||
int ttype = adaptor.getType(t);
|
||||
List elements = (List)m.get(new Integer(ttype));
|
||||
List<T> elements = m.get(ttype);
|
||||
if ( elements==null ) {
|
||||
elements = new ArrayList();
|
||||
m.put(new Integer(ttype), elements);
|
||||
elements = new ArrayList<T>();
|
||||
m.put(ttype, elements);
|
||||
}
|
||||
elements.add(t);
|
||||
int n = adaptor.getChildCount(t);
|
||||
for (int i=0; i<n; i++) {
|
||||
Object child = adaptor.getChild(t, i);
|
||||
T child = adaptor.getChild(t, i);
|
||||
_index(child, m);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a List of tree nodes with token type ttype */
|
||||
public List find(Object t, int ttype) {
|
||||
final List nodes = new ArrayList();
|
||||
visit(t, ttype, new TreeWizard.Visitor() {
|
||||
public void visit(Object t) {
|
||||
public List<T> find(T t, int ttype) {
|
||||
final List<T> nodes = new ArrayList<T>();
|
||||
visit(t, ttype, new TreeWizard.Visitor<T>() {
|
||||
@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<T> find(T t, String pattern) {
|
||||
final List<T> subtrees = new ArrayList<T>();
|
||||
// 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<T>() {
|
||||
@Override
|
||||
public void visit(T t, Object parent, int childIndex, Map<String, T> 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<T> 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<T> visitor) {
|
||||
if ( t==null ) {
|
||||
return;
|
||||
}
|
||||
|
@ -259,7 +263,7 @@ public class TreeWizard {
|
|||
}
|
||||
int n = adaptor.getChildCount(t);
|
||||
for (int i=0; i<n; i++) {
|
||||
Object child = adaptor.getChild(t, i);
|
||||
T child = adaptor.getChild(t, i);
|
||||
_visit(child, t, i, ttype, visitor);
|
||||
}
|
||||
}
|
||||
|
@ -269,12 +273,12 @@ public class TreeWizard {
|
|||
* with visit(t, ttype, visitor) so nil-rooted patterns are not allowed.
|
||||
* Patterns with wildcard roots are also not allowed.
|
||||
*/
|
||||
public void visit(Object t, final String pattern, final ContextVisitor visitor) {
|
||||
public void visit(T t, final String pattern, final ContextVisitor<T> 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<String, T> labels = new HashMap<String, T>(); // 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<T>() {
|
||||
@Override
|
||||
public void visit(T t, Object parent, int childIndex, Map<String, T> 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<String, T> 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<String, T> 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<n1; i++) {
|
||||
Object child1 = adaptor.getChild(t1, i);
|
||||
T child1 = adaptor.getChild(t1, i);
|
||||
TreePattern child2 = (TreePattern)tpattern.getChild(i);
|
||||
if ( !_parse(child1, child2, labels) ) {
|
||||
return false;
|
||||
|
@ -374,10 +379,10 @@ public class TreeWizard {
|
|||
* nil is a special name meaning "give me a nil node". Useful for
|
||||
* making lists: (nil A B C) is a list of A B C.
|
||||
*/
|
||||
public Object create(String pattern) {
|
||||
public TreePattern create(String pattern) {
|
||||
TreePatternLexer tokenizer = new TreePatternLexer(pattern);
|
||||
TreePatternParser parser = new TreePatternParser(tokenizer, this, adaptor);
|
||||
Object t = parser.pattern();
|
||||
TreePatternParser parser = new TreePatternParser(tokenizer, this, new TreePatternASTAdaptor());
|
||||
TreePattern t = parser.pattern();
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -390,18 +395,18 @@ public class TreeWizard {
|
|||
* I cannot rely on the tree node's equals() implementation as I make
|
||||
* no constraints at all on the node types nor interface etc...
|
||||
*/
|
||||
public static boolean equals(Object t1, Object t2, ASTAdaptor adaptor) {
|
||||
public static <T> boolean equals(T t1, T t2, ASTAdaptor<T> 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 <T> boolean _equals(T t1, T t2, ASTAdaptor<T> 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<n1; i++) {
|
||||
Object child1 = adaptor.getChild(t1, i);
|
||||
Object child2 = adaptor.getChild(t2, i);
|
||||
T child1 = adaptor.getChild(t1, i);
|
||||
T child2 = adaptor.getChild(t2, i);
|
||||
if ( !_equals(child1, child2, adaptor) ) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ import java.util.TreeSet;
|
|||
/** A set of utility routines useful for all kinds of ANTLR trees */
|
||||
public class Trees {
|
||||
|
||||
public static String getPS(Tree t, BaseRecognizer recog,
|
||||
public static String getPS(Tree t, BaseRecognizer<?> 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<BaseAST> newChildren = null;
|
||||
List<BaseAST> 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> T dupTree(ASTAdaptor<T> 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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -53,8 +53,8 @@ public class Blank<listener.grammarName>Listener implements <listener.grammarNam
|
|||
@Override public void enterRule(<listener.parserName>.<lname>Context ctx) { \}
|
||||
@Override public void exitRule(<listener.parserName>.<lname>Context ctx) { \}}; separator="\n">
|
||||
|
||||
@Override public void enterEveryRule(ParserRuleContext ctx) { }
|
||||
@Override public void exitEveryRule(ParserRuleContext ctx) { }
|
||||
@Override public void enterEveryRule(ParserRuleContext\<<TokenLabelType()> > ctx) { }
|
||||
@Override public void exitEveryRule(ParserRuleContext\<<TokenLabelType()> > ctx) { }
|
||||
@Override public void visitToken(Token token) { }
|
||||
}
|
||||
>>
|
||||
|
@ -459,6 +459,16 @@ setState(<p.stateNumber>);
|
|||
if (!(<chunks>)) throw new FailedPredicateException(this, <if(p.msg)><p.msg><else><failChunks><endif>);
|
||||
>>
|
||||
|
||||
ParserASTExtensionMembers(s) ::= <<
|
||||
public ASTAdaptor\<<ASTLabelType()> > _adaptor = (ASTAdaptor)new CommonASTAdaptor();
|
||||
>>
|
||||
|
||||
ParserASTContextInterface(s) ::= "ASTContext\<<ASTLabelType()> >"
|
||||
ParserASTTreeFieldDecl(s) ::= "<ASTLabelType()> tree"
|
||||
ParserASTContextMembers(s) ::= <<
|
||||
@Override public <ASTLabelType()> getTree() { return tree; }
|
||||
>>
|
||||
|
||||
DefaultParserSuperClass(s) ::= "Parser"
|
||||
DefaultTreeParserSuperClass(s) ::= "TreeParser\<<ASTLabelType()>>"
|
||||
|
||||
|
@ -539,7 +549,7 @@ ListLabelName(label) ::= "<label>_list"
|
|||
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
|
||||
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"
|
||||
|
||||
StructDecl(s,attrs,visitorDispatchMethods,interfaces,extensionMembers,superClass="ParserRuleContext") ::= <<
|
||||
StructDecl(s,attrs,visitorDispatchMethods,interfaces,extensionMembers,superClass={ParserRuleContext\<<TokenLabelType()>>}) ::= <<
|
||||
public static class <s.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
|
||||
<attrs:{a | public <a>;}; separator="\n">
|
||||
<if(s.ctorAttrs)>public <s.name>(RuleContext parent, int state) { super(parent, state); }<endif>
|
||||
|
@ -560,7 +570,7 @@ public static class <s.name> extends <superClass><if(interfaces)> implements <in
|
|||
>>
|
||||
|
||||
TreeParserStructDecl(s,attrs,visitorDispatchMethods) ::= <<
|
||||
<StructDecl(superClass="TreeParserRuleContext", ...)>
|
||||
<StructDecl(superClass={TreeParserRuleContext\<<ASTLabelType()> >}, ...)>
|
||||
>>
|
||||
|
||||
AltLabelStructDecl(s,attrs,visitorDispatchMethods) ::= <<
|
||||
|
|
|
@ -30,11 +30,13 @@
|
|||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.actions.ParserASTExtensionMembers;
|
||||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Attribute;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -44,6 +46,26 @@ public class ParserASTExtension extends CodeGeneratorExtension {
|
|||
super(factory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParserFile parserFile(ParserFile file) {
|
||||
Action members = file.namedActions.get("members");
|
||||
if (members == null) {
|
||||
members = new Action(factory, null);
|
||||
file.namedActions.put("members", members);
|
||||
}
|
||||
|
||||
members.chunks.add(new ParserASTExtensionMembers());
|
||||
return super.parserFile(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuleFunction rule(RuleFunction rf) {
|
||||
rf.ruleCtx.addDecl(new ParserASTTreeFieldDecl(factory));
|
||||
rf.ruleCtx.addExtensionMember(new ParserASTContextMembers());
|
||||
rf.ruleCtx.implementInterface(new ParserASTContextInterface());
|
||||
return super.rule(rf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Choice getChoiceBlock(Choice choice) {
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
[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.codegen.model.actions;
|
||||
|
||||
public class ParserASTExtensionMembers extends ActionChunk {
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
[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.codegen.model.ast;
|
||||
|
||||
import org.antlr.v4.codegen.model.OutputModelObject;
|
||||
|
||||
public class ParserASTContextInterface extends OutputModelObject {
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
[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.codegen.model.ast;
|
||||
|
||||
import org.antlr.v4.codegen.model.OutputModelObject;
|
||||
|
||||
public class ParserASTContextMembers extends OutputModelObject {
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
[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.codegen.model.decl;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
|
||||
public class ParserASTTreeFieldDecl extends AttributeDecl {
|
||||
public ParserASTTreeFieldDecl(OutputModelFactory factory) {
|
||||
super(factory, "tree", "Unknown");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue