removed all template / AST rewrite stuff; massive change; added -encoding tool option
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9780]
This commit is contained in:
parent
1921a46dd2
commit
1b04195a2f
|
@ -30,9 +30,9 @@ import org.antlr.v4.runtime.misc.OrderedHashSet;
|
|||
*
|
||||
* TODO: what to do about lexers
|
||||
*/
|
||||
public interface ANTLRErrorStrategy<Symbol> {
|
||||
public interface ANTLRErrorStrategy {
|
||||
/** Report any kind of RecognitionException. */
|
||||
void reportError(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
void reportError(@NotNull BaseRecognizer recognizer,
|
||||
@Nullable RecognitionException e)
|
||||
throws RecognitionException;
|
||||
|
||||
|
@ -52,7 +52,7 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* "inserting" tokens, we need to specify what that implicitly created
|
||||
* token is. We use object, because it could be a tree node.
|
||||
*/
|
||||
Symbol recoverInline(@NotNull BaseRecognizer<Symbol> recognizer)
|
||||
Token recoverInline(@NotNull BaseRecognizer recognizer)
|
||||
throws RecognitionException;
|
||||
|
||||
/** Resynchronize the parser by consuming tokens until we find one
|
||||
|
@ -60,7 +60,7 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* the current rule. The exception contains info you might want to
|
||||
* use to recover better.
|
||||
*/
|
||||
void recover(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
void recover(@NotNull BaseRecognizer recognizer,
|
||||
@Nullable RecognitionException e);
|
||||
|
||||
/** Make sure that the current lookahead symbol is consistent with
|
||||
|
@ -90,14 +90,14 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* turn off this functionality by simply overriding this method as
|
||||
* a blank { }.
|
||||
*/
|
||||
void sync(@NotNull BaseRecognizer<Symbol> recognizer);
|
||||
void sync(@NotNull BaseRecognizer recognizer);
|
||||
|
||||
/** Notify handler that parser has entered an error state. The
|
||||
* parser currently doesn't call this--the handler itself calls this
|
||||
* in report error methods. But, for symmetry with endErrorCondition,
|
||||
* this method is in the interface.
|
||||
*/
|
||||
void beginErrorCondition(@NotNull BaseRecognizer<Symbol> recognizer);
|
||||
void beginErrorCondition(@NotNull BaseRecognizer recognizer);
|
||||
|
||||
/** Is the parser in the process of recovering from an error? Upon
|
||||
* a syntax error, the parser enters recovery mode and stays there until
|
||||
|
@ -105,13 +105,13 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* avoid sending out spurious error messages. We only want one error
|
||||
* message per syntax error
|
||||
*/
|
||||
boolean inErrorRecoveryMode(@NotNull BaseRecognizer<Symbol> recognizer);
|
||||
boolean inErrorRecoveryMode(@NotNull BaseRecognizer recognizer);
|
||||
|
||||
/** Reset the error handler. Call this when the parser
|
||||
* matches a valid token (indicating no longer in recovery mode)
|
||||
* and from its own reset method.
|
||||
*/
|
||||
void endErrorCondition(@NotNull BaseRecognizer<Symbol> recognizer);
|
||||
void endErrorCondition(@NotNull BaseRecognizer recognizer);
|
||||
|
||||
/** Called when the parser detects a true ambiguity: an input sequence can be matched
|
||||
* literally by two or more pass through the grammar. ANTLR resolves the ambiguity in
|
||||
|
@ -120,7 +120,7 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* that can match the input sequence. This method is only called when we are parsing with
|
||||
* full context.
|
||||
*/
|
||||
void reportAmbiguity(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
void reportAmbiguity(@NotNull BaseRecognizer recognizer,
|
||||
DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs);
|
||||
|
||||
|
@ -130,12 +130,12 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* we can't be sure if a conflict is an ambiguity or simply a weakness in the Strong LL parsing
|
||||
* strategy. If we are parsing with full context, this method is never called.
|
||||
*/
|
||||
// void reportConflict(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
// void reportConflict(@NotNull BaseRecognizer recognizer,
|
||||
// int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
|
||||
// @NotNull OrderedHashSet<ATNConfig> configs);
|
||||
|
||||
|
||||
void reportAttemptingFullContext(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
void reportAttemptingFullContext(@NotNull BaseRecognizer recognizer,
|
||||
@NotNull DFA dfa,
|
||||
int startIndex, int stopIndex,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs);
|
||||
|
@ -145,7 +145,7 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* is more complicated than Strong LL can handle. The parser moved up to full context
|
||||
* parsing for that input sequence.
|
||||
*/
|
||||
void reportContextSensitivity(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
void reportContextSensitivity(@NotNull BaseRecognizer recognizer,
|
||||
@NotNull DFA dfa,
|
||||
int startIndex, int stopIndex,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs);
|
||||
|
@ -155,7 +155,7 @@ public interface ANTLRErrorStrategy<Symbol> {
|
|||
* If there are fewer than n-1, then we don't know which make it alternative to protect
|
||||
* if the predicates fail.
|
||||
*/
|
||||
void reportInsufficientPredicates(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
void reportInsufficientPredicates(@NotNull BaseRecognizer recognizer,
|
||||
@NotNull DFA dfa,
|
||||
int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
|
||||
DecisionState decState,
|
||||
|
|
|
@ -32,14 +32,14 @@ package org.antlr.v4.runtime;
|
|||
/** Bail out of parser at first syntax error. Do this to use it:
|
||||
* myparser.setErrorHandler(new BailErrorStrategy<Token>());
|
||||
*/
|
||||
public class BailErrorStrategy<Symbol> extends DefaultErrorStrategy<Symbol> {
|
||||
public class BailErrorStrategy extends DefaultErrorStrategy {
|
||||
/** Instead of recovering from exception e, Re-throw wrote it wrapped
|
||||
* in a generic RuntimeException so it is not caught by the
|
||||
* rule function catches. Exception e is the "cause" of the
|
||||
* RuntimeException.
|
||||
*/
|
||||
@Override
|
||||
public void recover(BaseRecognizer<Symbol> recognizer, RecognitionException e) {
|
||||
public void recover(BaseRecognizer recognizer, RecognitionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class BailErrorStrategy<Symbol> extends DefaultErrorStrategy<Symbol> {
|
|||
* successfully recovers, it won't throw an exception.
|
||||
*/
|
||||
@Override
|
||||
public Symbol recoverInline(BaseRecognizer<Symbol> recognizer)
|
||||
public Token recoverInline(BaseRecognizer recognizer)
|
||||
throws RecognitionException
|
||||
{
|
||||
throw new RuntimeException(new InputMismatchException(recognizer));
|
||||
|
@ -55,5 +55,5 @@ public class BailErrorStrategy<Symbol> extends DefaultErrorStrategy<Symbol> {
|
|||
|
||||
/** Make sure we don't attempt to recover from problems in subrules. */
|
||||
@Override
|
||||
public void sync(BaseRecognizer<Symbol> recognizer) { }
|
||||
public void sync(BaseRecognizer recognizer) { }
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.antlr.v4.runtime.atn.*;
|
|||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.runtime.tree.BufferedASTNodeStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -43,17 +42,19 @@ import java.util.List;
|
|||
* support code essentially; most of it is error recovery stuff and
|
||||
* backtracking.
|
||||
*
|
||||
* TODO: rename since lexer not under. or reorg parser/treeparser; treeparser under parser?
|
||||
* TODO: rename / reorg with parser
|
||||
*/
|
||||
public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2ParserATNSimulator<Symbol>> {
|
||||
public abstract class BaseRecognizer extends Recognizer<Token, v2ParserATNSimulator<Token>> {
|
||||
public static final String NEXT_TOKEN_RULE_NAME = "nextToken";
|
||||
|
||||
protected TokenStream _input;
|
||||
|
||||
/** The RuleContext object for the currently executing rule. This
|
||||
* must be non-null during parsing, but is initially null.
|
||||
* When somebody calls the start rule, this gets set to the
|
||||
* root context.
|
||||
*/
|
||||
protected ParserRuleContext<Symbol> _ctx;
|
||||
protected ParserRuleContext<Token> _ctx;
|
||||
|
||||
protected boolean buildParseTrees;
|
||||
protected boolean traceATNStates;
|
||||
|
@ -64,7 +65,7 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
* the parse or during tree walks later. Both could be done.
|
||||
* Not intended for tree parsing but would work.
|
||||
*/
|
||||
protected ParseTreeListener<Symbol> _listener;
|
||||
protected ParseTreeListener<Token> _listener;
|
||||
|
||||
/** Did the recognizer encounter a syntax error? Track how many. */
|
||||
protected int syntaxErrors = 0;
|
||||
|
@ -89,9 +90,9 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
* single token insertion or deletion error recovery. If
|
||||
* that fails, throw MismatchedTokenException.
|
||||
*/
|
||||
public Symbol match(int ttype) throws RecognitionException {
|
||||
public Token match(int ttype) throws RecognitionException {
|
||||
// System.out.println("match "+((TokenStream)input).LT(1)+" vs expected "+ttype);
|
||||
Symbol currentSymbol = getCurrentInputSymbol();
|
||||
Token currentSymbol = getCurrentToken();
|
||||
if ( getInputStream().LA(1)==ttype ) {
|
||||
_errHandler.endErrorCondition(this);
|
||||
consume();
|
||||
|
@ -145,11 +146,11 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
return traceATNStates;
|
||||
}
|
||||
|
||||
public ParseTreeListener<Symbol> getListener() {
|
||||
public ParseTreeListener<Token> getListener() {
|
||||
return _listener;
|
||||
}
|
||||
|
||||
public void setListener(ParseTreeListener<Symbol> listener) {
|
||||
public void setListener(ParseTreeListener<Token> listener) {
|
||||
this._listener = listener;
|
||||
}
|
||||
|
||||
|
@ -165,37 +166,48 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
}
|
||||
|
||||
@Override
|
||||
public abstract SymbolStream<Symbol> getInputStream();
|
||||
public TokenStream getInputStream() { return getTokenStream(); }
|
||||
|
||||
@Override
|
||||
public final void setInputStream(IntStream input) {
|
||||
setTokenStream((TokenStream)input);
|
||||
}
|
||||
|
||||
public TokenStream getTokenStream() {
|
||||
return _input;
|
||||
}
|
||||
|
||||
/** Set the token stream and reset the parser */
|
||||
public void setTokenStream(TokenStream input) {
|
||||
this._input = null;
|
||||
reset();
|
||||
this._input = input;
|
||||
}
|
||||
|
||||
public String getInputString(int start) {
|
||||
return getInputString(start, getInputStream().index());
|
||||
}
|
||||
|
||||
public String getInputString(int start, int stop) {
|
||||
SymbolStream<Symbol> input = getInputStream();
|
||||
SymbolStream<Token> input = getInputStream();
|
||||
if ( input instanceof TokenStream ) {
|
||||
return ((TokenStream)input).toString(start,stop);
|
||||
}
|
||||
else if ( input instanceof BufferedASTNodeStream ) {
|
||||
return ((BufferedASTNodeStream<Symbol>)input).toString(input.get(start),input.get(stop));
|
||||
}
|
||||
return "n/a";
|
||||
}
|
||||
|
||||
/** 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
|
||||
* for input stream type or change the IntStream interface, I use
|
||||
* a simple method to ask the recognizer to tell me what the current
|
||||
* input symbol is.
|
||||
* into the label for the associated token ref; e.g., x=ID.
|
||||
*/
|
||||
public abstract Symbol getCurrentInputSymbol();
|
||||
|
||||
public void notifyListeners(String msg) {
|
||||
notifyListeners(getCurrentInputSymbol(), msg, null);
|
||||
public Token getCurrentToken() {
|
||||
return _input.LT(1);
|
||||
}
|
||||
|
||||
public void notifyListeners(Symbol offendingToken, String msg,
|
||||
public void notifyListeners(String msg) {
|
||||
notifyListeners(getCurrentToken(), msg, null);
|
||||
}
|
||||
|
||||
public void notifyListeners(Token offendingToken, String msg,
|
||||
@Nullable RecognitionException e)
|
||||
{
|
||||
int line = -1;
|
||||
|
@ -204,17 +216,17 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
line = ((Token) offendingToken).getLine();
|
||||
charPositionInLine = ((Token) offendingToken).getCharPositionInLine();
|
||||
}
|
||||
ANTLRErrorListener<Symbol>[] listeners = getListeners();
|
||||
ANTLRErrorListener<Token>[] listeners = getListeners();
|
||||
if ( listeners.length == 0 ) {
|
||||
System.err.println("line "+line+":"+charPositionInLine+" "+msg);
|
||||
return;
|
||||
}
|
||||
for (ANTLRErrorListener<Symbol> pl : listeners) {
|
||||
for (ANTLRErrorListener<Token> pl : listeners) {
|
||||
pl.error(this, offendingToken, line, charPositionInLine, msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void enterOuterAlt(ParserRuleContext<Symbol> localctx, int altNum) {
|
||||
public void enterOuterAlt(ParserRuleContext<Token> 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 ) {
|
||||
|
@ -239,8 +251,8 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
*
|
||||
* Trigger listener events if there's a listener.
|
||||
*/
|
||||
public Symbol consume() {
|
||||
Symbol o = getCurrentInputSymbol();
|
||||
public Token consume() {
|
||||
Token o = getCurrentToken();
|
||||
getInputStream().consume();
|
||||
if ( buildParseTrees ) {
|
||||
// TODO: tree parsers?
|
||||
|
@ -262,22 +274,43 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
}
|
||||
}
|
||||
|
||||
public abstract void enterRule(ParserRuleContext<Symbol> localctx, int ruleIndex);
|
||||
|
||||
public void exitRule(int ruleIndex) {
|
||||
_ctx = (ParserRuleContext<Symbol>)_ctx.parent;
|
||||
/** Always called by generated parsers upon entry to a rule.
|
||||
* This occurs after the new context has been pushed. Access field
|
||||
* _ctx get the current context.
|
||||
*
|
||||
* This is flexible because users do not have to regenerate parsers
|
||||
* to get trace facilities.
|
||||
*/
|
||||
public void enterRule(ParserRuleContext<Token> localctx, int ruleIndex) {
|
||||
_ctx = localctx;
|
||||
_ctx.start = _input.LT(1);
|
||||
_ctx.ruleIndex = ruleIndex;
|
||||
if ( buildParseTrees ) addContextToParseTree();
|
||||
if ( _listener != null) {
|
||||
_listener.enterEveryRule(_ctx);
|
||||
_ctx.enterRule(_listener);
|
||||
}
|
||||
}
|
||||
|
||||
public ParserRuleContext<Symbol> getInvokingContext(int ruleIndex) {
|
||||
ParserRuleContext<Symbol> p = _ctx;
|
||||
public void exitRule(int ruleIndex) {
|
||||
// trigger event on _ctx, before it reverts to parent
|
||||
if ( _listener != null) {
|
||||
_ctx.exitRule(_listener);
|
||||
_listener.exitEveryRule(_ctx);
|
||||
}
|
||||
_ctx = (ParserRuleContext<Token>)_ctx.parent;
|
||||
}
|
||||
|
||||
public ParserRuleContext<Token> getInvokingContext(int ruleIndex) {
|
||||
ParserRuleContext<Token> p = _ctx;
|
||||
while ( p!=null ) {
|
||||
if ( p.getRuleIndex() == ruleIndex ) return p;
|
||||
p = (ParserRuleContext<Symbol>)p.parent;
|
||||
p = (ParserRuleContext<Token>)p.parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ParserRuleContext<Symbol> getContext() {
|
||||
public ParserRuleContext<Token> getContext() {
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
|
@ -409,7 +442,9 @@ public abstract class BaseRecognizer<Symbol> extends Recognizer<Symbol, v2Parser
|
|||
}
|
||||
}
|
||||
|
||||
public abstract String getSourceName();
|
||||
public String getSourceName() {
|
||||
return _input.getSourceName();
|
||||
}
|
||||
|
||||
/** A convenience method for use most often with template rewrites.
|
||||
* Convert a List<Token> to List<String>
|
||||
|
|
|
@ -34,12 +34,11 @@ import org.antlr.v4.runtime.dfa.DFA;
|
|||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.antlr.v4.runtime.tree.AST;
|
||||
|
||||
/** This is the default error handling mechanism for ANTLR parsers
|
||||
* and tree parsers.
|
||||
*/
|
||||
public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol> {
|
||||
public class DefaultErrorStrategy implements ANTLRErrorStrategy {
|
||||
/** This is true after we see an error and before having successfully
|
||||
* matched a token. Prevents generation of more than one error message
|
||||
* per error.
|
||||
|
@ -57,24 +56,24 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
protected IntervalSet lastErrorStates;
|
||||
|
||||
@Override
|
||||
public void beginErrorCondition(BaseRecognizer<Symbol> recognizer) {
|
||||
public void beginErrorCondition(BaseRecognizer recognizer) {
|
||||
errorRecoveryMode = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inErrorRecoveryMode(BaseRecognizer<Symbol> recognizer) {
|
||||
public boolean inErrorRecoveryMode(BaseRecognizer recognizer) {
|
||||
return errorRecoveryMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endErrorCondition(BaseRecognizer<Symbol> recognizer) {
|
||||
public void endErrorCondition(BaseRecognizer recognizer) {
|
||||
errorRecoveryMode = false;
|
||||
lastErrorStates = null;
|
||||
lastErrorIndex = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportError(BaseRecognizer<Symbol> recognizer,
|
||||
public void reportError(BaseRecognizer recognizer,
|
||||
RecognitionException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
|
@ -98,7 +97,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
else {
|
||||
System.err.println("unknown recognition error type: "+e.getClass().getName());
|
||||
if ( recognizer!=null ) {
|
||||
recognizer.notifyListeners((Symbol)e.offendingNode, e.getMessage(), e);
|
||||
recognizer.notifyListeners((Token)e.offendingToken, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +106,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
* token that the match() routine could not recover from.
|
||||
*/
|
||||
@Override
|
||||
public void recover(BaseRecognizer<Symbol> recognizer, RecognitionException e) {
|
||||
public void recover(BaseRecognizer recognizer, RecognitionException e) {
|
||||
// System.out.println("recover in "+recognizer.getRuleInvocationStack()+
|
||||
// " index="+recognizer.getInputStream().index()+
|
||||
// ", lastErrorIndex="+
|
||||
|
@ -147,13 +146,13 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
* We opt to stay in the loop as long as possible.
|
||||
*/
|
||||
@Override
|
||||
public void sync(BaseRecognizer<Symbol> recognizer) {
|
||||
public void sync(BaseRecognizer recognizer) {
|
||||
ATNState s = recognizer.getInterpreter().atn.states.get(recognizer._ctx.s);
|
||||
// System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName());
|
||||
// If already recovering, don't try to sync
|
||||
if ( errorRecoveryMode ) return;
|
||||
|
||||
SymbolStream<Symbol> tokens = recognizer.getInputStream();
|
||||
SymbolStream<Token> tokens = recognizer.getInputStream();
|
||||
int la = tokens.LA(1);
|
||||
|
||||
// try cheaper subset first; might get lucky. seems to shave a wee bit off
|
||||
|
@ -185,46 +184,47 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
// do nothing if we can't identify the exact kind of ATN state
|
||||
}
|
||||
|
||||
public void reportNoViableAlternative(BaseRecognizer<Symbol> recognizer,
|
||||
public void reportNoViableAlternative(BaseRecognizer recognizer,
|
||||
NoViableAltException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
SymbolStream<Symbol> tokens = recognizer.getInputStream();
|
||||
SymbolStream<Token> tokens = recognizer.getInputStream();
|
||||
String input;
|
||||
if (tokens instanceof TokenStream) {
|
||||
if ( e.startToken.getType()==Token.EOF ) input = "<EOF>";
|
||||
else input = ((TokenStream)tokens).toString(e.startToken, e.offendingToken);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
input = "<unknown input>";
|
||||
}
|
||||
String msg = "no viable alternative at input "+escapeWSAndQuote(input);
|
||||
recognizer.notifyListeners((Symbol) e.offendingNode, msg, e);
|
||||
recognizer.notifyListeners((Token) e.offendingToken, msg, e);
|
||||
}
|
||||
|
||||
public void reportInputMismatch(BaseRecognizer<Symbol> recognizer,
|
||||
public void reportInputMismatch(BaseRecognizer recognizer,
|
||||
InputMismatchException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
String msg = "mismatched input "+getTokenErrorDisplay((Symbol)e.offendingNode)+
|
||||
String msg = "mismatched input "+getTokenErrorDisplay((Token)e.offendingToken)+
|
||||
" expecting "+e.getExpectedTokens().toString(recognizer.getTokenNames());
|
||||
recognizer.notifyListeners((Symbol)e.offendingNode, msg, e);
|
||||
recognizer.notifyListeners((Token)e.offendingToken, msg, e);
|
||||
}
|
||||
|
||||
public void reportFailedPredicate(BaseRecognizer<Symbol> recognizer,
|
||||
public void reportFailedPredicate(BaseRecognizer recognizer,
|
||||
FailedPredicateException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
String ruleName = recognizer.getRuleNames()[recognizer._ctx.getRuleIndex()];
|
||||
String msg = "rule "+ruleName+" "+e.msg;
|
||||
recognizer.notifyListeners((Symbol)e.offendingNode, msg, e);
|
||||
recognizer.notifyListeners((Token)e.offendingToken, msg, e);
|
||||
}
|
||||
|
||||
public void reportUnwantedToken(BaseRecognizer<Symbol> recognizer) {
|
||||
public void reportUnwantedToken(BaseRecognizer recognizer) {
|
||||
if (errorRecoveryMode) return;
|
||||
recognizer.syntaxErrors++;
|
||||
beginErrorCondition(recognizer);
|
||||
|
||||
Symbol t = recognizer.getCurrentInputSymbol();
|
||||
Token t = recognizer.getCurrentToken();
|
||||
String tokenName = getTokenErrorDisplay(t);
|
||||
IntervalSet expecting = getExpectedTokens(recognizer);
|
||||
String msg = "extraneous input "+tokenName+" expecting "+
|
||||
|
@ -232,12 +232,12 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
recognizer.notifyListeners(t, msg, null);
|
||||
}
|
||||
|
||||
public void reportMissingToken(BaseRecognizer<Symbol> recognizer) {
|
||||
public void reportMissingToken(BaseRecognizer recognizer) {
|
||||
if (errorRecoveryMode) return;
|
||||
recognizer.syntaxErrors++;
|
||||
beginErrorCondition(recognizer);
|
||||
|
||||
Symbol t = recognizer.getCurrentInputSymbol();
|
||||
Token t = recognizer.getCurrentToken();
|
||||
IntervalSet expecting = getExpectedTokens(recognizer);
|
||||
String msg = "missing "+expecting.toString(recognizer.getTokenNames())+
|
||||
" at "+getTokenErrorDisplay(t);
|
||||
|
@ -275,11 +275,11 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
* reference in rule atom. It can assume that you forgot the ')'.
|
||||
*/
|
||||
@Override
|
||||
public Symbol recoverInline(BaseRecognizer<Symbol> recognizer)
|
||||
public Token recoverInline(BaseRecognizer recognizer)
|
||||
throws RecognitionException
|
||||
{
|
||||
// SINGLE TOKEN DELETION
|
||||
Symbol matchedSymbol = singleTokenDeletion(recognizer);
|
||||
Token matchedSymbol = singleTokenDeletion(recognizer);
|
||||
if ( matchedSymbol!=null ) {
|
||||
// we have deleted the extra token.
|
||||
// now, move past ttype token as if all were ok
|
||||
|
@ -297,7 +297,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
}
|
||||
|
||||
// if next token is what we are looking for then "delete" this token
|
||||
public boolean singleTokenInsertion(BaseRecognizer<Symbol> recognizer) {
|
||||
public boolean singleTokenInsertion(BaseRecognizer recognizer) {
|
||||
int currentSymbolType = recognizer.getInputStream().LA(1);
|
||||
// if current token is consistent with what could come after current
|
||||
// ATN state, then we know we're missing a token; error recovery
|
||||
|
@ -313,7 +313,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
return false;
|
||||
}
|
||||
|
||||
public Symbol singleTokenDeletion(BaseRecognizer<Symbol> recognizer) {
|
||||
public Token singleTokenDeletion(BaseRecognizer recognizer) {
|
||||
int nextTokenType = recognizer.getInputStream().LA(2);
|
||||
IntervalSet expecting = getExpectedTokens(recognizer);
|
||||
if ( expecting.contains(nextTokenType) ) {
|
||||
|
@ -326,7 +326,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
*/
|
||||
recognizer.consume(); // simply delete extra token
|
||||
// we want to return the token we're actually matching
|
||||
Symbol matchedSymbol = recognizer.getCurrentInputSymbol();
|
||||
Token matchedSymbol = recognizer.getCurrentToken();
|
||||
endErrorCondition(recognizer); // we know current token is correct
|
||||
return matchedSymbol;
|
||||
}
|
||||
|
@ -352,8 +352,8 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
* If you change what tokens must be created by the lexer,
|
||||
* override this method to create the appropriate tokens.
|
||||
*/
|
||||
protected Symbol getMissingSymbol(BaseRecognizer<Symbol> recognizer) {
|
||||
Symbol currentSymbol = recognizer.getCurrentInputSymbol();
|
||||
protected Token getMissingSymbol(BaseRecognizer recognizer) {
|
||||
Token currentSymbol = recognizer.getCurrentToken();
|
||||
if (!(currentSymbol instanceof Token)) {
|
||||
throw new UnsupportedOperationException("This error strategy only supports Token symbols.");
|
||||
}
|
||||
|
@ -373,10 +373,10 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
t.channel = Token.DEFAULT_CHANNEL;
|
||||
t.source = current.getTokenSource();
|
||||
t.index = -1; // indicate we conjured this up because it has no index
|
||||
return (Symbol)t;
|
||||
return (Token)t;
|
||||
}
|
||||
|
||||
public IntervalSet getExpectedTokens(BaseRecognizer<Symbol> recognizer) {
|
||||
public IntervalSet getExpectedTokens(BaseRecognizer recognizer) {
|
||||
return recognizer.getExpectedTokens();
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
* your token objects because you don't have to go modify your lexer
|
||||
* so that it creates a new Java type.
|
||||
*/
|
||||
public String getTokenErrorDisplay(Symbol t) {
|
||||
public String getTokenErrorDisplay(Token t) {
|
||||
if ( t==null ) return "<no token>";
|
||||
String s = getSymbolText(t);
|
||||
if ( s==null ) {
|
||||
|
@ -402,25 +402,19 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
return escapeWSAndQuote(s);
|
||||
}
|
||||
|
||||
protected String getSymbolText(@NotNull Symbol symbol) {
|
||||
protected String getSymbolText(@NotNull Token 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 Symbol symbol) {
|
||||
protected int getSymbolType(@NotNull Token symbol) {
|
||||
if (symbol instanceof Token) {
|
||||
return ((Token)symbol).getType();
|
||||
}
|
||||
else if (symbol instanceof AST) {
|
||||
return ((AST)symbol).getType();
|
||||
}
|
||||
else {
|
||||
return Token.INVALID_TYPE;
|
||||
}
|
||||
|
@ -526,7 +520,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
* 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<Symbol> recognizer) {
|
||||
protected IntervalSet getErrorRecoverySet(BaseRecognizer recognizer) {
|
||||
ATN atn = recognizer.getInterpreter().atn;
|
||||
RuleContext ctx = recognizer._ctx;
|
||||
IntervalSet recoverSet = new IntervalSet();
|
||||
|
@ -544,7 +538,7 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
}
|
||||
|
||||
/** Consume tokens until one matches the given token set */
|
||||
public void consumeUntil(BaseRecognizer<Symbol> recognizer, IntervalSet set) {
|
||||
public void consumeUntil(BaseRecognizer recognizer, IntervalSet set) {
|
||||
// System.err.println("consumeUntil("+set.toString(recognizer.getTokenNames())+")");
|
||||
int ttype = recognizer.getInputStream().LA(1);
|
||||
while (ttype != Token.EOF && !set.contains(ttype) ) {
|
||||
|
@ -556,14 +550,14 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportAmbiguity(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
public void reportAmbiguity(@NotNull BaseRecognizer recognizer,
|
||||
DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportAttemptingFullContext(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
public void reportAttemptingFullContext(@NotNull BaseRecognizer recognizer,
|
||||
@NotNull DFA dfa,
|
||||
int startIndex, int stopIndex,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs)
|
||||
|
@ -571,13 +565,13 @@ public class DefaultErrorStrategy<Symbol> implements ANTLRErrorStrategy<Symbol>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportContextSensitivity(@NotNull BaseRecognizer<Symbol> recognizer, @NotNull DFA dfa,
|
||||
public void reportContextSensitivity(@NotNull BaseRecognizer recognizer, @NotNull DFA dfa,
|
||||
int startIndex, int stopIndex, @NotNull OrderedHashSet<ATNConfig> configs)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportInsufficientPredicates(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
public void reportInsufficientPredicates(@NotNull BaseRecognizer recognizer,
|
||||
@NotNull DFA dfa,
|
||||
int startIndex, int stopIndex,
|
||||
@NotNull IntervalSet ambigAlts,
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
import org.antlr.v4.runtime.tree.gui.TreeViewer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class DefaultTreeGrammarErrorStrategy<T> extends DefaultErrorStrategy<T> {
|
||||
@Override
|
||||
public void beginErrorCondition(BaseRecognizer<T> recognizer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportError(BaseRecognizer<T> recognizer, RecognitionException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
super.reportError(recognizer, e);
|
||||
TreeParser<T> parser = (TreeParser<T>)recognizer;
|
||||
ASTNodeStream<T> input = parser.getInputStream();
|
||||
Object root = input.getTreeSource();
|
||||
// If instanceof Tree, we can show in TreeViewer
|
||||
if ( root instanceof Tree ) {
|
||||
TreeViewer viewer = new TreeViewer(recognizer, (Tree)root);
|
||||
viewer.open();
|
||||
List<T> unmatchedNodes = null;
|
||||
if ( e instanceof NoViableTreeGrammarAltException ) {
|
||||
NoViableTreeGrammarAltException nva =
|
||||
(NoViableTreeGrammarAltException)e;
|
||||
unmatchedNodes = getNodeList(input, nva);
|
||||
}
|
||||
else {
|
||||
unmatchedNodes = new ArrayList<T>();
|
||||
unmatchedNodes.add((T)e.offendingNode);
|
||||
}
|
||||
viewer.setHighlightedBoxColor(TreeViewer.LIGHT_RED);
|
||||
viewer.addHighlightedNodes((List<Tree>)unmatchedNodes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportNoViableAlternative(BaseRecognizer<T> recognizer,
|
||||
NoViableAltException e)
|
||||
throws RecognitionException
|
||||
{
|
||||
TreeParser<T> parser = (TreeParser<T>)recognizer;
|
||||
ASTNodeStream<T> input = parser.getInputStream();
|
||||
List<T> unmatchedNodes =
|
||||
getNodeList(input, (NoViableTreeGrammarAltException)e);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
ASTAdaptor<T> adap = input.getTreeAdaptor();
|
||||
for (int i = 0; i < unmatchedNodes.size(); i++) {
|
||||
if ( i>0 ) buf.append(" ");
|
||||
T t = unmatchedNodes.get(i);
|
||||
buf.append(adap.getText(t));
|
||||
}
|
||||
String s = buf.toString();
|
||||
String msg = "no viable alternative at node(s) "+escapeWSAndQuote(s);
|
||||
recognizer.notifyListeners((T)e.offendingNode, msg, e);
|
||||
}
|
||||
|
||||
protected List<T> getNodeList(ASTNodeStream<T> input,
|
||||
NoViableTreeGrammarAltException nva)
|
||||
{
|
||||
List<T> unmatchedNodes;
|
||||
T start = (T)nva.startNode;
|
||||
T stop = (T)nva.offendingNode;
|
||||
if ( input instanceof BufferedASTNodeStream) {
|
||||
BufferedASTNodeStream<T> b =
|
||||
(BufferedASTNodeStream<T>)input;
|
||||
unmatchedNodes = b.get(start, stop);
|
||||
}
|
||||
else {
|
||||
// if not buffered then we can't get from start to stop;
|
||||
// just highlight the start/stop nodes, but not in between
|
||||
unmatchedNodes = new ArrayList<T>();
|
||||
if ( nva.startNode!=null ) {
|
||||
unmatchedNodes.add((T)nva.startNode);
|
||||
}
|
||||
if ( nva.startNode==null || nva.offendingNode!=nva.startNode ) {
|
||||
unmatchedNodes.add((T)nva.offendingNode);
|
||||
}
|
||||
}
|
||||
return unmatchedNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T recoverInline(BaseRecognizer<T> recognizer) throws RecognitionException {
|
||||
InputMismatchException e = new InputMismatchException(recognizer);
|
||||
reportError(recognizer, e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recover(BaseRecognizer<T> recognizer, RecognitionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sync(BaseRecognizer<T> recognizer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inErrorRecoveryMode(BaseRecognizer<T> recognizer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endErrorCondition(BaseRecognizer<T> recognizer) {
|
||||
}
|
||||
}
|
|
@ -39,9 +39,9 @@ import org.antlr.v4.runtime.misc.OrderedHashSet;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DiagnosticErrorStrategy<Symbol> extends DefaultErrorStrategy<Symbol> {
|
||||
public class DiagnosticErrorStrategy extends DefaultErrorStrategy {
|
||||
@Override
|
||||
public void reportAmbiguity(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
public void reportAmbiguity(@NotNull BaseRecognizer recognizer,
|
||||
DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs)
|
||||
{
|
||||
|
@ -50,7 +50,7 @@ public class DiagnosticErrorStrategy<Symbol> extends DefaultErrorStrategy<Symbol
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportAttemptingFullContext(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
public void reportAttemptingFullContext(@NotNull BaseRecognizer recognizer,
|
||||
@NotNull DFA dfa,
|
||||
int startIndex, int stopIndex,
|
||||
@NotNull OrderedHashSet<ATNConfig> configs)
|
||||
|
@ -60,7 +60,7 @@ public class DiagnosticErrorStrategy<Symbol> extends DefaultErrorStrategy<Symbol
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportContextSensitivity(@NotNull BaseRecognizer<Symbol> recognizer, @NotNull DFA dfa,
|
||||
public void reportContextSensitivity(@NotNull BaseRecognizer recognizer, @NotNull DFA dfa,
|
||||
int startIndex, int stopIndex, @NotNull OrderedHashSet<ATNConfig> configs)
|
||||
{
|
||||
recognizer.notifyListeners("reportContextSensitivity d="+dfa.decision +": "+ configs + ", input='" +
|
||||
|
@ -68,7 +68,7 @@ public class DiagnosticErrorStrategy<Symbol> extends DefaultErrorStrategy<Symbol
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportInsufficientPredicates(@NotNull BaseRecognizer<Symbol> recognizer,
|
||||
public void reportInsufficientPredicates(@NotNull BaseRecognizer recognizer,
|
||||
@NotNull DFA dfa,
|
||||
int startIndex, int stopIndex,
|
||||
@NotNull IntervalSet ambigAlts,
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
*/
|
||||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.PredicateTransition;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.tree.AST;
|
||||
|
||||
/** A semantic predicate failed during validation. Validation of predicates
|
||||
* occurs when normally parsing the alternative just like matching a token.
|
||||
|
@ -42,24 +42,18 @@ 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.getInterpreter().atn.states.get(recognizer._ctx.s);
|
||||
PredicateTransition trans = (PredicateTransition)s.transition(0);
|
||||
ruleIndex = trans.ruleIndex;
|
||||
predIndex = trans.predIndex;
|
||||
this.msg = msg;
|
||||
Object la = recognizer.getCurrentInputSymbol();
|
||||
this.offendingNode = la;
|
||||
if ( la instanceof AST) {
|
||||
this.offendingToken = ((AST)la).getPayload();
|
||||
}
|
||||
else {
|
||||
this.offendingToken = (Token)la;
|
||||
}
|
||||
Token la = recognizer.getCurrentToken();
|
||||
this.offendingToken = la;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.tree.AST;
|
||||
|
||||
/** This signifies any kind of mismatched input exceptions such as
|
||||
* 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.offendingToken = ((AST)la).getPayload();
|
||||
}
|
||||
else {
|
||||
this.offendingToken = (Token)la;
|
||||
}
|
||||
Token la = recognizer.getCurrentToken();
|
||||
this.offendingToken = la;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,27 +45,24 @@ public class NoViableAltException extends RecognitionException {
|
|||
*/
|
||||
public Token startToken;
|
||||
|
||||
public <Symbol extends Token> NoViableAltException(BaseRecognizer<Symbol> recognizer) { // LL(1) error
|
||||
public <Symbol extends Token> NoViableAltException(BaseRecognizer recognizer) { // LL(1) error
|
||||
this(recognizer,recognizer.getInputStream(),
|
||||
recognizer.getCurrentInputSymbol(),
|
||||
recognizer.getCurrentInputSymbol(),
|
||||
recognizer.getCurrentInputSymbol(),
|
||||
recognizer.getCurrentToken(),
|
||||
recognizer.getCurrentToken(),
|
||||
null,
|
||||
recognizer._ctx);
|
||||
}
|
||||
|
||||
public <Symbol> NoViableAltException(BaseRecognizer<Symbol> recognizer,
|
||||
public <Symbol> NoViableAltException(BaseRecognizer recognizer,
|
||||
SymbolStream<Symbol> input,
|
||||
Token startToken,
|
||||
Token offendingToken,
|
||||
Symbol offendingNode,
|
||||
OrderedHashSet<ATNConfig> deadEndConfigs,
|
||||
ParserRuleContext ctx)
|
||||
{
|
||||
super(recognizer, input, ctx);
|
||||
this.deadEndConfigs = deadEndConfigs;
|
||||
this.startToken = startToken;
|
||||
this.offendingNode = offendingNode;
|
||||
this.offendingToken = offendingToken;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
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;
|
||||
|
||||
public <Symbol> NoViableTreeGrammarAltException(TreeParser<Symbol> recognizer) {
|
||||
this(recognizer,
|
||||
recognizer.getInputStream(),
|
||||
recognizer.getCurrentInputSymbol(),
|
||||
recognizer.getCurrentInputSymbol(),
|
||||
null,
|
||||
recognizer._ctx);
|
||||
}
|
||||
|
||||
public <Symbol> NoViableTreeGrammarAltException(BaseRecognizer<Symbol> recognizer,
|
||||
ASTNodeStream<Symbol> input,
|
||||
Symbol startNode,
|
||||
Symbol offendingNode,
|
||||
OrderedHashSet<ATNConfig> deadEndConfigs,
|
||||
ParserRuleContext ctx) {
|
||||
super(recognizer, input,
|
||||
input.getTreeAdaptor().getToken(startNode),
|
||||
input.getTreeAdaptor().getToken(offendingNode),
|
||||
offendingNode,
|
||||
deadEndConfigs, ctx);
|
||||
this.startNode = startNode;
|
||||
}
|
||||
}
|
|
@ -32,71 +32,11 @@ package org.antlr.v4.runtime;
|
|||
/** A parser for TokenStreams. "parser grammars" result in a subclass
|
||||
* of this.
|
||||
*/
|
||||
public class Parser extends BaseRecognizer<Token> {
|
||||
protected TokenStream _input;
|
||||
|
||||
public class Parser extends BaseRecognizer {
|
||||
public Parser(TokenStream input) {
|
||||
super(input);
|
||||
}
|
||||
|
||||
/** Always called by generated parsers upon entry to a rule.
|
||||
* This occurs after the new context has been pushed. Access field
|
||||
* _ctx get the current context.
|
||||
*
|
||||
* This is flexible because users do not have to regenerate parsers
|
||||
* to get trace facilities.
|
||||
*/
|
||||
@Override
|
||||
public void enterRule(ParserRuleContext<Token> localctx, int ruleIndex) {
|
||||
_ctx = localctx;
|
||||
_ctx.start = _input.LT(1);
|
||||
_ctx.ruleIndex = ruleIndex;
|
||||
if ( buildParseTrees ) addContextToParseTree();
|
||||
if ( _listener != null) {
|
||||
_listener.enterEveryRule(_ctx);
|
||||
_ctx.enterRule(_listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitRule(int ruleIndex) {
|
||||
// trigger event on _ctx, before it reverts to parent
|
||||
if ( _listener != null) {
|
||||
_ctx.exitRule(_listener);
|
||||
_listener.exitEveryRule(_ctx);
|
||||
}
|
||||
super.exitRule(ruleIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token match(int ttype) throws RecognitionException {
|
||||
return super.match(ttype);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token getCurrentInputSymbol() {
|
||||
return _input.LT(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenStream getInputStream() { return _input; }
|
||||
|
||||
@Override
|
||||
public final void setInputStream(IntStream input) {
|
||||
setTokenStream((TokenStream)input);
|
||||
}
|
||||
|
||||
/** Set the token stream and reset the parser */
|
||||
public void setTokenStream(TokenStream input) {
|
||||
this._input = null;
|
||||
reset();
|
||||
this._input = input;
|
||||
}
|
||||
|
||||
public TokenStream getTokenStream() {
|
||||
return _input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSourceName() {
|
||||
return _input.getSourceName();
|
||||
|
|
|
@ -220,7 +220,7 @@ public class ParserRuleContext<Symbol> extends RuleContext {
|
|||
}
|
||||
|
||||
/** Used for rule context info debugging during runtime, not so much for ATN debugging */
|
||||
public String toInfoString(BaseRecognizer<Symbol> recognizer) {
|
||||
public String toInfoString(BaseRecognizer recognizer) {
|
||||
List<String> rules = recognizer.getRuleInvocationStack();
|
||||
Collections.reverse(rules);
|
||||
return "ParserRuleContext"+rules+"{" +
|
||||
|
|
|
@ -58,11 +58,6 @@ public class RecognitionException extends RuntimeException {
|
|||
*/
|
||||
protected Token offendingToken;
|
||||
|
||||
/** If this is a tree parser exception, node is set to the node with
|
||||
* the problem.
|
||||
*/
|
||||
protected Object offendingNode;
|
||||
|
||||
protected int offendingState;
|
||||
|
||||
public RecognitionException(@Nullable Recognizer<?, ?> recognizer, IntStream input,
|
||||
|
@ -84,7 +79,7 @@ public class RecognitionException extends RuntimeException {
|
|||
|
||||
public IntervalSet getExpectedTokens() {
|
||||
// TODO: do we really need this type check?
|
||||
if ( recognizer!=null && recognizer instanceof BaseRecognizer<?> ) {
|
||||
if ( recognizer!=null && recognizer instanceof BaseRecognizer ) {
|
||||
return ((BaseRecognizer) recognizer).getExpectedTokens();
|
||||
}
|
||||
return null;
|
||||
|
@ -105,18 +100,4 @@ public class RecognitionException extends RuntimeException {
|
|||
public Recognizer<?, ?> getRecognizer() {
|
||||
return recognizer;
|
||||
}
|
||||
|
||||
// /** Return the token type or char of the unexpected input element */
|
||||
// public int getUnexpectedType() {
|
||||
// if ( recognizer==null ) return offendingToken.getType();
|
||||
// if ( recognizer.getInputStream() instanceof TokenStream) {
|
||||
// return offendingToken.getType();
|
||||
// }
|
||||
// else if ( recognizer.getInputStream() instanceof ASTNodeStream) {
|
||||
// ASTNodeStream nodes = (ASTNodeStream)recognizer.getInputStream();
|
||||
// ASTAdaptor adaptor = nodes.getTreeAdaptor();
|
||||
// return adaptor.getType(offendingNode);
|
||||
// }
|
||||
// return Token.INVALID_TYPE;
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ import java.util.List;
|
|||
public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
|
||||
public static final int EOF=-1;
|
||||
|
||||
protected ANTLRErrorStrategy<Symbol> _errHandler = new DefaultErrorStrategy<Symbol>();
|
||||
protected ANTLRErrorStrategy _errHandler = new DefaultErrorStrategy();
|
||||
|
||||
private List<ANTLRErrorListener<Symbol>> _listeners;
|
||||
|
||||
|
@ -117,9 +117,9 @@ public abstract class Recognizer<Symbol, ATNInterpreter extends ATNSimulator> {
|
|||
return _listeners.toArray(EMPTY_LISTENERS);
|
||||
}
|
||||
|
||||
public ANTLRErrorStrategy<Symbol> getErrorHandler() { return _errHandler; }
|
||||
public ANTLRErrorStrategy getErrorHandler() { return _errHandler; }
|
||||
|
||||
public void setErrorHandler(ANTLRErrorStrategy<Symbol> h) { this._errHandler = h; }
|
||||
public void setErrorHandler(ANTLRErrorStrategy h) { this._errHandler = h; }
|
||||
|
||||
// subclass needs to override these if there are sempreds or actions
|
||||
// that the ATN interp needs to execute
|
||||
|
|
|
@ -255,18 +255,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
|
||||
{
|
||||
|
@ -277,7 +277,7 @@ 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,8 +87,8 @@ public interface Token {
|
|||
int getChannel();
|
||||
|
||||
/** An index from 0..n-1 of the token object in the input stream.
|
||||
* This must be valid in order to print token streams,
|
||||
* use TokenRewriteStream, and generally deal with ASTs.
|
||||
* This must be valid in order to print token streams and
|
||||
* use TokenRewriteStream.
|
||||
*
|
||||
* Return -1 to indicate that this token was conjured up since
|
||||
* it doesn't have a valid index.
|
||||
|
|
|
@ -35,9 +35,6 @@ import org.antlr.v4.runtime.dfa.DFAState;
|
|||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.runtime.tree.ASTNodeStream;
|
||||
import org.antlr.v4.runtime.tree.BufferedASTNodeStream;
|
||||
import org.antlr.v4.runtime.tree.TreeParser;
|
||||
import org.stringtemplate.v4.misc.MultiMap;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -239,7 +236,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
public static int retry_with_context_indicates_no_conflict = 0;
|
||||
|
||||
@Nullable
|
||||
protected final BaseRecognizer<Symbol> parser;
|
||||
protected final BaseRecognizer parser;
|
||||
|
||||
@NotNull
|
||||
public final DFA[] decisionToDFA;
|
||||
|
@ -249,7 +246,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
this(null, atn);
|
||||
}
|
||||
|
||||
public v2ParserATNSimulator(@Nullable BaseRecognizer<Symbol> parser, @NotNull ATN atn) {
|
||||
public v2ParserATNSimulator(@Nullable BaseRecognizer parser, @NotNull ATN atn) {
|
||||
super(atn);
|
||||
this.parser = parser;
|
||||
// ctxToDFAs = new HashMap<RuleContext, DFA[]>();
|
||||
|
@ -264,7 +261,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
public void reset() {
|
||||
}
|
||||
|
||||
public int adaptivePredict(@NotNull SymbolStream<Symbol> input, int decision,
|
||||
public int adaptivePredict(@NotNull SymbolStream<Token> input, int decision,
|
||||
@Nullable ParserRuleContext outerContext)
|
||||
{
|
||||
predict_calls++;
|
||||
|
@ -291,7 +288,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
}
|
||||
}
|
||||
|
||||
public int predictATN(@NotNull DFA dfa, @NotNull SymbolStream<Symbol> input,
|
||||
public int predictATN(@NotNull DFA dfa, @NotNull SymbolStream<Token> input,
|
||||
@Nullable ParserRuleContext outerContext)
|
||||
{
|
||||
if ( outerContext==null ) outerContext = ParserRuleContext.EMPTY;
|
||||
|
@ -323,7 +320,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
}
|
||||
|
||||
public int execDFA(@NotNull DFA dfa, @NotNull DFAState s0,
|
||||
@NotNull SymbolStream<Symbol> input, int startIndex,
|
||||
@NotNull SymbolStream<Token> input, int startIndex,
|
||||
@Nullable ParserRuleContext outerContext)
|
||||
{
|
||||
if ( outerContext==null ) outerContext = ParserRuleContext.EMPTY;
|
||||
|
@ -476,7 +473,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
|
||||
*/
|
||||
public int execATN(@NotNull DFA dfa, @NotNull DFAState s0,
|
||||
@NotNull SymbolStream<Symbol> input, int startIndex,
|
||||
@NotNull SymbolStream<Token> input, int startIndex,
|
||||
ParserRuleContext outerContext)
|
||||
{
|
||||
if ( debug ) System.out.println("execATN decision "+dfa.decision+" exec LA(1)=="+ getLookaheadName(input));
|
||||
|
@ -597,7 +594,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
public ATNConfigSet execATNWithFullContext(DFA dfa,
|
||||
DFAState D, // how far we got before failing over
|
||||
@NotNull ATNConfigSet s0,
|
||||
@NotNull SymbolStream<Symbol> input, int startIndex,
|
||||
@NotNull SymbolStream<Token> input, int startIndex,
|
||||
ParserRuleContext outerContext,
|
||||
int nalts,
|
||||
boolean greedy)
|
||||
|
@ -1219,7 +1216,7 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
return String.valueOf(t);
|
||||
}
|
||||
|
||||
public String getLookaheadName(SymbolStream<Symbol> input) {
|
||||
public String getLookaheadName(SymbolStream<Token> input) {
|
||||
return getTokenName(input.LA(1));
|
||||
}
|
||||
|
||||
|
@ -1244,30 +1241,16 @@ public class v2ParserATNSimulator<Symbol> extends ATNSimulator {
|
|||
}
|
||||
|
||||
@NotNull
|
||||
public NoViableAltException noViableAlt(@NotNull SymbolStream<Symbol> input,
|
||||
public NoViableAltException noViableAlt(@NotNull SymbolStream<Token> input,
|
||||
@NotNull ParserRuleContext outerContext,
|
||||
@NotNull ATNConfigSet configs,
|
||||
int startIndex)
|
||||
{
|
||||
if ( parser instanceof TreeParser) {
|
||||
Symbol startNode = null;
|
||||
if ( input instanceof BufferedASTNodeStream) {
|
||||
startNode = input.get(startIndex);
|
||||
}
|
||||
return new NoViableTreeGrammarAltException(parser,
|
||||
(ASTNodeStream<Symbol>)input,
|
||||
startNode,
|
||||
input.LT(1),
|
||||
configs, outerContext);
|
||||
}
|
||||
else {
|
||||
return new NoViableAltException(parser, input,
|
||||
(Token)input.get(startIndex),
|
||||
(Token)input.LT(1),
|
||||
input.LT(1),
|
||||
configs, outerContext);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getUniqueAlt(@NotNull Collection<ATNConfig> configs) {
|
||||
int alt = ATN.INVALID_ALT_NUMBER;
|
||||
|
|
|
@ -33,6 +33,8 @@ import org.antlr.v4.runtime.*;
|
|||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
@ -50,8 +52,9 @@ public class TestRig {
|
|||
boolean gui = false;
|
||||
String psFile = null;
|
||||
boolean showTokens = false;
|
||||
String encoding = null;
|
||||
if ( args.length < 2 ) {
|
||||
System.err.println("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName [-print] [-tokens] [-gui] [-ps file.ps] [input-filename]");
|
||||
System.err.println("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName [-print] [-tokens] [-gui] [-encoding encodingname] [-ps file.ps] [input-filename]");
|
||||
return;
|
||||
}
|
||||
int i=0;
|
||||
|
@ -75,6 +78,14 @@ public class TestRig {
|
|||
if ( arg.equals("-tokens") ) {
|
||||
showTokens = true;
|
||||
}
|
||||
else if ( arg.equals("-encoding") ) {
|
||||
if ( i>=args.length ) {
|
||||
System.err.println("missing encoding on -encoding");
|
||||
return;
|
||||
}
|
||||
encoding = args[i];
|
||||
i++;
|
||||
}
|
||||
else if ( arg.equals("-ps") ) {
|
||||
if ( i>=args.length ) {
|
||||
System.err.println("missing filename on -ps");
|
||||
|
@ -101,8 +112,16 @@ public class TestRig {
|
|||
if ( inputFile!=null ) {
|
||||
is = new FileInputStream(inputFile);
|
||||
}
|
||||
Reader r;
|
||||
if ( encoding!=null ) {
|
||||
r = new InputStreamReader(is, encoding);
|
||||
}
|
||||
else {
|
||||
r = new InputStreamReader(is);
|
||||
}
|
||||
|
||||
ANTLRInputStream input = new ANTLRInputStream(is);
|
||||
try {
|
||||
ANTLRInputStream input = new ANTLRInputStream(r);
|
||||
|
||||
Constructor<Lexer> lexerCtor = lexerClass.getConstructor(CharStream.class);
|
||||
Lexer lexer = lexerCtor.newInstance(input);
|
||||
|
@ -118,7 +137,7 @@ public class TestRig {
|
|||
Constructor<Parser> parserCtor = parserClass.getConstructor(TokenStream.class);
|
||||
Parser parser = parserCtor.newInstance(tokens);
|
||||
|
||||
parser.setErrorHandler(new DiagnosticErrorStrategy<Token>());
|
||||
parser.setErrorHandler(new DiagnosticErrorStrategy());
|
||||
|
||||
if ( printTree || gui || psFile!=null ) {
|
||||
parser.setBuildParseTree(true);
|
||||
|
@ -137,4 +156,9 @@ public class TestRig {
|
|||
tree.save(parser, psFile); // Generate postscript
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if ( r!=null ) r.close();
|
||||
if ( is!=null ) is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
/** An abstract syntax tree built by ANTLR during a parse. */
|
||||
public interface AST extends SyntaxTree {
|
||||
/** Indicates the node is a nil node but may still have children, meaning
|
||||
* the tree is a flat list.
|
||||
*/
|
||||
boolean isNil();
|
||||
|
||||
/** Return a token type; needed for tree parsing */
|
||||
int getType();
|
||||
|
||||
/** Text for this node alone, not the subtree */
|
||||
String getText();
|
||||
|
||||
// TODO: do we need line/charpos????
|
||||
/** In case we don't have a token payload, what is the line for errors? */
|
||||
int getLine();
|
||||
|
||||
int getCharPositionInLine();
|
||||
|
||||
/** Redefined from Tree interface so we can narrow the return type */
|
||||
@Override
|
||||
AST getParent();
|
||||
|
||||
/** Redefined from Tree interface so we can narrow the return type */
|
||||
@Override
|
||||
Token getPayload();
|
||||
}
|
|
@ -1,262 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** How to create and navigate trees. Rather than have a separate factory
|
||||
* and adaptor, I've merged them. Makes sense to encapsulate.
|
||||
*
|
||||
* I do not need to know the type of a tree at all so they are all
|
||||
* generic Objects.
|
||||
*/
|
||||
public interface ASTAdaptor<T> {
|
||||
// BEGIN new v4 stuff
|
||||
|
||||
/** Used to track elements to left of -> for use in rewrite. These
|
||||
* are some kind of trees, but we generically use Object
|
||||
* for tree types in ANTLR.
|
||||
*/
|
||||
public List<T> createElementList();
|
||||
|
||||
/** Get the absolute index starting from 0 of this note within
|
||||
* a node stream. This should w
|
||||
ork even if the stream is not buffered
|
||||
*/
|
||||
// public int getNodeIndex(T t);
|
||||
|
||||
// END new v4 stuff
|
||||
|
||||
// C o n s t r u c t i o n
|
||||
|
||||
/** Create a tree node from Token object; for CommonAST type trees,
|
||||
* then the token just becomes the payload. This is the most
|
||||
* common create call.
|
||||
*
|
||||
* Override if you want another kind of node to be built.
|
||||
*/
|
||||
public T create(Token payload);
|
||||
|
||||
/** Duplicate a single tree node.
|
||||
* Override if you want another kind of node to be built.
|
||||
*/
|
||||
public T dupNode(T treeNode);
|
||||
|
||||
/** Duplicate tree recursively, using dupNode() for each node */
|
||||
public T dupTree(T tree);
|
||||
|
||||
/** Return a nil node (an empty but non-null node) that can hold
|
||||
* a list of element as the children. If you want a flat tree (a list)
|
||||
* use "t=adaptor.nil(); t.addChild(x); t.addChild(y);"
|
||||
*/
|
||||
public T nil();
|
||||
|
||||
/** Is tree considered a nil node used to make lists of child nodes? */
|
||||
public boolean isNil(T tree);
|
||||
|
||||
/** Add a child to the tree t. If child is a flat tree (a list), make all
|
||||
* in list children of t. Warning: if t has no children, but child does
|
||||
* and child isNil then you can decide it is ok to move children to t via
|
||||
* t.children = child.children; i.e., without copying the array. Just
|
||||
* make sure that this is consistent with have the user will build
|
||||
* ASTs. Do nothing if t or child is null.
|
||||
*/
|
||||
public void addChild(T t, T child);
|
||||
|
||||
/** If oldRoot is a nil root, just copy or move the children to newRoot.
|
||||
* If not a nil root, make oldRoot a child of newRoot.
|
||||
*
|
||||
* old=^(nil a b c), new=r yields ^(r a b c)
|
||||
* old=^(a b c), new=r yields ^(r ^(a b c))
|
||||
*
|
||||
* If newRoot is a nil-rooted single child tree, use the single
|
||||
* child as the new root node.
|
||||
*
|
||||
* old=^(nil a b c), new=^(nil r) yields ^(r a b c)
|
||||
* old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
|
||||
*
|
||||
* If oldRoot was null, it's ok, just return newRoot (even if isNil).
|
||||
*
|
||||
* old=null, new=r yields r
|
||||
* old=null, new=^(nil r) yields ^(nil r)
|
||||
*
|
||||
* Return newRoot. Throw an exception if newRoot is not a
|
||||
* simple node or nil root with a single child node--it must be a root
|
||||
* node. If newRoot is ^(nil x) return x as newRoot.
|
||||
*
|
||||
* Be advised that it's ok for newRoot to point at oldRoot's
|
||||
* children; i.e., you don't have to copy the list. We are
|
||||
* constructing these nodes so we should have this control for
|
||||
* efficiency.
|
||||
*/
|
||||
public T becomeRoot(T newRoot, T oldRoot);
|
||||
|
||||
/** Given the root of the subtree created for this rule, post process
|
||||
* it to do any simplifications or whatever you want. A required
|
||||
* behavior is to convert ^(nil singleSubtree) to singleSubtree
|
||||
* as the setting of start/stop indexes relies on a single non-nil root
|
||||
* for non-flat trees.
|
||||
*
|
||||
* Flat trees such as for lists like "idlist : ID+ ;" are left alone
|
||||
* unless there is only one ID. For a list, the start/stop indexes
|
||||
* are set in the nil node.
|
||||
*
|
||||
* This method is executed after all rule tree construction and right
|
||||
* before setTokenBoundaries().
|
||||
*/
|
||||
public T rulePostProcessing(T root);
|
||||
|
||||
/** For identifying trees.
|
||||
*
|
||||
* How to identify nodes so we can say "add node to a prior node"?
|
||||
* Even becomeRoot is an issue. Use System.identityHashCode(node)
|
||||
* usually.
|
||||
*/
|
||||
public int getUniqueID(T node);
|
||||
|
||||
|
||||
// R e w r i t e R u l e s
|
||||
|
||||
/** Create a node for newRoot make it the root of oldRoot.
|
||||
* If oldRoot is a nil root, just copy or move the children to newRoot.
|
||||
* If not a nil root, make oldRoot a child of newRoot.
|
||||
*
|
||||
* Return node created for newRoot.
|
||||
*
|
||||
* Be advised: when debugging ASTs, the DebugTreeAdaptor manually
|
||||
* calls create(Token child) and then plain becomeRoot(node, node)
|
||||
* because it needs to trap calls to create, but it can't since it delegates
|
||||
* to not inherits from the ASTAdaptor.
|
||||
*/
|
||||
public T becomeRoot(Token newRoot, T oldRoot);
|
||||
|
||||
/** Create a new node derived from a token, with a new token type.
|
||||
* This is invoked from an imaginary node ref on right side of a
|
||||
* rewrite rule as IMAG[$tokenLabel].
|
||||
*
|
||||
* This should invoke createToken(Token).
|
||||
*/
|
||||
public T create(int tokenType, Token fromToken);
|
||||
|
||||
/** Same as create(tokenType,fromToken) except set the text too.
|
||||
* This is invoked from an imaginary node ref on right side of a
|
||||
* rewrite rule as IMAG[$tokenLabel, "IMAG"].
|
||||
*
|
||||
* This should invoke createToken(Token).
|
||||
*/
|
||||
public T create(int tokenType, Token fromToken, String text);
|
||||
|
||||
/** Create a new node derived from a token, with a new token type.
|
||||
* This is invoked from an imaginary node ref on right side of a
|
||||
* rewrite rule as IMAG["IMAG"].
|
||||
*
|
||||
* This should invoke createToken(int,String).
|
||||
*/
|
||||
public T create(int tokenType, String text);
|
||||
|
||||
|
||||
// C o n t e n t
|
||||
|
||||
/** For tree parsing, I need to know the token type of a node */
|
||||
public int getType(T t);
|
||||
|
||||
/** Node constructors can set the type of a node */
|
||||
public void setType(T t, int type);
|
||||
|
||||
public String getText(T t);
|
||||
|
||||
/** Node constructors can set the text of a node */
|
||||
public void setText(T t, String text);
|
||||
|
||||
/** Return the token object from which this node was created.
|
||||
* Currently used only for printing an error message.
|
||||
* The error display routine in BaseRecognizer needs to
|
||||
* display where the input the error occurred. If your
|
||||
* tree of limitation does not store information that can
|
||||
* lead you to the token, you can create a token filled with
|
||||
* the appropriate information and pass that back. See
|
||||
* BaseRecognizer.getErrorMessage().
|
||||
*/
|
||||
public Token getToken(T t);
|
||||
|
||||
/** Where are the bounds in the input token stream for this node and
|
||||
* all children? Each rule that creates AST nodes will call this
|
||||
* method right before returning. Flat trees (i.e., lists) will
|
||||
* still usually have a nil root node just to hold the children list.
|
||||
* That node would contain the start/stop indexes then.
|
||||
*/
|
||||
public void setTokenBoundaries(T t, Token startToken, Token stopToken);
|
||||
|
||||
/** Get the token start index for this subtree; return -1 if no such index */
|
||||
public int getTokenStartIndex(T t);
|
||||
|
||||
/** Get the token stop index for this subtree; return -1 if no such index */
|
||||
public int getTokenStopIndex(T t);
|
||||
|
||||
|
||||
// N a v i g a t i o n / T r e e P a r s i n g
|
||||
|
||||
/** Get a child 0..n-1 node */
|
||||
public T getChild(T t, int i);
|
||||
|
||||
/** Set ith child (0..n-1) to t; t must be non-null and non-nil node */
|
||||
public void setChild(T t, int i, T child);
|
||||
|
||||
/** Remove ith child and shift children down from right. */
|
||||
public T deleteChild(T t, int i);
|
||||
|
||||
/** How many children? If 0, then this is a leaf node */
|
||||
public int getChildCount(T t);
|
||||
|
||||
/** Who is the parent node of this node; if null, implies node is root.
|
||||
* If your node type doesn't handle this, it's ok but the tree rewrites
|
||||
* in tree parsers need this functionality.
|
||||
*/
|
||||
public T getParent(T t);
|
||||
public void setParent(T t, T parent);
|
||||
|
||||
/** What index is this node in the child list? Range: 0..n-1
|
||||
* If your node type doesn't handle this, it's ok but the tree rewrites
|
||||
* in tree parsers need this functionality.
|
||||
*/
|
||||
public int getChildIndex(T t);
|
||||
public void setChildIndex(T t, int index);
|
||||
|
||||
/** Replace from start to stop child index of parent with t, which might
|
||||
* be a list. Number of children may be different
|
||||
* after this call.
|
||||
*
|
||||
* If parent is null, don't do anything; must be at root of overall tree.
|
||||
* Can't replace whatever points to the parent externally. Do nothing.
|
||||
*/
|
||||
public void replaceChildren(T parent, int startChildIndex, int stopChildIndex, T t);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
[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();
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.misc.FastQueue;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/** Return a node stream from a doubly-linked tree whose nodes
|
||||
* know what child index they are. No remove() is supported.
|
||||
*
|
||||
* Emit navigation nodes (DOWN, UP, and EOF) to let show tree structure.
|
||||
*/
|
||||
public class ASTIterator<T> implements Iterator<T> {
|
||||
protected ASTAdaptor<T> adaptor;
|
||||
protected T root;
|
||||
protected T tree;
|
||||
protected boolean firstTime = true;
|
||||
|
||||
// navigation nodes to return during walk and at end
|
||||
public T up;
|
||||
public T down;
|
||||
public T eof;
|
||||
|
||||
/** If we emit UP/DOWN nodes, we need to spit out multiple nodes per
|
||||
* next() call.
|
||||
*/
|
||||
protected FastQueue<T> nodes;
|
||||
|
||||
public ASTIterator(T tree) {
|
||||
this((tree instanceof CommonAST) ? (ASTAdaptor<T>)new CommonASTAdaptor() : null,
|
||||
tree);
|
||||
}
|
||||
|
||||
public ASTIterator(ASTAdaptor<T> adaptor, T tree) {
|
||||
this.adaptor = adaptor;
|
||||
this.tree = tree;
|
||||
this.root = tree;
|
||||
nodes = new FastQueue<T>();
|
||||
if ( adaptor!=null ) {
|
||||
down = adaptor.create(Token.DOWN, "DOWN");
|
||||
up = adaptor.create(Token.UP, "UP");
|
||||
eof = adaptor.create(Token.EOF, "EOF");
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
firstTime = true;
|
||||
tree = root;
|
||||
nodes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if ( firstTime ) return root!=null;
|
||||
if ( nodes!=null && nodes.size()>0 ) return true;
|
||||
if ( tree==null ) return false;
|
||||
if ( adaptor.getChildCount(tree)>0 ) return true;
|
||||
return adaptor.getParent(tree)!=null; // back at root?
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
if ( firstTime ) { // initial condition
|
||||
firstTime = false;
|
||||
if ( adaptor.getChildCount(tree)==0 ) { // single node tree (special)
|
||||
nodes.add(eof);
|
||||
return tree;
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
// if any queued up, use those first
|
||||
if ( nodes!=null && nodes.size()>0 ) return nodes.remove();
|
||||
|
||||
// no nodes left?
|
||||
if ( tree==null ) return eof;
|
||||
|
||||
// next node will be child 0 if any children
|
||||
if ( adaptor.getChildCount(tree)>0 ) {
|
||||
tree = adaptor.getChild(tree, 0);
|
||||
nodes.add(tree); // real node is next after DOWN
|
||||
return down;
|
||||
}
|
||||
// if no children, look for next sibling of tree or ancestor
|
||||
T parent = adaptor.getParent(tree);
|
||||
// while we're out of siblings, keep popping back up towards root
|
||||
while ( parent!=null &&
|
||||
adaptor.getChildIndex(tree)+1 >= adaptor.getChildCount(parent) )
|
||||
{
|
||||
nodes.add(up); // we're moving back up
|
||||
tree = parent;
|
||||
parent = adaptor.getParent(tree);
|
||||
}
|
||||
// no nodes left?
|
||||
if ( parent==null ) {
|
||||
tree = null; // back at root? nothing left then
|
||||
nodes.add(eof); // add to queue, might have UP nodes in there
|
||||
return nodes.remove();
|
||||
}
|
||||
|
||||
// must have found a node with an unvisited sibling
|
||||
// move to it and return it
|
||||
int nextSiblingIndex = adaptor.getChildIndex(tree) + 1;
|
||||
tree = adaptor.getChild(parent, nextSiblingIndex);
|
||||
nodes.add(tree); // add to queue, might have UP nodes in there
|
||||
return nodes.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() { throw new UnsupportedOperationException(); }
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
/** A stream of tree nodes, accessing nodes from a tree of some kind */
|
||||
public interface ASTNodeStream<T> extends SymbolStream<T> {
|
||||
/** Get a tree node at an absolute index i; 0..n-1.
|
||||
* If you don't want to buffer up nodes, then this method makes no
|
||||
* sense for you.
|
||||
*/
|
||||
@Override
|
||||
T get(int i);
|
||||
|
||||
/** Get tree node at current input pointer + i ahead where i=1 is next node.
|
||||
* i<0 indicates nodes in the past. So LT(-1) is previous node, but
|
||||
* implementations are not required to provide results for k < -1.
|
||||
* LT(0) is undefined. For i>=n, return null.
|
||||
* Return null for LT(0) and any index that results in an absolute address
|
||||
* that is negative.
|
||||
*
|
||||
* This is analogus to the LT() method of the TokenStream, but this
|
||||
* returns a tree node instead of a token. Makes code gen identical
|
||||
* for both parser and tree grammars. :)
|
||||
*/
|
||||
@Override
|
||||
T LT(int k);
|
||||
|
||||
/** Where is this stream pulling nodes from? This is not the name, but
|
||||
* the object that provides node objects.
|
||||
*/
|
||||
public T getTreeSource();
|
||||
|
||||
/** If the tree associated with this stream was created from a TokenStream,
|
||||
* you can specify it here. Used to do rule $text attribute in tree
|
||||
* parser. Optional unless you use tree parser rule text attribute
|
||||
* or output=template and rewrite=true options.
|
||||
*/
|
||||
public TokenStream getTokenStream();
|
||||
|
||||
/** What adaptor can tell me how to interpret/navigate nodes and
|
||||
* trees. E.g., get text of a node.
|
||||
*/
|
||||
public ASTAdaptor<T> getTreeAdaptor();
|
||||
|
||||
/** As we flatten the tree, we use UP, DOWN nodes to represent
|
||||
* the tree structure. When debugging we need unique nodes
|
||||
* so we have to instantiate new ones. When doing normal tree
|
||||
* parsing, it's slow and a waste of memory to create unique
|
||||
* navigation nodes. Default should be false;
|
||||
*/
|
||||
public void setUniqueNavigationNodes(boolean uniqueNavigationNodes);
|
||||
|
||||
/** Reset the tree node stream in such a way that it acts like
|
||||
* a freshly constructed stream.
|
||||
*/
|
||||
public void reset();
|
||||
|
||||
/** Return the text of all nodes from start to stop, inclusive.
|
||||
* If the stream does not buffer all the nodes then it can still
|
||||
* walk recursively from start until stop. You can always return
|
||||
* null or "" too, but users should not access $ruleLabel.text in
|
||||
* an action of course in that case.
|
||||
*/
|
||||
public String toString(T start, T stop);
|
||||
|
||||
|
||||
// REWRITING TREES (used by tree parser)
|
||||
|
||||
/** Replace from start to stop child index of parent with t, which might
|
||||
* be a list. Number of children may be different
|
||||
* after this call. The stream is notified because it is walking the
|
||||
* tree and might need to know you are monkeying with the underlying
|
||||
* tree. Also, it might be able to modify the node stream to avoid
|
||||
* restreaming for future phases.
|
||||
*
|
||||
* If parent is null, don't do anything; must be at root of overall tree.
|
||||
* Can't replace whatever points to the parent externally. Do nothing.
|
||||
*/
|
||||
public void replaceChildren(T parent, int startChildIndex, int stopChildIndex, T t);
|
||||
}
|
|
@ -1,308 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.BaseRecognizer;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.tree.gui.TreeViewer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/** A generic AST implementation with no payload. You must subclass to
|
||||
* actually have any user data. ANTLR v3 uses a list of children approach
|
||||
* instead of the child-sibling approach in v2. A flat tree (a list) is
|
||||
* an empty node whose children represent the list. An empty, but
|
||||
* non-null node is called "nil".
|
||||
*/
|
||||
public abstract class BaseAST implements AST {
|
||||
/** Who is the parent node of this node; if null, implies node is root */
|
||||
public BaseAST parent;
|
||||
|
||||
protected List<BaseAST> children;
|
||||
|
||||
/** What index is this node in the child list? Range: 0..n-1 */
|
||||
public int childIndex = -1;
|
||||
|
||||
public BaseAST() {
|
||||
}
|
||||
|
||||
/** Create a new node from an existing node does nothing for BaseTree
|
||||
* as there are no fields other than the children list, which cannot
|
||||
* be copied as the children are not considered part of this node.
|
||||
*/
|
||||
public BaseAST(AST node) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseAST getChild(int i) {
|
||||
if ( children==null || i>=children.size() ) {
|
||||
return null;
|
||||
}
|
||||
return children.get(i);
|
||||
}
|
||||
|
||||
/** Get the children internal List; note that if you directly mess with
|
||||
* the list, do so at your own risk.
|
||||
*/
|
||||
public List<BaseAST> getChildren() { return children; }
|
||||
|
||||
public AST getFirstChildWithType(int type) {
|
||||
return Trees.getFirstChildWithType(this, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount() {
|
||||
if ( children==null ) return 0;
|
||||
return children.size();
|
||||
}
|
||||
|
||||
/** Add t as child of this node.
|
||||
*
|
||||
* Warning: if t has no children, but child does
|
||||
* and child isNil then this routine moves children to t via
|
||||
* t.children = child.children; i.e., without copying the array.
|
||||
*/
|
||||
public void addChild(BaseAST t) {
|
||||
//System.out.println("add child "+t.toStringTree()+" "+this.toStringTree());
|
||||
//System.out.println("existing children: "+children);
|
||||
if ( t==null ) {
|
||||
return; // do nothing upon addChild(null)
|
||||
}
|
||||
BaseAST childTree = t;
|
||||
if ( childTree.isNil() ) { // t is an empty node possibly with children
|
||||
if ( this.children!=null && this.children == childTree.children ) {
|
||||
throw new RuntimeException("attempt to add child list to itself");
|
||||
}
|
||||
// just add all of childTree's children to this
|
||||
if ( childTree.children!=null ) {
|
||||
if ( this.children!=null ) { // must copy, this has children already
|
||||
int n = childTree.children.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
BaseAST c = childTree.children.get(i);
|
||||
this.children.add(c);
|
||||
// handle double-link stuff for each child of nil root
|
||||
c.setParent(this);
|
||||
c.setChildIndex(children.size()-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// no children for this but t has children; just set pointer
|
||||
// call general freshener routine
|
||||
this.children = childTree.children;
|
||||
this.freshenParentAndChildIndexes();
|
||||
}
|
||||
}
|
||||
}
|
||||
else { // child is not nil (don't care about children)
|
||||
if ( children==null ) {
|
||||
children = createChildrenList(); // create children list on demand
|
||||
}
|
||||
children.add(t);
|
||||
childTree.setParent(this);
|
||||
childTree.setChildIndex(children.size()-1);
|
||||
}
|
||||
// System.out.println("now children are: "+children);
|
||||
}
|
||||
|
||||
/** Add all elements of kids list as children of this node */
|
||||
public void addChildren(List<? extends BaseAST> kids) {
|
||||
if ( kids==null ) return;
|
||||
for (int i = 0; i < kids.size(); i++) {
|
||||
BaseAST t = kids.get(i);
|
||||
addChild(t);
|
||||
}
|
||||
}
|
||||
|
||||
public void setChild(int i, BaseAST t) {
|
||||
if ( t==null ) {
|
||||
return;
|
||||
}
|
||||
if ( t.isNil() ) {
|
||||
throw new IllegalArgumentException("Can't set single child to a list");
|
||||
}
|
||||
if ( children==null ) {
|
||||
children = createChildrenList();
|
||||
}
|
||||
children.set(i, t);
|
||||
t.setParent(this);
|
||||
t.setChildIndex(i);
|
||||
}
|
||||
|
||||
public int getChildIndex() {
|
||||
return childIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AST getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(BaseAST t) {
|
||||
this.parent = t;
|
||||
}
|
||||
|
||||
public void setChildIndex(int index) {
|
||||
this.childIndex = index;
|
||||
}
|
||||
|
||||
public BaseAST deleteChild(int i) {
|
||||
if ( children==null ) {
|
||||
return null;
|
||||
}
|
||||
BaseAST killed = children.remove(i);
|
||||
// walk rest and decrement their child indexes
|
||||
this.freshenParentAndChildIndexes(i);
|
||||
return killed;
|
||||
}
|
||||
|
||||
public boolean deleteChild(BaseAST t) {
|
||||
for (int i=0; i<children.size(); i++) {
|
||||
BaseAST c = children.get(i);
|
||||
if ( c == t ) {
|
||||
deleteChild(t.getChildIndex());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Insert child t at child position i (0..n) by shifting children
|
||||
i+1..n-1 to the right one position. Set parent / indexes properly
|
||||
but does NOT collapse nil-rooted t's that come in here like addChild.
|
||||
Set position i==n to add to end. Add @ 0 in empty list, adds 1st child.
|
||||
*/
|
||||
public void insertChild(int i, BaseAST t) {
|
||||
if (i < 0 || i > getChildCount()) {
|
||||
throw new IndexOutOfBoundsException(i+" out or range");
|
||||
}
|
||||
if ( children==null ) children = createChildrenList();
|
||||
children.add(i, t);
|
||||
// walk others to increment their child indexes
|
||||
// set index, parent of this one too
|
||||
this.freshenParentAndChildIndexes(i);
|
||||
}
|
||||
|
||||
/** Override in a subclass to change the impl of children list */
|
||||
protected List<BaseAST> createChildrenList() {
|
||||
return new ArrayList<BaseAST>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNil() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Set the parent and child index values for all child of t */
|
||||
public void freshenParentAndChildIndexes() {
|
||||
freshenParentAndChildIndexes(0);
|
||||
}
|
||||
|
||||
public void freshenParentAndChildIndexes(int offset) {
|
||||
int n = getChildCount();
|
||||
for (int c = offset; c < n; c++) {
|
||||
BaseAST child = getChild(c);
|
||||
child.setChildIndex(c);
|
||||
child.setParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void freshenParentAndChildIndexesDeeply() {
|
||||
freshenParentAndChildIndexesDeeply(0);
|
||||
}
|
||||
|
||||
public void freshenParentAndChildIndexesDeeply(int offset) {
|
||||
int n = getChildCount();
|
||||
for (int c = offset; c < n; c++) {
|
||||
BaseAST child = getChild(c);
|
||||
child.setChildIndex(c);
|
||||
child.setParent(this);
|
||||
child.freshenParentAndChildIndexesDeeply();
|
||||
}
|
||||
}
|
||||
|
||||
/** Walk upwards looking for ancestor with this token type. */
|
||||
public boolean hasAncestor(int ttype) { return getAncestor(ttype)!=null; }
|
||||
|
||||
/** Walk upwards and get first ancestor with this token type. */
|
||||
public Tree getAncestor(int ttype) { return Trees.getAncestor(this, ttype); }
|
||||
|
||||
/** Return a list of all ancestors of this node. The first node of
|
||||
* list is the root and the last is the parent of this node.
|
||||
*/
|
||||
@NotNull
|
||||
public List<? extends Tree> getAncestors() { return Trees.getAncestors(this); }
|
||||
|
||||
public void inspect(BaseRecognizer<?> parser) {
|
||||
TreeViewer viewer = new TreeViewer(parser, this);
|
||||
viewer.open();
|
||||
}
|
||||
|
||||
public void save(BaseRecognizer<?> parser, String fileName)
|
||||
throws IOException
|
||||
{
|
||||
Trees.writePS(this, parser, fileName);
|
||||
}
|
||||
|
||||
public void save(BaseRecognizer<?> parser, String fileName,
|
||||
String fontName, int fontSize)
|
||||
throws IOException
|
||||
{
|
||||
Trees.writePS(this, parser, fileName, fontName, fontSize);
|
||||
}
|
||||
|
||||
/** Don't use standard tree printing mechanism since ASTs can have nil
|
||||
* root nodes.
|
||||
*/
|
||||
@Override
|
||||
public String toStringTree() {
|
||||
return Trees.toStringTree(this, null);
|
||||
// if ( children==null || children.size()==0 ) {
|
||||
// return this.toString();
|
||||
// }
|
||||
// StringBuffer buf = new StringBuffer();
|
||||
// if ( !isNil() ) {
|
||||
// buf.append("(");
|
||||
// buf.append(this.toString());
|
||||
// buf.append(' ');
|
||||
// }
|
||||
// for (int i = 0; children!=null && i < children.size(); i++) {
|
||||
// AST t = children.get(i);
|
||||
// if ( i>0 ) {
|
||||
// buf.append(' ');
|
||||
// }
|
||||
// buf.append(t.toStringTree());
|
||||
// }
|
||||
// if ( !isNil() ) {
|
||||
// buf.append(")");
|
||||
// }
|
||||
// return buf.toString();
|
||||
}
|
||||
}
|
|
@ -1,286 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.WritableToken;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** An ASTAdaptor that works with any BaseAST implementation. */
|
||||
public abstract class BaseASTAdaptor<T extends BaseAST> implements ASTAdaptor<T> {
|
||||
/** System.identityHashCode() is not always unique; we have to
|
||||
* track ourselves. That's ok, it's only for debugging, though it's
|
||||
* expensive: we have to create a hashtable with all tree nodes in it.
|
||||
* TODO: rm?
|
||||
*/
|
||||
protected Map<BaseAST, Integer> treeToUniqueIDMap;
|
||||
protected int uniqueNodeID = 1;
|
||||
|
||||
@Override
|
||||
public List<T> createElementList() {
|
||||
return new ElementList<T>(this);
|
||||
}
|
||||
|
||||
// END v4 stuff
|
||||
|
||||
@Override
|
||||
public T nil() {
|
||||
return create(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNil(T tree) {
|
||||
return tree.isNil();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T dupTree(T tree) {
|
||||
return dupTree(tree, null);
|
||||
}
|
||||
|
||||
/** This is generic in the sense that it will work with any kind of
|
||||
* tree (not just AST interface). It invokes the adaptor routines
|
||||
* not the tree node routines to do the construction.
|
||||
*/
|
||||
public T dupTree(T t, T parent) {
|
||||
if ( t==null ) {
|
||||
return null;
|
||||
}
|
||||
T newTree = dupNode(t);
|
||||
// ensure new subtree root has parent/child index set
|
||||
setChildIndex(newTree, getChildIndex(t)); // same index in new tree
|
||||
setParent(newTree, parent);
|
||||
int n = getChildCount(t);
|
||||
for (int i = 0; i < n; i++) {
|
||||
T child = getChild(t, i);
|
||||
T newSubTree = dupTree(child, t);
|
||||
addChild(newTree, newSubTree);
|
||||
}
|
||||
return newTree;
|
||||
}
|
||||
|
||||
/** Add a child to the tree t. If child is a flat tree (a list), make all
|
||||
* in list children of t. Warning: if t has no children, but child does
|
||||
* and child isNil then you can decide it is ok to move children to t via
|
||||
* t.children = child.children; i.e., without copying the array. Just
|
||||
* make sure that this is consistent with have the user will build
|
||||
* ASTs.
|
||||
*/
|
||||
@Override
|
||||
public void addChild(T t, T child) {
|
||||
if ( t!=null && child!=null ) {
|
||||
t.addChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
/** If oldRoot is a nil root, just copy or move the children to newRoot.
|
||||
* If not a nil root, make oldRoot a child of newRoot.
|
||||
*
|
||||
* old=^(nil a b c), new=r yields ^(r a b c)
|
||||
* old=^(a b c), new=r yields ^(r ^(a b c))
|
||||
*
|
||||
* If newRoot is a nil-rooted single child tree, use the single
|
||||
* child as the new root node.
|
||||
*
|
||||
* old=^(nil a b c), new=^(nil r) yields ^(r a b c)
|
||||
* old=^(a b c), new=^(nil r) yields ^(r ^(a b c))
|
||||
*
|
||||
* If oldRoot was null, it's ok, just return newRoot (even if isNil).
|
||||
*
|
||||
* old=null, new=r yields r
|
||||
* old=null, new=^(nil r) yields ^(nil r)
|
||||
*
|
||||
* Return newRoot. Throw an exception if newRoot is not a
|
||||
* simple node or nil root with a single child node--it must be a root
|
||||
* node. If newRoot is ^(nil x) return x as newRoot.
|
||||
*
|
||||
* Be advised that it's ok for newRoot to point at oldRoot's
|
||||
* children; i.e., you don't have to copy the list. We are
|
||||
* constructing these nodes so we should have this control for
|
||||
* efficiency.
|
||||
*/
|
||||
@Override
|
||||
public T becomeRoot(T newRoot, T oldRoot) {
|
||||
//System.out.println("becomeroot new "+newRoot.toString()+" old "+oldRoot);
|
||||
if ( oldRoot==null ) {
|
||||
return newRoot;
|
||||
}
|
||||
if ( newRoot==null ) {
|
||||
return oldRoot;
|
||||
}
|
||||
// handle ^(nil real-node)
|
||||
if ( newRoot.isNil() ) {
|
||||
int nc = newRoot.getChildCount();
|
||||
if ( nc==1 ) newRoot = (T)newRoot.getChild(0);
|
||||
else if ( nc >1 ) {
|
||||
// TODO: make tree run time exceptions hierarchy
|
||||
throw new RuntimeException("more than one node as root (TODO: make exception hierarchy)");
|
||||
}
|
||||
}
|
||||
// add oldRoot to newRoot; addChild takes care of case where oldRoot
|
||||
// is a flat list (i.e., nil-rooted tree). All children of oldRoot
|
||||
// are added to newRoot.
|
||||
newRoot.addChild(oldRoot);
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
/** Transform ^(nil x) to x and nil to null */
|
||||
@Override
|
||||
public T rulePostProcessing(T root) {
|
||||
//System.out.println("rulePostProcessing: "+((AST)root).toStringTree());
|
||||
if ( root!=null && root.isNil() ) {
|
||||
if ( root.getChildCount()==0 ) {
|
||||
root = null;
|
||||
}
|
||||
else if ( root.getChildCount()==1 ) {
|
||||
root = (T)root.getChild(0);
|
||||
// whoever invokes rule will set parent and child index
|
||||
root.setParent(null);
|
||||
root.setChildIndex(-1);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T becomeRoot(Token newRoot, T oldRoot) {
|
||||
return becomeRoot(create(newRoot), oldRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T create(int tokenType, Token fromToken) {
|
||||
WritableToken tok = createToken(fromToken);
|
||||
//((ClassicToken)fromToken).setType(tokenType);
|
||||
tok.setType(tokenType);
|
||||
return create(tok);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T create(int tokenType, Token fromToken, String text) {
|
||||
if (fromToken == null) return create(tokenType, text);
|
||||
WritableToken tok = createToken(fromToken);
|
||||
tok.setType(tokenType);
|
||||
tok.setText(text);
|
||||
return create(tok);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T create(int tokenType, String text) {
|
||||
Token fromToken = createToken(tokenType, text);
|
||||
return create(fromToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType(T t) {
|
||||
return t.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(T t, int type) {
|
||||
throw new UnsupportedOperationException("don't know enough about AST node");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(T t) {
|
||||
return t.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(T t, String text) {
|
||||
throw new UnsupportedOperationException("don't know enough about AST node");
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getChild(T t, int i) {
|
||||
return (T)t.getChild(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChild(T t, int i, T child) {
|
||||
t.setChild(i, child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T deleteChild(T t, int i) {
|
||||
return (T)t.deleteChild(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(T t) {
|
||||
return t.getChildCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUniqueID(T node) {
|
||||
if ( treeToUniqueIDMap==null ) {
|
||||
treeToUniqueIDMap = new HashMap<BaseAST, Integer>();
|
||||
}
|
||||
Integer prevID = treeToUniqueIDMap.get(node);
|
||||
if ( prevID!=null ) {
|
||||
return prevID;
|
||||
}
|
||||
int ID = uniqueNodeID;
|
||||
treeToUniqueIDMap.put(node, ID);
|
||||
uniqueNodeID++;
|
||||
return ID;
|
||||
// GC makes these nonunique:
|
||||
// return System.identityHashCode(node);
|
||||
}
|
||||
|
||||
/** Tell me how to create a token for use with imaginary token nodes.
|
||||
* For example, there is probably no input symbol associated with imaginary
|
||||
* token DECL, but you need to create it as a payload or whatever for
|
||||
* the DECL node as in ^(DECL type ID).
|
||||
*
|
||||
* If you care what the token payload objects' type is, you should
|
||||
* override this method and any other createToken variant.
|
||||
*/
|
||||
public abstract WritableToken createToken(int tokenType, String text);
|
||||
|
||||
/** Tell me how to create a token for use with imaginary token nodes.
|
||||
* For example, there is probably no input symbol associated with imaginary
|
||||
* token DECL, but you need to create it as a payload or whatever for
|
||||
* the DECL node as in ^(DECL type ID).
|
||||
*
|
||||
* This is a variant of createToken where the new token is derived from
|
||||
* an actual real input token. Typically this is for converting '{'
|
||||
* tokens to BLOCK etc... You'll see
|
||||
*
|
||||
* r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
|
||||
*
|
||||
* If you care what the token payload objects' type is, you should
|
||||
* override this method and any other createToken variant.
|
||||
*/
|
||||
public abstract WritableToken createToken(Token fromToken);
|
||||
}
|
||||
|
|
@ -1,524 +0,0 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2005-2009 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;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** A buffered stream of tree nodes. Nodes can be from a tree of ANY kind.
|
||||
*
|
||||
* This node stream sucks all nodes out of the tree specified in
|
||||
* the constructor during construction and makes pointers into
|
||||
* the tree using an array of Object pointers. The stream necessarily
|
||||
* includes pointers to DOWN and UP and EOF nodes.
|
||||
*
|
||||
* This stream knows how to mark/release for backtracking.
|
||||
*
|
||||
* This stream is most suitable for tree interpreters that need to
|
||||
* jump around a lot or for tree parsers requiring speed (at cost of memory).
|
||||
* There is some duplicated functionality here with UnBufferedASTNodeStream
|
||||
* but just in bookkeeping, not tree walking etc...
|
||||
*
|
||||
* TARGET DEVELOPERS:
|
||||
*
|
||||
* This is the old CommonASTNodeStream that buffered up entire node stream.
|
||||
* No need to implement really as new CommonASTNodeStream is much better
|
||||
* and covers what we need.
|
||||
*
|
||||
* @see CommonASTNodeStream
|
||||
*/
|
||||
public class BufferedASTNodeStream<T> implements ASTNodeStream<T> {
|
||||
public static final int DEFAULT_INITIAL_BUFFER_SIZE = 100;
|
||||
public static final int INITIAL_CALL_STACK_SIZE = 10;
|
||||
|
||||
protected class StreamIterator implements Iterator<T> {
|
||||
int i = 0;
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return i<nodes.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
int current = i;
|
||||
i++;
|
||||
if ( current < nodes.size() ) {
|
||||
return nodes.get(current);
|
||||
}
|
||||
return eof;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new RuntimeException("cannot remove nodes from stream");
|
||||
}
|
||||
}
|
||||
|
||||
// all these navigation nodes are shared and hence they
|
||||
// cannot contain any line/column info
|
||||
|
||||
protected T down;
|
||||
protected T up;
|
||||
protected T eof;
|
||||
|
||||
/** The complete mapping from stream index to tree node.
|
||||
* This buffer includes pointers to DOWN, UP, and EOF nodes.
|
||||
* It is built upon ctor invocation. The elements are type
|
||||
* Object as we don't what the trees look like.
|
||||
*
|
||||
* Load upon first need of the buffer so we can set token types
|
||||
* of interest for reverseIndexing. Slows us down a wee bit to
|
||||
* do all of the if p==-1 testing everywhere though.
|
||||
*/
|
||||
protected List<T> nodes;
|
||||
|
||||
/** Pull nodes from which tree? */
|
||||
protected T root;
|
||||
|
||||
/** IF this tree (root) was created from a token stream, track it. */
|
||||
protected TokenStream tokens;
|
||||
|
||||
/** What tree adaptor was used to build these trees */
|
||||
ASTAdaptor<T> adaptor;
|
||||
|
||||
/** Reuse same DOWN, UP navigation nodes unless this is true */
|
||||
protected boolean uniqueNavigationNodes = false;
|
||||
|
||||
/** The index into the nodes list of the current node (next node
|
||||
* to consume). If -1, nodes array not filled yet.
|
||||
*/
|
||||
protected int p = -1;
|
||||
|
||||
/** Track the last mark() call result value for use in rewind(). */
|
||||
protected int lastMarker;
|
||||
|
||||
/** Stack of indexes used for push/pop calls */
|
||||
protected List<Integer> calls;
|
||||
|
||||
public BufferedASTNodeStream(T tree) {
|
||||
this((ASTAdaptor<T>)new CommonASTAdaptor(), tree);
|
||||
}
|
||||
|
||||
public BufferedASTNodeStream(ASTAdaptor<T> adaptor, T tree) {
|
||||
this(adaptor, tree, DEFAULT_INITIAL_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public BufferedASTNodeStream(ASTAdaptor<T> adaptor, T tree, int initialBufferSize) {
|
||||
this.root = tree;
|
||||
this.adaptor = adaptor;
|
||||
nodes = new ArrayList<T>(initialBufferSize);
|
||||
down = adaptor.create(Token.DOWN, "DOWN");
|
||||
up = adaptor.create(Token.UP, "UP");
|
||||
eof = adaptor.create(Token.EOF, "EOF");
|
||||
}
|
||||
|
||||
/** Walk tree with depth-first-search and fill nodes buffer.
|
||||
* Don't do DOWN, UP nodes if its a list (t is isNil).
|
||||
*/
|
||||
protected void fillBuffer() {
|
||||
fillBuffer(root);
|
||||
//System.out.println("revIndex="+tokenTypeToStreamIndexesMap);
|
||||
p = 0; // buffer of nodes intialized now
|
||||
}
|
||||
|
||||
public void fillBuffer(T t) {
|
||||
boolean nil = adaptor.isNil(t);
|
||||
if ( !nil ) {
|
||||
nodes.add(t); // add this node
|
||||
}
|
||||
// add DOWN node if t has children
|
||||
int n = adaptor.getChildCount(t);
|
||||
if ( !nil && n>0 ) {
|
||||
addNavigationNode(Token.DOWN);
|
||||
}
|
||||
// and now add all its children
|
||||
for (int c=0; c<n; c++) {
|
||||
T child = adaptor.getChild(t,c);
|
||||
fillBuffer(child);
|
||||
}
|
||||
// add UP node if t has children
|
||||
if ( !nil && n>0 ) {
|
||||
addNavigationNode(Token.UP);
|
||||
}
|
||||
}
|
||||
|
||||
/** What is the stream index for node? 0..n-1
|
||||
* Return -1 if node not found.
|
||||
*/
|
||||
protected int getNodeIndex(T node) {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
T t = nodes.get(i);
|
||||
if ( t==node ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** As we flatten the tree, we use UP, DOWN nodes to represent
|
||||
* the tree structure. When debugging we need unique nodes
|
||||
* so instantiate new ones when uniqueNavigationNodes is true.
|
||||
*/
|
||||
protected void addNavigationNode(final int ttype) {
|
||||
T navNode = null;
|
||||
if ( ttype==Token.DOWN ) {
|
||||
if ( hasUniqueNavigationNodes() ) {
|
||||
navNode = adaptor.create(Token.DOWN, "DOWN");
|
||||
}
|
||||
else {
|
||||
navNode = down;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( hasUniqueNavigationNodes() ) {
|
||||
navNode = adaptor.create(Token.UP, "UP");
|
||||
}
|
||||
else {
|
||||
navNode = up;
|
||||
}
|
||||
}
|
||||
nodes.add(navNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int i) {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
return nodes.get(i);
|
||||
}
|
||||
|
||||
public List<T> get(int i, int j) {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
return nodes.subList(i,j+1);
|
||||
}
|
||||
|
||||
public List<T> get(T start, T stop) {
|
||||
int i=0;
|
||||
for (; i<nodes.size(); i++) {
|
||||
T t = nodes.get(i);
|
||||
if ( t==start ) break;
|
||||
}
|
||||
int j=i;
|
||||
for (; j<nodes.size(); j++) {
|
||||
T t = nodes.get(j);
|
||||
if ( t==stop ) break;
|
||||
}
|
||||
if ( i>=nodes.size() ) return null;
|
||||
if ( j>=nodes.size() ) j = nodes.size()-1;
|
||||
return get(i,j);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T LT(int k) {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
if ( k==0 ) {
|
||||
return null;
|
||||
}
|
||||
if ( k<0 ) {
|
||||
return LB(-k);
|
||||
}
|
||||
//System.out.print("LT(p="+p+","+k+")=");
|
||||
if ( (p+k-1) >= nodes.size() ) {
|
||||
return eof;
|
||||
}
|
||||
return nodes.get(p+k-1);
|
||||
}
|
||||
|
||||
public T getCurrentSymbol() { return LT(1); }
|
||||
|
||||
/*
|
||||
public T getLastTreeNode() {
|
||||
int i = index();
|
||||
if ( i>=size() ) {
|
||||
i--; // if at EOF, have to start one back
|
||||
}
|
||||
System.out.println("start last node: "+i+" size=="+nodes.size());
|
||||
while ( i>=0 &&
|
||||
(adaptor.getType(get(i))==Token.EOF ||
|
||||
adaptor.getType(get(i))==Token.UP ||
|
||||
adaptor.getType(get(i))==Token.DOWN) )
|
||||
{
|
||||
i--;
|
||||
}
|
||||
System.out.println("stop at node: "+i+" "+nodes.get(i));
|
||||
return nodes.get(i);
|
||||
}
|
||||
*/
|
||||
|
||||
/** Look backwards k nodes */
|
||||
protected T LB(int k) {
|
||||
if ( k==0 ) {
|
||||
return null;
|
||||
}
|
||||
if ( (p-k)<0 ) {
|
||||
return null;
|
||||
}
|
||||
return nodes.get(p-k);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getTreeSource() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSourceName() {
|
||||
return getTokenStream().getSourceName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTAdaptor<T> getTreeAdaptor() {
|
||||
return adaptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenStream getTokenStream() {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
public void setTokenStream(TokenStream tokens) {
|
||||
this.tokens = tokens;
|
||||
}
|
||||
|
||||
public ASTAdaptor<T> getASTAdaptor() {
|
||||
return adaptor;
|
||||
}
|
||||
|
||||
public void setASTAdaptor(ASTAdaptor<T> adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
|
||||
public boolean hasUniqueNavigationNodes() {
|
||||
return uniqueNavigationNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUniqueNavigationNodes(boolean uniqueNavigationNodes) {
|
||||
this.uniqueNavigationNodes = uniqueNavigationNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void consume() {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int LA(int i) {
|
||||
return adaptor.getType(LT(i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int mark() {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
lastMarker = index();
|
||||
return lastMarker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(int marker) {
|
||||
// no resources to release
|
||||
}
|
||||
|
||||
@Override
|
||||
public int index() {
|
||||
return p;
|
||||
}
|
||||
|
||||
public void rewind(int marker) {
|
||||
seek(marker);
|
||||
}
|
||||
|
||||
public void rewind() {
|
||||
seek(lastMarker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seek(int index) {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
p = index;
|
||||
}
|
||||
|
||||
/** Make stream jump to a new location, saving old location.
|
||||
* Switch back with pop().
|
||||
*/
|
||||
public void push(int index) {
|
||||
if ( calls==null ) {
|
||||
calls = new ArrayList<Integer>();
|
||||
}
|
||||
calls.add(p); // save current index
|
||||
seek(index);
|
||||
}
|
||||
|
||||
/** Seek back to previous index saved during last push() call.
|
||||
* Return top of stack (return index).
|
||||
*/
|
||||
public int pop() {
|
||||
int ret = calls.remove(calls.size() - 1);
|
||||
seek(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
p = 0;
|
||||
lastMarker = 0;
|
||||
if (calls != null) {
|
||||
calls.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
return nodes.size();
|
||||
}
|
||||
|
||||
public Iterator<T> iterator() {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
return new StreamIterator();
|
||||
}
|
||||
|
||||
// TREE REWRITE INTERFACE
|
||||
|
||||
@Override
|
||||
public void replaceChildren(T parent, int startChildIndex, int stopChildIndex, T t) {
|
||||
if ( parent!=null ) {
|
||||
adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t);
|
||||
}
|
||||
}
|
||||
|
||||
/** Used for testing, just return the token type stream */
|
||||
public String toTokenTypeString() {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
T t = nodes.get(i);
|
||||
buf.append(" ");
|
||||
buf.append(adaptor.getType(t));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** Debugging */
|
||||
public String toTokenString(int start, int stop) {
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = start; i < nodes.size() && i <= stop; i++) {
|
||||
T t = nodes.get(i);
|
||||
buf.append(" ");
|
||||
buf.append(adaptor.getToken(t));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(T start, T stop) {
|
||||
System.out.println("toString");
|
||||
if ( start==null || stop==null ) {
|
||||
return null;
|
||||
}
|
||||
if ( p==-1 ) {
|
||||
fillBuffer();
|
||||
}
|
||||
//System.out.println("stop: "+stop);
|
||||
if ( start instanceof CommonAST )
|
||||
System.out.print("toString: "+((CommonAST)start).getToken()+", ");
|
||||
else
|
||||
System.out.println(start);
|
||||
if ( stop instanceof CommonAST )
|
||||
System.out.println(((CommonAST)stop).getToken());
|
||||
else
|
||||
System.out.println(stop);
|
||||
// if we have the token stream, use that to dump text in order
|
||||
if ( tokens!=null ) {
|
||||
int beginTokenIndex = adaptor.getTokenStartIndex(start);
|
||||
int endTokenIndex = adaptor.getTokenStopIndex(stop);
|
||||
// if it's a tree, use start/stop index from start node
|
||||
// else use token range from start/stop nodes
|
||||
if ( adaptor.getType(stop)==Token.UP ) {
|
||||
endTokenIndex = adaptor.getTokenStopIndex(start);
|
||||
}
|
||||
else if ( adaptor.getType(stop)==Token.EOF ) {
|
||||
endTokenIndex = size()-2; // don't use EOF
|
||||
}
|
||||
return tokens.toString(beginTokenIndex, endTokenIndex);
|
||||
}
|
||||
// walk nodes looking for start
|
||||
T t = null;
|
||||
int i = 0;
|
||||
for (; i < nodes.size(); i++) {
|
||||
t = nodes.get(i);
|
||||
if ( t==start ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// now walk until we see stop, filling string buffer with text
|
||||
StringBuffer buf = new StringBuffer();
|
||||
t = nodes.get(i);
|
||||
while ( t!=stop ) {
|
||||
String text = adaptor.getText(t);
|
||||
if ( text==null ) {
|
||||
text = " "+String.valueOf(adaptor.getType(t));
|
||||
}
|
||||
buf.append(text);
|
||||
i++;
|
||||
t = nodes.get(i);
|
||||
}
|
||||
// include stop node too
|
||||
String text = adaptor.getText(stop);
|
||||
if ( text==null ) {
|
||||
text = " "+String.valueOf(adaptor.getType(stop));
|
||||
}
|
||||
buf.append(text);
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.misc.Interval;
|
||||
|
||||
/** A tree node that is wrapper for a Token object. */
|
||||
public class CommonAST extends BaseAST {
|
||||
/** A single token is the payload */
|
||||
public Token token;
|
||||
|
||||
/** What token indexes bracket all tokens associated with this node
|
||||
* and below?
|
||||
*/
|
||||
protected int startIndex=-1, stopIndex=-1;
|
||||
|
||||
public CommonAST() { }
|
||||
|
||||
public CommonAST(CommonAST node) {
|
||||
super(node);
|
||||
this.token = node.token;
|
||||
this.startIndex = node.startIndex;
|
||||
this.stopIndex = node.stopIndex;
|
||||
}
|
||||
|
||||
public CommonAST(Token t) {
|
||||
this.token = t;
|
||||
}
|
||||
|
||||
public Token getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token getPayload() {
|
||||
return getToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interval getSourceInterval() {
|
||||
return new Interval(getTokenStartIndex(), getTokenStopIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNil() {
|
||||
return token==null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonAST getChild(int i) {
|
||||
return (CommonAST)super.getChild(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonAST getParent() {
|
||||
return (CommonAST)super.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType() {
|
||||
if ( token==null ) {
|
||||
return Token.INVALID_TYPE;
|
||||
}
|
||||
return token.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
if ( token==null ) {
|
||||
return null;
|
||||
}
|
||||
return token.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLine() {
|
||||
if ( token==null || token.getLine()==0 ) {
|
||||
if ( getChildCount()>0 ) {
|
||||
return getChild(0).getLine();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return token.getLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharPositionInLine() {
|
||||
if ( token==null || token.getCharPositionInLine()==-1 ) {
|
||||
if ( getChildCount()>0 ) {
|
||||
return getChild(0).getCharPositionInLine();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return token.getCharPositionInLine();
|
||||
}
|
||||
|
||||
public int getTokenStartIndex() {
|
||||
if ( startIndex==-1 && token!=null ) {
|
||||
return token.getTokenIndex();
|
||||
}
|
||||
return startIndex;
|
||||
}
|
||||
|
||||
public void setTokenStartIndex(int index) {
|
||||
startIndex = index;
|
||||
}
|
||||
|
||||
public int getTokenStopIndex() {
|
||||
if ( stopIndex==-1 && token!=null ) {
|
||||
return token.getTokenIndex();
|
||||
}
|
||||
return stopIndex;
|
||||
}
|
||||
|
||||
public void setTokenStopIndex(int index) {
|
||||
stopIndex = index;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if ( isNil() ) {
|
||||
return "nil";
|
||||
}
|
||||
if ( getType()==Token.INVALID_TYPE) {
|
||||
return "<errornode>";
|
||||
}
|
||||
if ( token==null ) {
|
||||
return null;
|
||||
}
|
||||
return token.getText();
|
||||
}
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
/** An ASTAdaptor that works with CommonAST. It provides
|
||||
* really just factory methods; all the work is done by BaseTreeAdaptor.
|
||||
* If you would like to have different tokens created than CommonToken
|
||||
* objects, you need to override this and then set the parser tree adaptor to
|
||||
* use your subclass.
|
||||
*
|
||||
* To get your parser to build nodes of a different type, override
|
||||
* create(Token).
|
||||
*/
|
||||
public class CommonASTAdaptor extends BaseASTAdaptor<CommonAST> {
|
||||
/** Duplicate a node. This is part of the factory;
|
||||
* override if you want another kind of node to be built.
|
||||
*
|
||||
* I could use reflection to prevent having to override this
|
||||
* but reflection is slow.
|
||||
*/
|
||||
@Override
|
||||
public CommonAST dupNode(CommonAST t) {
|
||||
if ( t==null ) return null;
|
||||
return new CommonAST(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonAST create(Token payload) {
|
||||
return new CommonAST(payload);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Tell me how to create a token for use with imaginary token nodes.
|
||||
* For example, there is probably no input symbol associated with imaginary
|
||||
* token DECL, but you need to create it as a payload or whatever for
|
||||
* the DECL node as in ^(DECL type ID).
|
||||
*
|
||||
* If you care what the token payload objects' type is, you should
|
||||
* override this method and any other createToken variant.
|
||||
*/
|
||||
@Override
|
||||
public WritableToken createToken(int tokenType, String text) {
|
||||
return new CommonToken(tokenType, text);
|
||||
}
|
||||
|
||||
/** Tell me how to create a token for use with imaginary token nodes.
|
||||
* For example, there is probably no input symbol associated with imaginary
|
||||
* token DECL, but you need to create it as a payload or whatever for
|
||||
* the DECL node as in ^(DECL type ID).
|
||||
*
|
||||
* This is a variant of createToken where the new token is derived from
|
||||
* an actual real input token. Typically this is for converting '{'
|
||||
* tokens to BLOCK etc... You'll see
|
||||
*
|
||||
* r : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
|
||||
*
|
||||
* If you care what the token payload objects' type is, you should
|
||||
* override this method and any other createToken variant.
|
||||
*/
|
||||
@Override
|
||||
public WritableToken createToken(Token fromToken) {
|
||||
return new CommonToken(fromToken);
|
||||
}
|
||||
|
||||
/** Track start/stop token for subtree root created for a rule.
|
||||
* Only works with CommonAST nodes. For rules that match nothing,
|
||||
* seems like this will yield start=i and stop=i-1 in a nil node.
|
||||
* Might be useful info so I'll not force to be i..i.
|
||||
*/
|
||||
@Override
|
||||
public void setTokenBoundaries(CommonAST t, Token startToken, Token stopToken) {
|
||||
if ( t==null ) return;
|
||||
int start = 0;
|
||||
int stop = 0;
|
||||
if ( startToken!=null ) start = startToken.getTokenIndex();
|
||||
if ( stopToken!=null ) stop = stopToken.getTokenIndex();
|
||||
t.setTokenStartIndex(start);
|
||||
t.setTokenStopIndex(stop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenStartIndex(CommonAST t) {
|
||||
if ( t==null ) return -1;
|
||||
return t.getTokenStartIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTokenStopIndex(CommonAST t) {
|
||||
if ( t==null ) return -1;
|
||||
return t.getTokenStopIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(CommonAST t) {
|
||||
if ( t==null ) return null;
|
||||
return t.getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getType(CommonAST t) {
|
||||
if ( t==null ) return Token.INVALID_TYPE;
|
||||
return t.getType();
|
||||
}
|
||||
|
||||
/** What is the Token associated with this node? If
|
||||
* you are not using CommonAST, then you must
|
||||
* override this in your own adaptor.
|
||||
*/
|
||||
@Override
|
||||
public Token getToken(CommonAST t) {
|
||||
if ( t==null ) return null;
|
||||
return t.getToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonAST getChild(CommonAST t, int i) {
|
||||
if ( t==null ) return null;
|
||||
return t.getChild(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildCount(CommonAST t) {
|
||||
if ( t==null ) return 0;
|
||||
return t.getChildCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonAST getParent(CommonAST t) {
|
||||
if ( t==null ) return null;
|
||||
return t.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(CommonAST t, CommonAST parent) {
|
||||
if ( t!=null ) t.setParent(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildIndex(CommonAST t) {
|
||||
if ( t==null ) return 0;
|
||||
return t.getChildIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChildIndex(CommonAST t, int index) {
|
||||
if ( t!=null ) t.setChildIndex(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceChildren(CommonAST parent, int startChildIndex, int stopChildIndex, CommonAST t) {
|
||||
if ( parent!=null ) {
|
||||
Trees.replaceChildren(parent, startChildIndex, stopChildIndex, t);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,195 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.misc.LookaheadStream;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
public class CommonASTNodeStream<T> extends LookaheadStream<T>
|
||||
implements ASTNodeStream<T>
|
||||
{
|
||||
public static final int DEFAULT_INITIAL_BUFFER_SIZE = 100;
|
||||
public static final int INITIAL_CALL_STACK_SIZE = 10;
|
||||
|
||||
/** Pull nodes from which tree? */
|
||||
protected T root;
|
||||
|
||||
/** If this tree (root) was created from a token stream, track it. */
|
||||
protected TokenStream tokens;
|
||||
|
||||
/** What tree adaptor was used to build these trees */
|
||||
ASTAdaptor<T> adaptor;
|
||||
|
||||
/** The tree iterator we using */
|
||||
protected ASTIterator<T> it;
|
||||
|
||||
/** Stack of indexes used for push/pop calls */
|
||||
protected Stack<Integer> calls;
|
||||
|
||||
/** Tree (nil A B C) trees like flat A B C streams */
|
||||
protected boolean hasNilRoot = false;
|
||||
|
||||
/** Tracks tree depth. Level=0 means we're at root node level. */
|
||||
protected int level = 0;
|
||||
|
||||
public CommonASTNodeStream(T tree) {
|
||||
this((tree instanceof CommonAST)?(ASTAdaptor<T>)new CommonASTAdaptor():null,
|
||||
tree);
|
||||
}
|
||||
|
||||
public CommonASTNodeStream(ASTAdaptor<T> adaptor, T tree) {
|
||||
this.root = tree;
|
||||
this.adaptor = adaptor;
|
||||
it = new ASTIterator<T>(adaptor,root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
it.reset();
|
||||
hasNilRoot = false;
|
||||
level = 0;
|
||||
if ( calls != null ) calls.clear();
|
||||
}
|
||||
|
||||
/** Pull elements from tree iterator. Track tree level 0..max_level.
|
||||
* If nil rooted tree, don't give initial nil and DOWN nor final UP.
|
||||
*/
|
||||
@Override
|
||||
public T nextElement() {
|
||||
T t = it.next();
|
||||
//System.out.println("pulled "+adaptor.getType(t));
|
||||
if ( t == it.up ) {
|
||||
level--;
|
||||
if ( level==0 && hasNilRoot ) return it.next(); // don't give last UP; get EOF
|
||||
}
|
||||
else if ( t == it.down ) level++;
|
||||
if ( level==0 && adaptor.isNil(t) ) { // if nil root, scarf nil, DOWN
|
||||
hasNilRoot = true;
|
||||
t = it.next(); // t is now DOWN, so get first real node next
|
||||
level++;
|
||||
t = it.next();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEOF(T o) { return adaptor.getType(o) == Token.EOF; }
|
||||
|
||||
@Override
|
||||
public void setUniqueNavigationNodes(boolean uniqueNavigationNodes) { }
|
||||
|
||||
@Override
|
||||
public T getTreeSource() { return root; }
|
||||
|
||||
@Override
|
||||
public String getSourceName() { return getTokenStream().getSourceName(); }
|
||||
|
||||
@Override
|
||||
public TokenStream getTokenStream() { return tokens; }
|
||||
|
||||
public void setTokenStream(TokenStream tokens) { this.tokens = tokens; }
|
||||
|
||||
@Override
|
||||
public ASTAdaptor<T> getTreeAdaptor() { return adaptor; }
|
||||
|
||||
public void setTreeAdaptor(ASTAdaptor<T> adaptor) { this.adaptor = adaptor; }
|
||||
|
||||
@Override
|
||||
public T get(int i) {
|
||||
throw new UnsupportedOperationException("Absolute node indexes are meaningless in an unbuffered stream");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int LA(int i) { return adaptor.getType(LT(i)); }
|
||||
|
||||
/** Make stream jump to a new location, saving old location.
|
||||
* Switch back with pop().
|
||||
*/
|
||||
public void push(int index) {
|
||||
if ( calls==null ) {
|
||||
calls = new Stack<Integer>();
|
||||
}
|
||||
calls.push(p); // save current index
|
||||
seek(index);
|
||||
}
|
||||
|
||||
/** Seek back to previous index saved during last push() call.
|
||||
* Return top of stack (return index).
|
||||
*/
|
||||
public int pop() {
|
||||
int ret = calls.pop();
|
||||
seek(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TREE REWRITE INTERFACE
|
||||
|
||||
@Override
|
||||
public void replaceChildren(T parent, int startChildIndex, int stopChildIndex, T t) {
|
||||
if ( parent!=null ) {
|
||||
adaptor.replaceChildren(parent, startChildIndex, stopChildIndex, t);
|
||||
}
|
||||
}
|
||||
|
||||
/** Print the token text between start and stop nodes. If stop is an UP
|
||||
* node, then we have to walk it back until we see the first non-UP node.
|
||||
* Then, just get the token indexes and look into the token stream.
|
||||
*/
|
||||
@Override
|
||||
public String toString(T start, T stop) {
|
||||
if ( tokens==null ) throw new UnsupportedOperationException("can't print from null token stream in node stream");
|
||||
if ( start==null || stop==null ) return "";
|
||||
Token startToken = adaptor.getToken(start);
|
||||
Token stopToken = adaptor.getToken(stop);
|
||||
while ( stopToken.getType()==Token.UP ) {
|
||||
stopToken = adaptor.getToken(stop);
|
||||
}
|
||||
return tokens.toString(startToken.getTokenIndex(), stopToken.getTokenIndex());
|
||||
}
|
||||
|
||||
/** For debugging; destructive: moves tree iterator to end. */
|
||||
public String toTokenTypeString() {
|
||||
reset();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
T o = LT(1);
|
||||
int type = adaptor.getType(o);
|
||||
while ( type!=Token.EOF ) {
|
||||
buf.append(" ");
|
||||
buf.append(type);
|
||||
consume();
|
||||
o = LT(1);
|
||||
type = adaptor.getType(o);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** This list tracks elements to left of -> for use on right of -> */
|
||||
public class ElementList<E> extends ArrayList<E> {
|
||||
protected ASTAdaptor<E> adaptor;
|
||||
|
||||
/** Once a node / subtree has been used in a stream, it must be dup'd
|
||||
* from then on.
|
||||
*/
|
||||
protected HashSet<Integer> used = new HashSet<Integer>();
|
||||
|
||||
public class ElementListIterator implements Iterator<E> {
|
||||
int cursor = 0;
|
||||
|
||||
/** If just 1 element, we still track cursor; next() will dup if
|
||||
* cursor beyond 1 element.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
int n = size();
|
||||
return (n==1 && cursor<1) || (n>1 && cursor<n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
int n = size();
|
||||
if ( n == 0 ) throw new RewriteEmptyStreamException("n/a");
|
||||
if ( cursor >= n) { // out of elements?
|
||||
if ( n == 1 ) { // if size is 1, it's ok; return and we'll dup
|
||||
return adaptor.dupTree( get(0) );
|
||||
}
|
||||
// out of elements and size was not 1, so we can't dup
|
||||
throw new RewriteCardinalityException("size=="+n+" and out of elements");
|
||||
}
|
||||
|
||||
// we have elements
|
||||
if ( n == 1 ) {
|
||||
cursor++; // move cursor even for single element list
|
||||
return adaptor.dupTree( get(0) );
|
||||
}
|
||||
// must have more than one in list, pull from elements
|
||||
E e = get(cursor);
|
||||
cursor++;
|
||||
return e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() { throw new UnsupportedOperationException(); }
|
||||
}
|
||||
|
||||
public ElementList(ASTAdaptor<E> adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
E o = super.get(index);
|
||||
if ( used.contains(index) ) {
|
||||
return adaptor.dupTree( o );
|
||||
}
|
||||
used.add(index); // any subsequent ref must be dup'd
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new ElementListIterator();
|
||||
}
|
||||
}
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
package org.antlr.v4.runtime.tree;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.RuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.misc.Interval;
|
||||
|
||||
/** An interface to access the tree of RuleContext objects created
|
||||
|
@ -37,8 +38,7 @@ import org.antlr.v4.runtime.misc.Interval;
|
|||
* This node represents both internal nodes, rule invocations,
|
||||
* and leaf nodes, token matches.
|
||||
*
|
||||
* Unlike the common AST stuff in the runtime library, there is no such thing
|
||||
* as a nil node. The payload is either a token or a context object.
|
||||
* The payload is either a token or a context object.
|
||||
*/
|
||||
public interface ParseTree extends SyntaxTree {
|
||||
public interface RuleNode extends ParseTree {
|
||||
|
@ -89,13 +89,8 @@ public interface ParseTree extends SyntaxTree {
|
|||
if (symbol instanceof Token) {
|
||||
if ( ((Token)symbol).getType() == Token.EOF ) return "<EOF>";
|
||||
return ((Token)symbol).getText();
|
||||
} else if (symbol instanceof AST) {
|
||||
if (((AST)symbol).getType() == Token.EOF) {
|
||||
return "<EOF>";
|
||||
} else {
|
||||
return ((AST)symbol).getText();
|
||||
}
|
||||
} else {
|
||||
else {
|
||||
throw new UnsupportedOperationException("This symbol type is not supported by the default implementation.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
/** Base class for all exceptions thrown during AST rewrite construction.
|
||||
* This signifies a case where the cardinality of two or more elements
|
||||
* in a subrule are different: (ID INT)* where |ID|!=|INT|
|
||||
*/
|
||||
public class RewriteCardinalityException extends RuntimeException {
|
||||
public String elementDescription;
|
||||
|
||||
public RewriteCardinalityException(String elementDescription) {
|
||||
this.elementDescription = elementDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
if ( elementDescription!=null ) {
|
||||
return elementDescription;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
/** Ref to ID or expr but no tokens in ID stream or subtrees in expr stream */
|
||||
public class RewriteEmptyStreamException extends RewriteCardinalityException {
|
||||
public RewriteEmptyStreamException(String elementDescription) {
|
||||
super(elementDescription);
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ import org.antlr.v4.runtime.misc.Interval;
|
|||
|
||||
/** A tree that knows about an interval in a token stream
|
||||
* is some kind of syntax tree. Subinterfaces distinguish
|
||||
* between parse trees and ASTs.
|
||||
* between parse trees and other kinds of syntax trees we might want to create.
|
||||
*/
|
||||
public interface SyntaxTree extends Tree {
|
||||
/** Return an interval indicating the index in the TokenStream of
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
/**
|
||||
Cut-n-paste from material I'm not using in the book anymore (edit later
|
||||
to make sense):
|
||||
|
||||
Now, how are we going to test these tree patterns against every
|
||||
subtree in our original tree? In what order should we visit nodes?
|
||||
For this application, it turns out we need a simple ``apply once''
|
||||
rule application strategy and a ``down then up'' tree traversal
|
||||
strategy. Let's look at rule application first.
|
||||
|
||||
As we visit each node, we need to see if any of our patterns match. If
|
||||
a pattern matches, we execute the associated tree rewrite and move on
|
||||
to the next node. In other words, we only look for a single rule
|
||||
application opportunity (we'll see below that we sometimes need to
|
||||
repeatedly apply rules). The following method applies a rule in a @cl
|
||||
TreeParser (derived from a tree grammar) to a tree:
|
||||
|
||||
here is where weReferenced code/walking/patterns/TreePatternMatcher.java
|
||||
|
||||
It uses reflection to lookup the appropriate rule within the generated
|
||||
tree parser class (@cl Simplify in this case). Most of the time, the
|
||||
rule will not match the tree. To avoid issuing syntax errors and
|
||||
attempting error recovery, it bumps up the backtracking level. Upon
|
||||
failure, the invoked rule immediately returns. If you don't plan on
|
||||
using this technique in your own ANTLR-based application, don't sweat
|
||||
the details. This method boils down to ``call a rule to match a tree,
|
||||
executing any embedded actions and rewrite rules.''
|
||||
|
||||
At this point, we know how to define tree grammar rules and how to
|
||||
apply them to a particular subtree. The final piece of the tree
|
||||
pattern matcher is the actual tree traversal. We have to get the
|
||||
correct node visitation order. In particular, we need to perform the
|
||||
scalar-vector multiply transformation on the way down (preorder) and
|
||||
we need to reduce multiply-by-zero subtrees on the way up (postorder).
|
||||
|
||||
To implement a top-down visitor, we do a depth first walk of the tree,
|
||||
executing an action in the preorder position. To get a bottom-up
|
||||
visitor, we execute an action in the postorder position. ANTLR
|
||||
provides a standard @cl TreeVisitor class with a depth first search @v
|
||||
visit method. That method executes either a @m pre or @m post method
|
||||
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<T> {
|
||||
public interface fptr {
|
||||
public void rule() throws RecognitionException;
|
||||
}
|
||||
|
||||
protected TokenStream originalTokenStream;
|
||||
protected ASTAdaptor<T> originalAdaptor;
|
||||
|
||||
public TreeFilter(ASTNodeStream<T> input) {
|
||||
super(input);
|
||||
originalAdaptor = input.getTreeAdaptor();
|
||||
originalTokenStream = input.getTokenStream();
|
||||
}
|
||||
|
||||
public void applyOnce(T t, fptr whichRule) {
|
||||
if ( t==null ) return;
|
||||
try {
|
||||
// share TreeParser object but not parsing-related state
|
||||
_input = new CommonASTNodeStream<T>(originalAdaptor, t);
|
||||
((CommonASTNodeStream<T>) _input).setTokenStream(originalTokenStream);
|
||||
whichRule.rule();
|
||||
}
|
||||
catch (RecognitionException e) { }
|
||||
}
|
||||
|
||||
public void downup(T 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
|
||||
public T post(T t) { applyOnce(t, bottomup_fptr); return t; }
|
||||
};
|
||||
v.visit(t, actions);
|
||||
}
|
||||
|
||||
fptr topdown_fptr = new fptr() {
|
||||
@Override
|
||||
public void rule() throws RecognitionException {
|
||||
topdown();
|
||||
}
|
||||
};
|
||||
|
||||
fptr bottomup_fptr = new fptr() {
|
||||
@Override
|
||||
public void rule() throws RecognitionException {
|
||||
bottomup();
|
||||
}
|
||||
};
|
||||
|
||||
// methods the downup strategy uses to do the up and down rules.
|
||||
// to override, just define tree grammar rule topdown and turn on
|
||||
// filter=true.
|
||||
public void topdown() throws RecognitionException {}
|
||||
public void bottomup() throws RecognitionException {}
|
||||
}
|
|
@ -1,256 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
import java.util.regex.*;
|
||||
|
||||
/** A parser for a stream of tree nodes. "tree grammars" result in a subclass
|
||||
* of this. All the error reporting and recovery is shared with Parser via
|
||||
* the BaseRecognizer superclass.
|
||||
*/
|
||||
public class TreeParser<T> extends BaseRecognizer<T> {
|
||||
public static final int DOWN = Token.DOWN;
|
||||
public static final int UP = Token.UP;
|
||||
|
||||
public ASTAdaptor<T> _adaptor = (ASTAdaptor<T>)new CommonASTAdaptor();
|
||||
|
||||
// precompiled regex used by inContext
|
||||
static String dotdot = ".*[^.]\\.\\.[^.].*";
|
||||
static String doubleEtc = ".*\\.\\.\\.\\s+\\.\\.\\..*";
|
||||
static Pattern dotdotPattern = Pattern.compile(dotdot);
|
||||
static Pattern doubleEtcPattern = Pattern.compile(doubleEtc);
|
||||
|
||||
protected ASTNodeStream<T> _input;
|
||||
|
||||
public TreeParser(ASTNodeStream<T> input) {
|
||||
super(input);
|
||||
_errHandler = new DefaultTreeGrammarErrorStrategy<T>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset(); // reset all recognizer state variables
|
||||
if ( _input !=null ) {
|
||||
_input.seek(0); // rewind the input
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getCurrentInputSymbol() { return _input.LT(1); }
|
||||
|
||||
@Override
|
||||
public ASTNodeStream<T> getInputStream() { return _input; }
|
||||
|
||||
@Override
|
||||
public void setInputStream(IntStream input) { _input = (ASTNodeStream<T>)input; }
|
||||
|
||||
/** Always called by generated parsers upon entry to a rule.
|
||||
* This occurs after the new context has been pushed. Access field
|
||||
* _ctx get the current context.
|
||||
*
|
||||
* 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<T> localctx, int ruleIndex) {
|
||||
_ctx = localctx;
|
||||
_ctx.start = _input.LT(1);
|
||||
_ctx.ruleIndex = ruleIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSourceName() {
|
||||
return _input.getSourceName();
|
||||
}
|
||||
|
||||
// protected T getCurrentInputSymbol(IntStream input) {
|
||||
// return ((ASTNodeStream)input).LT(1);
|
||||
// }
|
||||
|
||||
protected T getMissingSymbol(IntStream input,
|
||||
RecognitionException e,
|
||||
int expectedTokenType)
|
||||
{
|
||||
String tokenText =
|
||||
"<missing "+getTokenNames()[expectedTokenType]+">";
|
||||
ASTAdaptor<T> adaptor = ((ASTNodeStream<T>)e.getInputStream()).getTreeAdaptor();
|
||||
return adaptor.create(new CommonToken(expectedTokenType, tokenText));
|
||||
}
|
||||
|
||||
/** Match '.' in tree parser has special meaning. Skip node or
|
||||
* entire tree if node has children. If children, scan until
|
||||
* corresponding UP node.
|
||||
*/
|
||||
public void matchAny(IntStream ignore) { // ignore stream, copy of input
|
||||
_errHandler.endErrorCondition(this);
|
||||
T look = _input.LT(1);
|
||||
if ( _input.getTreeAdaptor().getChildCount(look)==0 ) {
|
||||
_input.consume(); // not subtree, consume 1 node and return
|
||||
return;
|
||||
}
|
||||
// current node is a subtree, skip to corresponding UP.
|
||||
// must count nesting level to get right UP
|
||||
int level=0;
|
||||
int tokenType = _input.getTreeAdaptor().getType(look);
|
||||
while ( tokenType!=Token.EOF && !(tokenType==UP && level==0) ) {
|
||||
_input.consume();
|
||||
look = _input.LT(1);
|
||||
tokenType = _input.getTreeAdaptor().getType(look);
|
||||
if ( tokenType == DOWN ) {
|
||||
level++;
|
||||
}
|
||||
else if ( tokenType == UP ) {
|
||||
level--;
|
||||
}
|
||||
}
|
||||
_input.consume(); // consume UP
|
||||
}
|
||||
|
||||
/** We have DOWN/UP nodes in the stream that have no line info; override.
|
||||
* plus we want to alter the exception type. Don't try to recover
|
||||
* from tree parser errors inline...
|
||||
*/
|
||||
protected T recoverFromMismatchedToken(IntStream input,
|
||||
int ttype)
|
||||
throws RecognitionException
|
||||
{
|
||||
//throw new MismatchedTreeNodeException(ttype, (TreeNodeStream)input);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Prefix error message with the grammar name because message is
|
||||
* always intended for the programmer because the parser built
|
||||
* the input tree not the user.
|
||||
public String getErrorHeader(RecognitionException e) {
|
||||
// todo: might not have token; use node?
|
||||
int line = e.offendingToken.getLine();
|
||||
int charPositionInLine = e.offendingToken.getCharPositionInLine();
|
||||
return getGrammarFileName()+": node from "+
|
||||
(e.approximateLineInfo?"after ":"")+"line "+line+":"+charPositionInLine;
|
||||
}
|
||||
*/
|
||||
|
||||
/** Tree parsers parse nodes they usually have a token object as
|
||||
* payload. Set the exception token and do the default behavior.
|
||||
public String getErrorMessage(RecognitionException e, String[] tokenNames) {
|
||||
if ( this instanceof TreeParser ) {
|
||||
ASTAdaptor adaptor = ((ASTNodeStream)e.input).getTreeAdaptor();
|
||||
e.offendingToken = adaptor.getToken(e.offendingNode);
|
||||
if ( e.offendingToken ==null ) { // could be an UP/DOWN node
|
||||
e.offendingToken = new CommonToken(adaptor.getType(e.offendingNode),
|
||||
adaptor.getText(e.offendingNode));
|
||||
}
|
||||
}
|
||||
return super.getErrorMessage(e);
|
||||
}
|
||||
*/
|
||||
|
||||
/** Check if current node in input has a context. Context means sequence
|
||||
* of nodes towards root of tree. For example, you might say context
|
||||
* is "MULT" which means my parent must be MULT. "CLASS VARDEF" says
|
||||
* current node must be child of a VARDEF and whose parent is a CLASS node.
|
||||
* You can use "..." to mean zero-or-more nodes. "METHOD ... VARDEF"
|
||||
* means my parent is VARDEF and somewhere above that is a METHOD node.
|
||||
* The first node in the context is not necessarily the root. The context
|
||||
* matcher stops matching and returns true when it runs out of context.
|
||||
* There is no way to force the first node to be the root.
|
||||
*/
|
||||
@Override
|
||||
public boolean inContext(String context) {
|
||||
return inContext(_input.getTreeAdaptor(), getTokenNames(), _input.LT(1), context);
|
||||
}
|
||||
|
||||
/** The worker for inContext. It's static and full of parameters for
|
||||
* testing purposes.
|
||||
*/
|
||||
public static <T> boolean inContext(ASTAdaptor<T> adaptor,
|
||||
String[] tokenNames,
|
||||
T t,
|
||||
String context)
|
||||
{
|
||||
Matcher dotdotMatcher = dotdotPattern.matcher(context);
|
||||
Matcher doubleEtcMatcher = doubleEtcPattern.matcher(context);
|
||||
if ( dotdotMatcher.find() ) { // don't allow "..", must be "..."
|
||||
throw new IllegalArgumentException("invalid syntax: ..");
|
||||
}
|
||||
if ( doubleEtcMatcher.find() ) { // don't allow double "..."
|
||||
throw new IllegalArgumentException("invalid syntax: ... ...");
|
||||
}
|
||||
context = context.replaceAll("\\.\\.\\.", " ... "); // ensure spaces around ...
|
||||
context = context.trim();
|
||||
String[] nodes = context.split("\\s+");
|
||||
int ni = nodes.length-1;
|
||||
t = adaptor.getParent(t);
|
||||
while ( ni>=0 && t!=null ) {
|
||||
if ( nodes[ni].equals("...") ) {
|
||||
// walk upwards until we see nodes[ni-1] then continue walking
|
||||
if ( ni==0 ) return true; // ... at start is no-op
|
||||
String goal = nodes[ni-1];
|
||||
T ancestor = getAncestor(adaptor, tokenNames, t, goal);
|
||||
if ( ancestor==null ) return false;
|
||||
t = ancestor;
|
||||
ni--;
|
||||
}
|
||||
String name = tokenNames[adaptor.getType(t)];
|
||||
if ( !name.equals(nodes[ni]) ) {
|
||||
//System.err.println("not matched: "+nodes[ni]+" at "+t);
|
||||
return false;
|
||||
}
|
||||
// advance to parent and to previous element in context node list
|
||||
ni--;
|
||||
t = adaptor.getParent(t);
|
||||
}
|
||||
|
||||
if ( t==null && ni>=0 ) return false; // at root but more nodes to match
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Helper for static inContext */
|
||||
protected static <T> T getAncestor(ASTAdaptor<T> adaptor, String[] tokenNames, T t, String goal) {
|
||||
while ( t!=null ) {
|
||||
String name = tokenNames[adaptor.getType(t)];
|
||||
if ( name.equals(goal) ) return t;
|
||||
t = adaptor.getParent(t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// public void traceIn(String ruleName, int ruleIndex) {
|
||||
// super.traceIn(ruleName, ruleIndex, input.LT(1));
|
||||
// }
|
||||
//
|
||||
// public void traceOut(String ruleName, int ruleIndex) {
|
||||
// super.traceOut(ruleName, ruleIndex, input.LT(1));
|
||||
// }
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
/*
|
||||
[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 class TreePatternLexer {
|
||||
public static final int EOF = -1;
|
||||
public static final int BEGIN = 1;
|
||||
public static final int END = 2;
|
||||
public static final int ID = 3;
|
||||
public static final int ARG = 4;
|
||||
public static final int PERCENT = 5;
|
||||
public static final int COLON = 6;
|
||||
public static final int DOT = 7;
|
||||
|
||||
/** The tree pattern to lex like "(A B C)" */
|
||||
protected String pattern;
|
||||
|
||||
/** Index into input string */
|
||||
protected int p = -1;
|
||||
|
||||
/** Current char */
|
||||
protected int c;
|
||||
|
||||
/** How long is the pattern in char? */
|
||||
protected int n;
|
||||
|
||||
/** Set when token type is ID or ARG (name mimics Java's StreamTokenizer) */
|
||||
public StringBuffer sval = new StringBuffer();
|
||||
|
||||
public boolean error = false;
|
||||
|
||||
public TreePatternLexer(String pattern) {
|
||||
this.pattern = pattern;
|
||||
this.n = pattern.length();
|
||||
consume();
|
||||
}
|
||||
|
||||
public int nextToken() {
|
||||
sval.setLength(0); // reset, but reuse buffer
|
||||
while ( c != EOF ) {
|
||||
if ( c==' ' || c=='\n' || c=='\r' || c=='\t' ) {
|
||||
consume();
|
||||
continue;
|
||||
}
|
||||
if ( (c>='a' && c<='z') || (c>='A' && c<='Z') || c=='_' ) {
|
||||
sval.append((char)c);
|
||||
consume();
|
||||
while ( (c>='a' && c<='z') || (c>='A' && c<='Z') ||
|
||||
(c>='0' && c<='9') || c=='_' )
|
||||
{
|
||||
sval.append((char)c);
|
||||
consume();
|
||||
}
|
||||
return ID;
|
||||
}
|
||||
if ( c=='(' ) {
|
||||
consume();
|
||||
return BEGIN;
|
||||
}
|
||||
if ( c==')' ) {
|
||||
consume();
|
||||
return END;
|
||||
}
|
||||
if ( c=='%' ) {
|
||||
consume();
|
||||
return PERCENT;
|
||||
}
|
||||
if ( c==':' ) {
|
||||
consume();
|
||||
return COLON;
|
||||
}
|
||||
if ( c=='.' ) {
|
||||
consume();
|
||||
return DOT;
|
||||
}
|
||||
if ( c=='[' ) { // grab [x] as a string, returning x
|
||||
consume();
|
||||
while ( c!=']' ) {
|
||||
if ( c=='\\' ) {
|
||||
consume();
|
||||
if ( c!=']' ) {
|
||||
sval.append('\\');
|
||||
}
|
||||
sval.append((char)c);
|
||||
}
|
||||
else {
|
||||
sval.append((char)c);
|
||||
}
|
||||
consume();
|
||||
}
|
||||
consume();
|
||||
return ARG;
|
||||
}
|
||||
consume();
|
||||
error = true;
|
||||
return EOF;
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
protected void consume() {
|
||||
p++;
|
||||
if ( p>=n ) {
|
||||
c = EOF;
|
||||
}
|
||||
else {
|
||||
c = pattern.charAt(p);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
public class TreePatternParser {
|
||||
protected TreePatternLexer tokenizer;
|
||||
protected int ttype;
|
||||
protected TreeWizard<?> wizard;
|
||||
// TODO: would be nice to use ASTAdaptor<TreeWizard.TreePattern>...
|
||||
protected ASTAdaptor<CommonAST> adaptor;
|
||||
|
||||
public TreePatternParser(TreePatternLexer tokenizer, TreeWizard<?> wizard, ASTAdaptor<CommonAST> adaptor) {
|
||||
this.tokenizer = tokenizer;
|
||||
this.wizard = wizard;
|
||||
this.adaptor = adaptor;
|
||||
ttype = tokenizer.nextToken(); // kickstart
|
||||
}
|
||||
|
||||
public TreeWizard.TreePattern pattern() {
|
||||
if ( ttype==TreePatternLexer.BEGIN ) {
|
||||
return parseTree();
|
||||
}
|
||||
else if ( ttype==TreePatternLexer.ID ) {
|
||||
TreeWizard.TreePattern node = parseNode();
|
||||
if ( ttype==TreePatternLexer.EOF ) {
|
||||
return node;
|
||||
}
|
||||
return null; // extra junk on end
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public TreeWizard.TreePattern parseTree() {
|
||||
if ( ttype != TreePatternLexer.BEGIN ) {
|
||||
throw new RuntimeException("no BEGIN");
|
||||
}
|
||||
ttype = tokenizer.nextToken();
|
||||
TreeWizard.TreePattern root = parseNode();
|
||||
if ( root==null ) {
|
||||
return null;
|
||||
}
|
||||
while ( ttype==TreePatternLexer.BEGIN ||
|
||||
ttype==TreePatternLexer.ID ||
|
||||
ttype==TreePatternLexer.PERCENT ||
|
||||
ttype==TreePatternLexer.DOT )
|
||||
{
|
||||
if ( ttype==TreePatternLexer.BEGIN ) {
|
||||
TreeWizard.TreePattern subtree = parseTree();
|
||||
adaptor.addChild(root, subtree);
|
||||
}
|
||||
else {
|
||||
TreeWizard.TreePattern child = parseNode();
|
||||
if ( child==null ) {
|
||||
return null;
|
||||
}
|
||||
adaptor.addChild(root, child);
|
||||
}
|
||||
}
|
||||
if ( ttype != TreePatternLexer.END ) {
|
||||
throw new RuntimeException("no END");
|
||||
}
|
||||
ttype = tokenizer.nextToken();
|
||||
return root;
|
||||
}
|
||||
|
||||
public TreeWizard.TreePattern parseNode() {
|
||||
// "%label:" prefix
|
||||
String label = null;
|
||||
if ( ttype == TreePatternLexer.PERCENT ) {
|
||||
ttype = tokenizer.nextToken();
|
||||
if ( ttype != TreePatternLexer.ID ) {
|
||||
return null;
|
||||
}
|
||||
label = tokenizer.sval.toString();
|
||||
ttype = tokenizer.nextToken();
|
||||
if ( ttype != TreePatternLexer.COLON ) {
|
||||
return null;
|
||||
}
|
||||
ttype = tokenizer.nextToken(); // move to ID following colon
|
||||
}
|
||||
|
||||
// Wildcard?
|
||||
if ( ttype == TreePatternLexer.DOT ) {
|
||||
ttype = tokenizer.nextToken();
|
||||
Token wildcardPayload = new CommonToken(0, ".");
|
||||
TreeWizard.TreePattern node =
|
||||
new TreeWizard.WildcardTreePattern(wildcardPayload);
|
||||
if ( label!=null ) {
|
||||
node.label = label;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// "ID" or "ID[arg]"
|
||||
if ( ttype != TreePatternLexer.ID ) {
|
||||
return null;
|
||||
}
|
||||
String tokenName = tokenizer.sval.toString();
|
||||
ttype = tokenizer.nextToken();
|
||||
if ( tokenName.equals("nil") ) {
|
||||
return (TreeWizard.TreePattern)adaptor.nil();
|
||||
}
|
||||
String text = tokenName;
|
||||
// check for arg
|
||||
String arg = null;
|
||||
if ( ttype == TreePatternLexer.ARG ) {
|
||||
arg = tokenizer.sval.toString();
|
||||
text = arg;
|
||||
ttype = tokenizer.nextToken();
|
||||
}
|
||||
|
||||
// create node
|
||||
int treeNodeType = wizard.getTokenType(tokenName);
|
||||
if ( treeNodeType== Token.INVALID_TYPE ) {
|
||||
return null;
|
||||
}
|
||||
TreeWizard.TreePattern node;
|
||||
node = (TreeWizard.TreePattern)adaptor.create(treeNodeType, text);
|
||||
if ( label!=null && node.getClass()==TreeWizard.TreePattern.class ) {
|
||||
node.label = label;
|
||||
}
|
||||
if ( arg!=null && node.getClass()==TreeWizard.TreePattern.class ) {
|
||||
node.hasTextArg = true;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
/** Do a depth first walk of a tree, applying pre() and post() actions
|
||||
* as we discover and finish nodes.
|
||||
*/
|
||||
public class TreeVisitor<T> {
|
||||
protected ASTAdaptor<T> adaptor;
|
||||
|
||||
public TreeVisitor(ASTAdaptor<T> adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
|
||||
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.
|
||||
* Execute both actions even if t has no children.
|
||||
* If a child visit yields a new child, it can update its
|
||||
* parent's child list or just return the new child. The
|
||||
* child update code works even if the child visit alters its parent
|
||||
* and returns the new tree.
|
||||
*
|
||||
* Return result of applying post action to this node.
|
||||
*/
|
||||
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++) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if ( action!=null && !isNil ) t = action.post(t);
|
||||
return t;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
/** How to execute code for node t when a visitor visits node t. Execute
|
||||
* pre() before visiting children and execute post() after visiting children.
|
||||
*/
|
||||
public interface TreeVisitorAction<T> {
|
||||
/** Execute an action before visiting children of t. Return t or
|
||||
* a rewritten t. It is up to the visitor to decide what to do
|
||||
* with the return value. Children of returned value will be
|
||||
* visited if using TreeVisitor.visit().
|
||||
*/
|
||||
public T pre(T t);
|
||||
|
||||
/** Execute an action after visiting children of t. Return t or
|
||||
* a rewritten t. It is up to the visitor to decide what to do
|
||||
* with the return value.
|
||||
*/
|
||||
public T post(T t);
|
||||
}
|
|
@ -1,535 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** Build and navigate trees with this object. Must know about the names
|
||||
* of tokens so you have to pass in a map or array of token names (from which
|
||||
* this class can build the map). I.e., Token DECL means nothing unless the
|
||||
* class can translate it to a token type.
|
||||
*
|
||||
* In order to create nodes and navigate, this class needs a ASTAdaptor.
|
||||
*
|
||||
* This class can build a token type -> node index for repeated use or for
|
||||
* iterating over the various nodes with a particular type.
|
||||
*
|
||||
* This class works in conjunction with the ASTAdaptor rather than moving
|
||||
* all this functionality into the adaptor. An adaptor helps build and
|
||||
* navigate trees using methods. This class helps you do it with string
|
||||
* patterns like "(A B C)". You can create a tree from that pattern or
|
||||
* match subtrees against it.
|
||||
*/
|
||||
public class TreeWizard<T> {
|
||||
protected ASTAdaptor<T> adaptor;
|
||||
protected Map<String, Integer> tokenNameToTypeMap;
|
||||
|
||||
public interface ContextVisitor<T> {
|
||||
// TODO: should this be called visit or something else?
|
||||
public void visit(T t, Object parent, int childIndex, @Nullable Map<String, T> 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(T t);
|
||||
}
|
||||
|
||||
/** When using %label:TOKENNAME in a tree for parse(), we must
|
||||
* track the label.
|
||||
*/
|
||||
public static class TreePattern extends CommonAST {
|
||||
public String label;
|
||||
public boolean hasTextArg;
|
||||
public TreePattern(Token payload) {
|
||||
super(payload);
|
||||
}
|
||||
public String toString() {
|
||||
if ( label!=null ) {
|
||||
return "%"+label+":"+super.toString();
|
||||
}
|
||||
else {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class WildcardTreePattern extends TreePattern {
|
||||
public WildcardTreePattern(Token payload) {
|
||||
super(payload);
|
||||
}
|
||||
}
|
||||
|
||||
/** This adaptor creates TreePattern objects for use during scan() */
|
||||
public static class TreePatternASTAdaptor extends CommonASTAdaptor {
|
||||
public CommonAST create(Token payload) {
|
||||
return new TreePattern(payload);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: build indexes for the wizard
|
||||
|
||||
/** During fillBuffer(), we can make a reverse index from a set
|
||||
* of token types of interest to the list of indexes into the
|
||||
* node stream. This lets us convert a node pointer to a
|
||||
* stream index semi-efficiently for a list of interesting
|
||||
* nodes such as function definition nodes (you'll want to seek
|
||||
* to their bodies for an interpreter). Also useful for doing
|
||||
* dynamic searches; i.e., go find me all PLUS nodes.
|
||||
protected Map tokenTypeToStreamIndexesMap;
|
||||
|
||||
/** If tokenTypesToReverseIndex set to INDEX_ALL then indexing
|
||||
* occurs for all token types.
|
||||
public static final Set INDEX_ALL = new HashSet();
|
||||
|
||||
/** A set of token types user would like to index for faster lookup.
|
||||
* If this is INDEX_ALL, then all token types are tracked. If null,
|
||||
* then none are indexed.
|
||||
protected Set tokenTypesToReverseIndex = null;
|
||||
*/
|
||||
|
||||
public TreeWizard(ASTAdaptor<T> adaptor) {
|
||||
this.adaptor = adaptor;
|
||||
}
|
||||
|
||||
public TreeWizard(ASTAdaptor<T> adaptor, Map<String, Integer> tokenNameToTypeMap) {
|
||||
this.adaptor = adaptor;
|
||||
this.tokenNameToTypeMap = tokenNameToTypeMap;
|
||||
}
|
||||
|
||||
public TreeWizard(ASTAdaptor<T> adaptor, String[] tokenNames) {
|
||||
this.adaptor = adaptor;
|
||||
this.tokenNameToTypeMap = computeTokenTypes(tokenNames);
|
||||
}
|
||||
|
||||
public TreeWizard(String[] 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<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, ttype);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Using the map of token names to token types, return the type. */
|
||||
public int getTokenType(String tokenName) {
|
||||
if ( tokenNameToTypeMap==null ) {
|
||||
return Token.INVALID_TYPE;
|
||||
}
|
||||
Integer ttypeI = tokenNameToTypeMap.get(tokenName);
|
||||
if ( ttypeI!=null ) {
|
||||
return ttypeI;
|
||||
}
|
||||
return Token.INVALID_TYPE;
|
||||
}
|
||||
|
||||
/** Walk the entire tree and make a node name to nodes mapping.
|
||||
* For now, use recursion but later nonrecursive version may be
|
||||
* more efficient. Returns Map<Integer, List> where the List is
|
||||
* of your AST node type. The Integer is the token type of the node.
|
||||
*
|
||||
* TODO: save this index so that find and visit are faster
|
||||
*/
|
||||
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(T t, Map<Integer, List<T>> m) {
|
||||
if ( t==null ) {
|
||||
return;
|
||||
}
|
||||
int ttype = adaptor.getType(t);
|
||||
List<T> elements = m.get(ttype);
|
||||
if ( elements==null ) {
|
||||
elements = new ArrayList<T>();
|
||||
m.put(ttype, elements);
|
||||
}
|
||||
elements.add(t);
|
||||
int n = adaptor.getChildCount(t);
|
||||
for (int i=0; i<n; i++) {
|
||||
T child = adaptor.getChild(t, i);
|
||||
_index(child, m);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a List of tree nodes with token type ttype */
|
||||
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);
|
||||
}
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/** Return a List of subtrees matching pattern. */
|
||||
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 = parser.pattern();
|
||||
// don't allow invalid patterns
|
||||
if ( tpattern==null ||
|
||||
tpattern.isNil() ||
|
||||
tpattern.getClass()==WildcardTreePattern.class )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
int rootTokenType = tpattern.getType();
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
return subtrees;
|
||||
}
|
||||
|
||||
public T findFirst(T t, int ttype) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public T findFirst(T t, String pattern) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Visit every ttype node in t, invoking the visitor. This is a quicker
|
||||
* version of the general visit(t, pattern) method. The labels arg
|
||||
* 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(T t, int ttype, ContextVisitor<T> visitor) {
|
||||
_visit(t, null, 0, ttype, visitor);
|
||||
}
|
||||
|
||||
/** Do the recursive work for visit */
|
||||
protected void _visit(T t, @Nullable Object parent, int childIndex, int ttype, ContextVisitor<T> visitor) {
|
||||
if ( t==null ) {
|
||||
return;
|
||||
}
|
||||
if ( adaptor.getType(t)==ttype ) {
|
||||
visitor.visit(t, parent, childIndex, null);
|
||||
}
|
||||
int n = adaptor.getChildCount(t);
|
||||
for (int i=0; i<n; i++) {
|
||||
T child = adaptor.getChild(t, i);
|
||||
_visit(child, t, i, ttype, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
/** For all subtrees that match the pattern, execute the visit action.
|
||||
* The implementation uses the root node of the pattern in combination
|
||||
* with visit(t, ttype, visitor) so nil-rooted patterns are not allowed.
|
||||
* Patterns with wildcard roots are also not allowed.
|
||||
*/
|
||||
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 = parser.pattern();
|
||||
// don't allow invalid patterns
|
||||
if ( tpattern==null ||
|
||||
tpattern.isNil() ||
|
||||
tpattern.getClass()==WildcardTreePattern.class )
|
||||
{
|
||||
return;
|
||||
}
|
||||
final Map<String, T> labels = new HashMap<String, T>(); // reused for each _parse
|
||||
int rootTokenType = tpattern.getType();
|
||||
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) ) {
|
||||
visitor.visit(t, parent, childIndex, labels);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Given a pattern like (ASSIGN %lhs:ID %rhs:.) with optional labels
|
||||
* on the various nodes and '.' (dot) as the node/subtree wildcard,
|
||||
* return true if the pattern matches and fill the labels Map with
|
||||
* the labels pointing at the appropriate nodes. Return false if
|
||||
* the pattern is malformed or the tree does not match.
|
||||
*
|
||||
* If a node specifies a text arg in pattern, then that must match
|
||||
* for that node in t.
|
||||
*
|
||||
* TODO: what's a better way to indicate bad pattern? Exceptions are a hassle
|
||||
*/
|
||||
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 = parser.pattern();
|
||||
/*
|
||||
System.out.println("t="+((Tree)t).toStringTree());
|
||||
System.out.println("scant="+tpattern.toStringTree());
|
||||
*/
|
||||
boolean matched = _parse(t, tpattern, labels);
|
||||
return matched;
|
||||
}
|
||||
|
||||
public boolean parse(T t, String pattern) {
|
||||
return parse(t, pattern, null);
|
||||
}
|
||||
|
||||
/** Do the work for parse. Check to see if the t2 pattern fits the
|
||||
* structure and token types in t1. Check text if the pattern has
|
||||
* text arguments on nodes. Fill labels map with pointers to nodes
|
||||
* in tree matched against nodes in pattern with 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;
|
||||
}
|
||||
// check roots (wildcard matches anything)
|
||||
if ( tpattern.getClass() != WildcardTreePattern.class ) {
|
||||
if ( adaptor.getType(t1) != tpattern.getType() ) return false;
|
||||
// if pattern has text, check node text
|
||||
if ( tpattern.hasTextArg && !adaptor.getText(t1).equals(tpattern.getText()) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( tpattern.label!=null && labels!=null ) {
|
||||
// map label in pattern to node in t1
|
||||
labels.put(tpattern.label, t1);
|
||||
}
|
||||
// check children
|
||||
int n1 = adaptor.getChildCount(t1);
|
||||
int n2 = tpattern.getChildCount();
|
||||
if ( n1 != n2 ) {
|
||||
return false;
|
||||
}
|
||||
for (int i=0; i<n1; i++) {
|
||||
T child1 = adaptor.getChild(t1, i);
|
||||
TreePattern child2 = (TreePattern)tpattern.getChild(i);
|
||||
if ( !_parse(child1, child2, labels) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Create a tree or node from the indicated tree pattern that closely
|
||||
* follows ANTLR tree grammar tree element syntax:
|
||||
*
|
||||
* (root child1 ... child2).
|
||||
*
|
||||
* You can also just pass in a node: ID
|
||||
*
|
||||
* Any node can have a text argument: ID[foo]
|
||||
* (notice there are no quotes around foo--it's clear it's a string).
|
||||
*
|
||||
* 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 TreePattern create(String pattern) {
|
||||
TreePatternLexer tokenizer = new TreePatternLexer(pattern);
|
||||
TreePatternParser parser = new TreePatternParser(tokenizer, this, new TreePatternASTAdaptor());
|
||||
TreePattern t = parser.pattern();
|
||||
return t;
|
||||
}
|
||||
|
||||
/** Compare t1 and t2; return true if token types/text, structure match exactly.
|
||||
* The trees are examined in their entirety so that (A B) does not match
|
||||
* (A B C) nor (A (B C)).
|
||||
// TODO: allow them to pass in a comparator
|
||||
* TODO: have a version that is nonstatic so it can use instance adaptor
|
||||
*
|
||||
* 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 <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(T t1, T t2) {
|
||||
return _equals(t1, t2, 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;
|
||||
}
|
||||
// check roots
|
||||
if ( adaptor.getType(t1) != adaptor.getType(t2) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !adaptor.getText(t1).equals(adaptor.getText(t2)) ) {
|
||||
return false;
|
||||
}
|
||||
// check children
|
||||
int n1 = adaptor.getChildCount(t1);
|
||||
int n2 = adaptor.getChildCount(t2);
|
||||
if ( n1 != n2 ) {
|
||||
return false;
|
||||
}
|
||||
for (int i=0; i<n1; i++) {
|
||||
T child1 = adaptor.getChild(t1, i);
|
||||
T child2 = adaptor.getChild(t2, i);
|
||||
if ( !_equals(child1, child2, adaptor) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: next stuff taken from CommonASTNodeStream
|
||||
|
||||
/** Given a node, add this to the reverse index tokenTypeToStreamIndexesMap.
|
||||
* You can override this method to alter how indexing occurs. The
|
||||
* default is to create a
|
||||
*
|
||||
* Map<Integer token type,ArrayList<Integer stream index>>
|
||||
*
|
||||
* This data structure allows you to find all nodes with type INT in order.
|
||||
*
|
||||
* If you really need to find a node of type, say, FUNC quickly then perhaps
|
||||
*
|
||||
* Map<Integertoken type,Map<Object tree node,Integer stream index>>
|
||||
*
|
||||
* would be better for you. The interior maps map a tree node to
|
||||
* the index so you don't have to search linearly for a specific node.
|
||||
*
|
||||
* If you change this method, you will likely need to change
|
||||
* getNodeIndex(), which extracts information.
|
||||
protected void fillReverseIndex(Object node, int streamIndex) {
|
||||
//System.out.println("revIndex "+node+"@"+streamIndex);
|
||||
if ( tokenTypesToReverseIndex==null ) {
|
||||
return; // no indexing if this is empty (nothing of interest)
|
||||
}
|
||||
if ( tokenTypeToStreamIndexesMap==null ) {
|
||||
tokenTypeToStreamIndexesMap = new HashMap(); // first indexing op
|
||||
}
|
||||
int tokenType = adaptor.getType(node);
|
||||
Integer tokenTypeI = new Integer(tokenType);
|
||||
if ( !(tokenTypesToReverseIndex==INDEX_ALL ||
|
||||
tokenTypesToReverseIndex.contains(tokenTypeI)) )
|
||||
{
|
||||
return; // tokenType not of interest
|
||||
}
|
||||
Integer streamIndexI = new Integer(streamIndex);
|
||||
ArrayList indexes = (ArrayList)tokenTypeToStreamIndexesMap.get(tokenTypeI);
|
||||
if ( indexes==null ) {
|
||||
indexes = new ArrayList(); // no list yet for this token type
|
||||
indexes.add(streamIndexI); // not there yet, add
|
||||
tokenTypeToStreamIndexesMap.put(tokenTypeI, indexes);
|
||||
}
|
||||
else {
|
||||
if ( !indexes.contains(streamIndexI) ) {
|
||||
indexes.add(streamIndexI); // not there yet, add
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Track the indicated token type in the reverse index. Call this
|
||||
* repeatedly for each type or use variant with Set argument to
|
||||
* set all at once.
|
||||
* @param tokenType
|
||||
public void reverseIndex(int tokenType) {
|
||||
if ( tokenTypesToReverseIndex==null ) {
|
||||
tokenTypesToReverseIndex = new HashSet();
|
||||
}
|
||||
else if ( tokenTypesToReverseIndex==INDEX_ALL ) {
|
||||
return;
|
||||
}
|
||||
tokenTypesToReverseIndex.add(new Integer(tokenType));
|
||||
}
|
||||
|
||||
/** Track the indicated token types in the reverse index. Set
|
||||
* to INDEX_ALL to track all token types.
|
||||
public void reverseIndex(Set tokenTypes) {
|
||||
tokenTypesToReverseIndex = tokenTypes;
|
||||
}
|
||||
|
||||
/** Given a node pointer, return its index into the node stream.
|
||||
* This is not its Token stream index. If there is no reverse map
|
||||
* from node to stream index or the map does not contain entries
|
||||
* for node's token type, a linear search of entire stream is used.
|
||||
*
|
||||
* Return -1 if exact node pointer not in stream.
|
||||
public int getNodeIndex(Object node) {
|
||||
//System.out.println("get "+node);
|
||||
if ( tokenTypeToStreamIndexesMap==null ) {
|
||||
return getNodeIndexLinearly(node);
|
||||
}
|
||||
int tokenType = adaptor.getType(node);
|
||||
Integer tokenTypeI = new Integer(tokenType);
|
||||
ArrayList indexes = (ArrayList)tokenTypeToStreamIndexesMap.get(tokenTypeI);
|
||||
if ( indexes==null ) {
|
||||
//System.out.println("found linearly; stream index = "+getNodeIndexLinearly(node));
|
||||
return getNodeIndexLinearly(node);
|
||||
}
|
||||
for (int i = 0; i < indexes.size(); i++) {
|
||||
Integer streamIndexI = (Integer)indexes.get(i);
|
||||
Object n = get(streamIndexI.intValue());
|
||||
if ( n==node ) {
|
||||
//System.out.println("found in index; stream index = "+streamIndexI);
|
||||
return streamIndexI.intValue(); // found it!
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
|
@ -29,17 +29,22 @@
|
|||
|
||||
package org.antlr.v4.runtime.tree;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.BaseRecognizer;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.tree.gui.TreePostScriptGenerator;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** 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 =
|
||||
|
@ -47,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
|
||||
|
@ -63,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);
|
||||
|
@ -73,29 +78,21 @@ 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();
|
||||
if ( !nilRoot ) {
|
||||
buf.append("(");
|
||||
buf.append(getNodeText(t, recog));
|
||||
buf.append(' ');
|
||||
}
|
||||
for (int i = 0; i<t.getChildCount(); i++) {
|
||||
if ( i>0 ) buf.append(' ');
|
||||
buf.append(toStringTree(t.getChild(i), recog));
|
||||
}
|
||||
if ( !nilRoot ) {
|
||||
buf.append(")");
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static <Symbol> String getNodeText(Tree t, BaseRecognizer<Symbol> recog) {
|
||||
if ( t instanceof AST ) {
|
||||
return t.toString();
|
||||
}
|
||||
public static <Symbol> String getNodeText(Tree t, BaseRecognizer recog) {
|
||||
if ( recog!=null ) {
|
||||
if ( t instanceof ParseTree.RuleNode ) {
|
||||
int ruleIndex = ((ParseTree.RuleNode)t).getRuleContext().getRuleIndex();
|
||||
|
@ -112,7 +109,7 @@ public class Trees {
|
|||
}
|
||||
}
|
||||
}
|
||||
// not AST and no recog for rule names
|
||||
// no recog for rule names
|
||||
Object payload = t.getPayload();
|
||||
if ( payload instanceof Token ) {
|
||||
return ((Token)payload).getText();
|
||||
|
@ -120,16 +117,6 @@ public class Trees {
|
|||
return t.getPayload().toString();
|
||||
}
|
||||
|
||||
/** Walk upwards and get first ancestor with this token type. */
|
||||
public static AST getAncestor(AST t, int ttype) {
|
||||
t = t.getParent();
|
||||
while ( t!=null ) {
|
||||
if ( t.getType()==ttype ) return t;
|
||||
t = t.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Return a list of all ancestors of this node. The first node of
|
||||
* list is the root and the last is the parent of this node.
|
||||
*/
|
||||
|
@ -145,162 +132,4 @@ public class Trees {
|
|||
return ancestors;
|
||||
}
|
||||
|
||||
public static AST getFirstChildWithType(AST t, int type) {
|
||||
for (int i = 0; i<t.getChildCount(); i++) {
|
||||
AST c = (AST)t.getChild(i);
|
||||
if ( c.getType()==type ) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Delete children from start to stop and replace with t even if t is
|
||||
* a list (nil-root tree). num of children can increase or decrease.
|
||||
* For huge child lists, inserting children can force walking rest of
|
||||
* children to set their childindex; could be slow.
|
||||
*/
|
||||
public static void replaceChildren(BaseAST tree, int startChildIndex, int stopChildIndex, Object t) {
|
||||
/*
|
||||
System.out.println("replaceChildren "+startChildIndex+", "+stopChildIndex+
|
||||
" with "+((BaseTree)t).toStringTree());
|
||||
System.out.println("in="+toStringTree());
|
||||
*/
|
||||
if ( tree.getChildCount()==0 ) {
|
||||
throw new IllegalArgumentException("indexes invalid; no children in list");
|
||||
}
|
||||
int replacingHowMany = stopChildIndex - startChildIndex + 1;
|
||||
int replacingWithHowMany;
|
||||
BaseAST newTree = (BaseAST)t;
|
||||
List<BaseAST> newChildren;
|
||||
// normalize to a list of children to add: newChildren
|
||||
if ( newTree.isNil() ) {
|
||||
newChildren = newTree.children;
|
||||
}
|
||||
else {
|
||||
newChildren = new ArrayList<BaseAST>(1);
|
||||
newChildren.add(newTree);
|
||||
}
|
||||
replacingWithHowMany = newChildren.size();
|
||||
int numNewChildren = newChildren.size();
|
||||
int delta = replacingHowMany - replacingWithHowMany;
|
||||
// if same number of nodes, do direct replace
|
||||
if ( delta == 0 ) {
|
||||
int j = 0; // index into new children
|
||||
for (int i=startChildIndex; i<=stopChildIndex; i++) {
|
||||
BaseAST child = newChildren.get(j);
|
||||
tree.setChild(i, child);
|
||||
child.setParent(tree);
|
||||
child.setChildIndex(i);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
else if ( delta > 0 ) { // fewer new nodes than there were
|
||||
// set children and then delete extra
|
||||
for (int j=0; j<numNewChildren; j++) {
|
||||
tree.setChild(startChildIndex + j, newChildren.get(j));
|
||||
}
|
||||
int indexToDelete = startChildIndex+numNewChildren;
|
||||
for (int c=indexToDelete; c<=stopChildIndex; c++) {
|
||||
// delete same index, shifting everybody down each time
|
||||
tree.children.remove(indexToDelete);
|
||||
}
|
||||
tree.freshenParentAndChildIndexes(startChildIndex);
|
||||
}
|
||||
else { // more new nodes than were there before
|
||||
// fill in as many children as we can (replacingHowMany) w/o moving data
|
||||
for (int j=0; j<replacingHowMany; j++) {
|
||||
tree.children.set(startChildIndex+j, newChildren.get(j));
|
||||
}
|
||||
int numToInsert = replacingWithHowMany-replacingHowMany;
|
||||
for (int j=replacingHowMany; j<replacingWithHowMany; j++) {
|
||||
tree.children.add(startChildIndex+j, newChildren.get(j));
|
||||
}
|
||||
tree.freshenParentAndChildIndexes(startChildIndex);
|
||||
}
|
||||
//System.out.println("out="+toStringTree());
|
||||
}
|
||||
|
||||
public static <Symbol> Symbol dupTree(ASTAdaptor<Symbol> adaptor, Symbol t, Symbol parent) {
|
||||
if ( t==null ) {
|
||||
return null;
|
||||
}
|
||||
Symbol 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++) {
|
||||
Symbol child = adaptor.getChild(t, i);
|
||||
Symbol newSubTree = dupTree(adaptor, child, t);
|
||||
adaptor.addChild(newTree, newSubTree);
|
||||
}
|
||||
return newTree;
|
||||
}
|
||||
|
||||
/** For every node in this subtree, make sure it's start/stop token's
|
||||
* are set. Walk depth first, visit bottom up. Only updates nodes
|
||||
* with at least one token index < 0.
|
||||
*/
|
||||
public static void setUnknownTokenBoundaries(CommonAST t) {
|
||||
if ( t.children==null ) {
|
||||
if ( t.startIndex<0 || t.stopIndex<0 ) {
|
||||
t.startIndex = t.stopIndex = t.token.getTokenIndex();
|
||||
}
|
||||
return;
|
||||
}
|
||||
int n = t.getChildCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
setUnknownTokenBoundaries(t.getChild(i));
|
||||
}
|
||||
if ( t.startIndex>=0 && t.stopIndex>=0 ) return; // already set
|
||||
if ( t.getChildCount() > 0 ) {
|
||||
CommonAST firstChild = t.getChild(0);
|
||||
CommonAST lastChild = t.getChild(t.getChildCount()-1);
|
||||
t.startIndex = firstChild.getTokenStartIndex();
|
||||
t.stopIndex = lastChild.getTokenStopIndex();
|
||||
}
|
||||
}
|
||||
|
||||
public static AST getFirstDescendantWithType(AST t, final int type) {
|
||||
return getFirstDescendantWithType(t, new TreeSet<Integer>() {{add(type);}} );
|
||||
}
|
||||
|
||||
// TODO: don't include this node!!
|
||||
public static AST getFirstDescendantWithType(AST t, Set<Integer> types) {
|
||||
if ( types.contains(t.getType()) ) return t;
|
||||
if ( t.getChildCount()==0 ) return null;
|
||||
int n = t.getChildCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
AST c = (AST)t.getChild(i);
|
||||
if ( types.contains(c.getType()) ) return c;
|
||||
AST d = getFirstDescendantWithType(c, types);
|
||||
if ( d!=null ) return d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void sanityCheckParentAndChildIndexes(BaseAST t) {
|
||||
sanityCheckParentAndChildIndexes(t, null, -1);
|
||||
}
|
||||
|
||||
public static void sanityCheckParentAndChildIndexes(BaseAST t, AST parent, int i) {
|
||||
if ( parent!=t.getParent() ) {
|
||||
throw new IllegalStateException("parents don't match; expected "+
|
||||
parent+" found "+t.getParent());
|
||||
}
|
||||
if ( i!=t.getChildIndex() ) {
|
||||
throw new IllegalStateException("child index of "+t.toStringTree()+
|
||||
" doesn't match in "+
|
||||
parent.toStringTree()+
|
||||
"; expected "+i+" found "+
|
||||
t.getChildIndex());
|
||||
}
|
||||
int n = t.getChildCount();
|
||||
for (int c = 0; c < n; c++) {
|
||||
BaseAST child = t.getChild(c);
|
||||
sanityCheckParentAndChildIndexes(child, t, c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,15 +35,11 @@ import org.abego.treelayout.TreeForTreeLayout;
|
|||
import org.abego.treelayout.TreeLayout;
|
||||
import org.abego.treelayout.util.DefaultConfiguration;
|
||||
import org.antlr.v4.runtime.BaseRecognizer;
|
||||
import org.antlr.v4.runtime.CommonToken;
|
||||
import org.antlr.v4.runtime.tree.CommonAST;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.Tree;
|
||||
import org.antlr.v4.runtime.tree.Trees;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TreePostScriptGenerator {
|
||||
public class VariableExtentProvide implements NodeExtentProvider<Tree> {
|
||||
|
@ -75,11 +71,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;
|
||||
|
@ -167,36 +163,4 @@ public class TreePostScriptGenerator {
|
|||
this.treeTextProvider = treeTextProvider;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
CommonAST t = new CommonAST(new CommonToken(1, "s"));
|
||||
CommonAST ifstat = new CommonAST(new CommonToken(1, "ifstat"));
|
||||
CommonAST iff = new CommonAST(new CommonToken(1, "if"));
|
||||
CommonAST b = new CommonAST(new CommonToken(1, "("));
|
||||
CommonAST c = new CommonAST(new CommonToken(1, "expr"));
|
||||
CommonAST d = new CommonAST(new CommonToken(1, ")"));
|
||||
CommonAST e = new CommonAST(new CommonToken(1, "assign"));
|
||||
CommonAST f = new CommonAST(new CommonToken(1, "34"));
|
||||
CommonAST g = new CommonAST(new CommonToken(1, "a"));
|
||||
CommonAST h = new CommonAST(new CommonToken(1, "="));
|
||||
CommonAST i = new CommonAST(new CommonToken(1, "expr"));
|
||||
CommonAST j = new CommonAST(new CommonToken(1, ";"));
|
||||
CommonAST k = new CommonAST(new CommonToken(1, "b"));
|
||||
t.addChild(ifstat);
|
||||
ifstat.addChild(iff);
|
||||
ifstat.addChild(b);
|
||||
ifstat.addChild(c);
|
||||
ifstat.addChild(d);
|
||||
ifstat.addChild(e);
|
||||
c.addChild(f);
|
||||
e.addChild(g);
|
||||
e.addChild(h);
|
||||
e.addChild(i);
|
||||
e.addChild(j);
|
||||
i.addChild(k);
|
||||
Trees.writePS(t, null,
|
||||
"/Users/parrt/antlr/code/antlr4/main/tool/playground/t.eps",
|
||||
"ArialNarrow", 11);
|
||||
// TreePostScriptGenerator psgen = new TreePostScriptGenerator(null, t, "CourierNew", 11);
|
||||
// System.out.println(psgen.getPS());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,9 +53,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;
|
||||
BaseRecognizer parser;
|
||||
|
||||
public DefaultTreeTextProvider(BaseRecognizer<?> parser) {
|
||||
public DefaultTreeTextProvider(BaseRecognizer parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
|
@ -111,9 +111,9 @@ public class TreeViewer extends JComponent {
|
|||
protected Color borderColor = null;
|
||||
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));
|
||||
boolean useIdentity = true; // compare node identity
|
||||
|
|
|
@ -13,3 +13,5 @@ Trees
|
|||
Lexers
|
||||
|
||||
* Added [Abc] notation
|
||||
|
||||
* unicode rule/token names
|
|
@ -1,4 +1,4 @@
|
|||
ûparser grammar JavaParser;
|
||||
parser grammar JavaParser;
|
||||
options {backtrack=true; memoize=true; tokenVocab=JavaLexer;}
|
||||
|
||||
// starting point for parsing a java file
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
import org.antlr.v4.runtime.ANTLRFileStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.DiagnosticErrorStrategy;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
public class TestR {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
@ -42,7 +41,7 @@ public class TestR {
|
|||
// }
|
||||
RParser p = new RParser(tokens);
|
||||
p.setBuildParseTree(true);
|
||||
p.setErrorHandler(new DiagnosticErrorStrategy<Token>());
|
||||
p.setErrorHandler(new DiagnosticErrorStrategy());
|
||||
p.prog();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,6 @@ import java.util.ArrayList;
|
|||
<parser>
|
||||
>>
|
||||
|
||||
TreeParserFile(file, parser, namedActions) ::= <<
|
||||
<ParserFile(...)>
|
||||
>>
|
||||
|
||||
ListenerFile(file, header) ::= <<
|
||||
<header>
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
@ -64,16 +60,6 @@ Parser(parser, funcs, atn, sempredFuncs, superclass) ::= <<
|
|||
<Parser_(ctor="parser_ctor", ...)>
|
||||
>>
|
||||
|
||||
TreeParserModel(parser, funcs, atn, sempredFuncs, superclass) ::= <<
|
||||
<Parser_(ctor="treeparser_ctor",
|
||||
extras={
|
||||
@Override
|
||||
public <ASTLabelType()> match(int ttype) throws RecognitionException {
|
||||
return (<ASTLabelType()>)super.match(ttype);
|
||||
\}
|
||||
}, ...)>
|
||||
>>
|
||||
|
||||
Parser_(parser, funcs, atn, sempredFuncs, ctor, extras, superclass) ::= <<
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused"})
|
||||
public class <parser.name> extends <superclass> {
|
||||
|
@ -148,13 +134,6 @@ public <p.name>(TokenStream input) {
|
|||
}
|
||||
>>
|
||||
|
||||
treeparser_ctor(p) ::= <<
|
||||
public <p.name>(ASTNodeStream\<<ASTLabelType()>\> input) {
|
||||
super(input);
|
||||
_interp = new v2ParserATNSimulator\<<ASTLabelType()>\>(this,_ATN);
|
||||
}
|
||||
>>
|
||||
|
||||
RuleActionFunction(r, actions) ::= <<
|
||||
public void <r.name>_action(<r.ctxType> _localctx, int actionIndex) {
|
||||
switch ( actionIndex ) {
|
||||
|
@ -379,14 +358,6 @@ case <i>:
|
|||
Sync(s) ::= "sync(<s.expecting.name>);"
|
||||
|
||||
ThrowNoViableAlt(t) ::= "throw new NoViableAltException(this);"
|
||||
ThrowNoViableTreeAlt(t) ::= <<
|
||||
/*
|
||||
NoViableTreeGrammarAltException e<choice.uniqueID> = new NoViableTreeGrammarAltException(this);
|
||||
_errHandler.reportError(this, e<choice.uniqueID>);
|
||||
throw e<choice.uniqueID>;
|
||||
*/
|
||||
throw new NoViableTreeGrammarAltException(this);
|
||||
>>
|
||||
|
||||
TestSetInline(s) ::= <<
|
||||
<s.ttypes:{ttype | <s.varName>==<ttype>}; separator=" || ">
|
||||
|
@ -396,32 +367,6 @@ cases(ttypes) ::= <<
|
|||
<ttypes:{t | case <t>:}; separator="\n">
|
||||
>>
|
||||
|
||||
MatchTree(t, root, down, leftActions, kids, rightActions, up) ::= <<
|
||||
// match tree
|
||||
<root>
|
||||
<leftActions>
|
||||
<if(t.isNullable)>
|
||||
if ( _input.LA(1)==Token.DOWN ) {
|
||||
<down>
|
||||
<kids; separator="\n">
|
||||
<up>
|
||||
}
|
||||
<else>
|
||||
<down>
|
||||
<kids; separator="\n">
|
||||
<up>
|
||||
<endif>
|
||||
<rightActions>
|
||||
>>
|
||||
|
||||
MatchDOWN(m) ::= <<
|
||||
setState(<m.stateNumber>); match(Token.DOWN);
|
||||
>>
|
||||
|
||||
MatchUP(m) ::= <<
|
||||
setState(<m.stateNumber>); match(Token.UP);
|
||||
>>
|
||||
|
||||
InvokeRule(r, argExprsChunks) ::= <<
|
||||
setState(<r.stateNumber>); <if(r.labels)><r.labels:{l | <labelref(l)> = }><endif><r.name>(<argExprsChunks>);
|
||||
>>
|
||||
|
@ -462,18 +407,7 @@ 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()>>"
|
||||
|
||||
ActionText(t) ::= "<t.text>"
|
||||
ArgRef(a) ::= "_localctx.<a.name>"
|
||||
|
@ -488,7 +422,6 @@ SetAttr(s,rhsChunks) ::= "_localctx.<s.name> = <rhsChunks>;"
|
|||
LexerSetAttr(s,rhsChunks) ::= "<s.name> = <rhsChunks>;"
|
||||
//SetQAttr(s,rhsChunks) ::= "<s.dict>.<s.name> = <rhsChunks>;"
|
||||
|
||||
ASTLabelType() ::= "<file.ASTLabelType; null={Object}>"
|
||||
TokenLabelType() ::= "<file.TokenLabelType; null={Token}>"
|
||||
InputSymbolType() ::= "<file.InputSymbolType; null={Token}>"
|
||||
|
||||
|
@ -498,32 +431,18 @@ TokenPropertyRef_line(t) ::= "(_localctx.<t.label>!=null?_localctx.<t.label>.get
|
|||
TokenPropertyRef_pos(t) ::= "(_localctx.<t.label>!=null?_localctx.<t.label>.getCharPositionInLine():0)"
|
||||
TokenPropertyRef_channel(t) ::= "(_localctx.<t.label>!=null?_localctx.<t.label>.getChannel():0)"
|
||||
TokenPropertyRef_index(t) ::= "(_localctx.<t.label>!=null?_localctx.<t.label>.getTokenIndex():0)"
|
||||
TokenPropertyRef_tree(t) ::= "_localctx.<t.label>_tree"
|
||||
TokenPropertyRef_int(t) ::= "(_localctx.<t.label>!=null?Integer.valueOf(_localctx.<t.label>.getText()):0)"
|
||||
|
||||
RulePropertyRef_start(r) ::= "(_localctx.<r.label>!=null?(_localctx.<r.label>.start):null)"
|
||||
RulePropertyRef_stop(r) ::= "(_localctx.<r.label>!=null?(_localctx.<r.label>.stop):null)"
|
||||
RulePropertyRef_tree(r) ::= "(_localctx.<r.label>!=null?(_localctx.<r.label>.tree):null)"
|
||||
RulePropertyRef_text(r) ::= "(_localctx.<r.label>!=null?_input.toString(_localctx.<r.label>.start,_localctx.<r.label>.stop):null)"
|
||||
RulePropertyRef_st(r) ::= "(_localctx.<r.label>!=null?_localctx.<r.label>.st:null)"
|
||||
RulePropertyRef_ctx(r) ::= "_localctx.<r.label>"
|
||||
|
||||
ThisRulePropertyRef_start(r) ::= "_localctx.start"
|
||||
ThisRulePropertyRef_stop(r) ::= "_localctx.stop"
|
||||
ThisRulePropertyRef_tree(r) ::= "_localctx.tree"
|
||||
ThisRulePropertyRef_text(r) ::= "_input.toString(_localctx.start, _input.LT(-1))"
|
||||
ThisRulePropertyRef_st(r) ::= "_localctx.st"
|
||||
ThisRulePropertyRef_ctx(r) ::= "_localctx"
|
||||
|
||||
/*
|
||||
TreeRulePropertyRef_text(r) ::= <%
|
||||
(_localctx.<r.label>!=null?
|
||||
((ASTNodeStream\<<ASTLabelType()>>)_input).toString(_localctx.<r.label>.start,_localctx.<r.label>.stop)
|
||||
:null
|
||||
)
|
||||
%>
|
||||
*/
|
||||
|
||||
NonLocalAttrRef(s) ::= "((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name>"
|
||||
SetNonLocalAttr(s, rhsChunks) ::=
|
||||
"((<s.ruleName>Context)getInvokingContext(<s.ruleIndex>)).<s.name> = <rhsChunks>;"
|
||||
|
@ -536,9 +455,6 @@ TokenListDecl(t) ::= "List\<Token> <t.name> = new ArrayList\<Token>();"
|
|||
RuleContextDecl(r) ::= "<r.ctxName> <r.name>;"
|
||||
RuleContextListDecl(rdecl) ::= "List\<<rdecl.ctxName>> <rdecl.name> = new ArrayList\<<rdecl.ctxName>>();"
|
||||
|
||||
NodeDecl(t) ::= "<ASTLabelType()> <t.name>;"
|
||||
NodeListDecl(t) ::= "List\<<ASTLabelType()>> <t.name> = new ArrayList\<<ASTLabelType()>>();"
|
||||
|
||||
/** Default RuleContext type name for a Parser rule */
|
||||
ParserRuleContext() ::= "ParserRuleContext\<?>"
|
||||
|
||||
|
@ -575,8 +491,6 @@ public static class <s.name> extends <superClass><if(interfaces)> implements <in
|
|||
}
|
||||
>>
|
||||
|
||||
TreeParserStructDecl ::= StructDecl
|
||||
|
||||
AltLabelStructDecl(s,attrs,visitorDispatchMethods) ::= <<
|
||||
public static class <s.label>Context extends <currentRule.name>Context {
|
||||
public <s.label>Context(<currentRule.name>Context ctx) { copyFrom(ctx); }
|
||||
|
@ -591,17 +505,6 @@ public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener\<<I
|
|||
}
|
||||
>>
|
||||
|
||||
/*
|
||||
SwitchedVisitorDispatchMethod(method) ::= <<
|
||||
public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener\<<InputSymbolType()>\> listener) {
|
||||
switch ( altNum ) {
|
||||
<method.listenerNames:{m |
|
||||
case <i> : ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif><m>(this); break;}; separator="\n">
|
||||
}
|
||||
}
|
||||
>>
|
||||
*/
|
||||
|
||||
AttributeDecl(d) ::= "<d.decl>"
|
||||
|
||||
/** If we don't know location of label def x, use this template */
|
||||
|
@ -614,112 +517,6 @@ recRuleAltPredicate(ruleName,opPrec) ::= "<opPrec> >= <recRuleArg()>"
|
|||
recRuleSetResultAction() ::= "$tree=$<ruleName>_primary.tree;"
|
||||
recRuleSetReturnAction(src,name) ::= "$<name>=$<src>.<name>;"
|
||||
|
||||
// AST stuff (TODO: separate?)
|
||||
|
||||
RootDecl(d) ::= "<ASTLabelType()> <d.name> = _adaptor.nil();"
|
||||
RootName(level) ::= "_root<level>"
|
||||
|
||||
TokenAST(t) ::= "_adaptor.create(<labelref(t.label)>)"
|
||||
RuleAST(r) ::= "<labelref(r.label)>.tree"
|
||||
AssignTreeResult(a) ::= "_localctx.tree = _root0;"
|
||||
RuleASTCleanup(r) ::= <<
|
||||
_localctx.tree = _adaptor.rulePostProcessing(_localctx.tree);
|
||||
_adaptor.setTokenBoundaries(_localctx.tree, _localctx.start, _localctx.stop);
|
||||
>>
|
||||
|
||||
ElementListDecl(d) ::= "List\<<ASTLabelType()>> <d.name> = _adaptor.createElementList();"
|
||||
ElementListName(elemName) ::= "_track_<elemName>"
|
||||
ClearElementList(c) ::= "<c.name>.clear();"
|
||||
TrackRuleElement(e) ::= "<e.name>.add(<labelref(e.label)>.tree);"
|
||||
TrackTokenElement(e) ::= "<e.name>.add(_adaptor.create(<labelref(e.label)>));"
|
||||
|
||||
// REWRITE AST stuff
|
||||
// assume roots are always locals in tree rewrites
|
||||
|
||||
TreeRewrite(tr, locals, preamble, alts) ::= <<
|
||||
// rewrite: code level= <tr.codeBlockLevel>, tree level = <tr.treeLevel>
|
||||
<locals; separator="\n">
|
||||
<preamble; separator="\n">
|
||||
<alts; separator="else\n">
|
||||
_localctx.tree = _root0;
|
||||
>>
|
||||
|
||||
RewriteChoice(c, predicate, ops) ::= <<
|
||||
<if(predicate)>
|
||||
if ( <predicate> ) {
|
||||
<ops; separator="\n">
|
||||
}
|
||||
<else>
|
||||
{
|
||||
<ops; separator="\n"> <! empty if EPSILON alt !>
|
||||
}
|
||||
<endif>
|
||||
>>
|
||||
|
||||
RewriteIteratorDecl(d) ::= "Iterator\<<ASTLabelType()>> <d.name>;"
|
||||
RewriteIteratorInit(i) ::= "<i.decl.name> = <i.decl.listName>.iterator();"
|
||||
RewriteIteratorName(elemName,level) ::= "it<level>_<elemName>"
|
||||
|
||||
RewriteTreeOptional(o, locals, preamble, ops) ::= <<
|
||||
// ? code level= <o.codeBlockLevel>, tree level = <o.treeLevel>
|
||||
{
|
||||
<locals; separator="\n">
|
||||
<preamble; separator="\n">
|
||||
if ( <o.conditionalDecls:{d | <d.name>.hasNext()}; separator=" || "> ) {
|
||||
<ops; separator="\n">
|
||||
}
|
||||
}
|
||||
>>
|
||||
|
||||
RewriteTreeClosure(c, locals, preamble, ops) ::= <<
|
||||
// * code level= <c.codeBlockLevel>, tree level = <c.treeLevel>
|
||||
{
|
||||
<locals; separator="\n">
|
||||
<preamble; separator="\n">
|
||||
while ( <c.iteratorDecls:{d | <d.name>.hasNext()}; separator=" || "> ) {
|
||||
<ops; separator="\n">
|
||||
}
|
||||
}
|
||||
>>
|
||||
|
||||
RewriteTreeStructure(t, locals, ops) ::= <<
|
||||
// TREE code level= <t.codeBlockLevel>, tree level = <t.treeLevel>
|
||||
{
|
||||
<locals; separator="\n">
|
||||
<ops; separator="\n">
|
||||
_adaptor.addChild(_root<t.enclosingTreeLevel>, _root<t.treeLevel>);
|
||||
}
|
||||
>>
|
||||
|
||||
RewriteTokenRef(t) ::= "<t.iterName>.next()"
|
||||
|
||||
RewriteImagTokenRef(t, argChunks) ::= <<
|
||||
_adaptor.create(<t.tokenType>, <if(argChunks)><argChunks><else>"<t.tokenType>"<endif>)
|
||||
>>
|
||||
|
||||
RewriteRuleRef(r) ::= "<r.iterName>.next()"
|
||||
|
||||
RewriteLabelRef(t) ::= "<t.iterName>.next()"
|
||||
|
||||
// -> $e in rule e
|
||||
RewriteSelfRuleLabelRef(s) ::= "_localctx.tree"
|
||||
|
||||
RewriteAction(a, chunks) ::= "<chunks>"
|
||||
|
||||
/** how to add child in rewrite section */
|
||||
AddChild(x, rootName, child) ::= "_adaptor.addChild(<x.rootName>, <child>);"
|
||||
|
||||
/** how to make something a new root in rewrite section */
|
||||
BecomeRoot(x, rootName, newRoot) ::=
|
||||
"<x.rootName> = _adaptor.becomeRoot(<newRoot>, <x.rootName>);"
|
||||
|
||||
|
||||
/*
|
||||
BitSetDecl(b) ::= <<
|
||||
public static final LABitSet <b.name>=new LABitSet(new long[]{<b.hexWords:{it|<it>L};separator=",">}<if(b.fset.EOF)>, true<endif>);
|
||||
>>
|
||||
*/
|
||||
|
||||
LexerFile(lexerFile, lexer, namedActions) ::= <<
|
||||
// $ANTLR ANTLRVersion> <lexerFile.fileName> generatedTimestamp>
|
||||
<namedActions.header>
|
||||
|
|
|
@ -34,7 +34,6 @@ import org.antlr.v4.analysis.AnalysisPipeline;
|
|||
import org.antlr.v4.automata.ATNFactory;
|
||||
import org.antlr.v4.automata.LexerATNFactory;
|
||||
import org.antlr.v4.automata.ParserATNFactory;
|
||||
import org.antlr.v4.automata.TreeParserATNFactory;
|
||||
import org.antlr.v4.codegen.CodeGenPipeline;
|
||||
import org.antlr.v4.parse.ANTLRLexer;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
|
@ -88,6 +87,7 @@ public class Tool {
|
|||
public boolean profile = false;
|
||||
public boolean trace = false;
|
||||
public boolean generate_ATN_dot = false;
|
||||
public String grammarEncoding = null; // use default locale's encoding
|
||||
public String msgFormat = "antlr";
|
||||
public boolean saveLexer = false;
|
||||
public boolean genListener = true;
|
||||
|
@ -105,6 +105,7 @@ public class Tool {
|
|||
new Option("profile", "-profile", "generate a parser that computes profiling information"),
|
||||
new Option("trace", "-trace", "generate a recognizer that traces rule entry/exit"),
|
||||
new Option("generate_ATN_dot", "-atn", "generate rule augmented transition networks"),
|
||||
new Option("grammarEncoding", "-encoding", OptionArgType.STRING, "specify grammar file encoding; e.g., euc-jp"),
|
||||
new Option("msgFormat", "-message-format", OptionArgType.STRING, "specify output style for messages"),
|
||||
new Option("genListener", "-walker", "generate parse tree walker and listener"),
|
||||
new Option("saveLexer", "-Xsave-lexer", "save temp lexer file created for combined grammars"),
|
||||
|
@ -299,7 +300,6 @@ public class Tool {
|
|||
// BUILD ATN FROM AST
|
||||
ATNFactory factory;
|
||||
if ( g.isLexer() ) factory = new LexerATNFactory((LexerGrammar)g);
|
||||
else if ( g.isTreeGrammar() ) factory = new TreeParserATNFactory(g);
|
||||
else factory = new ParserATNFactory(g);
|
||||
g.atn = factory.createATN();
|
||||
|
||||
|
@ -338,7 +338,7 @@ public class Tool {
|
|||
|
||||
public GrammarRootAST loadGrammar(String fileName) {
|
||||
try {
|
||||
ANTLRFileStream in = new ANTLRFileStream(fileName);
|
||||
ANTLRFileStream in = new ANTLRFileStream(fileName, grammarEncoding);
|
||||
GrammarRootAST t = load(in);
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
[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.automata;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.TreePatternAST;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Build ATNs for tree grammars */
|
||||
public class TreeParserATNFactory extends ParserATNFactory {
|
||||
// track stuff for ^(...) patterns in grammar to fix up nullable after ATN build
|
||||
List<TreePatternAST> treePatternRootNodes = new ArrayList<TreePatternAST>();
|
||||
List<ATNState> firstChildStates = new ArrayList<ATNState>();
|
||||
List<ATNState> downStates = new ArrayList<ATNState>();
|
||||
List<ATNState> upTargetStates = new ArrayList<ATNState>();
|
||||
|
||||
public TreeParserATNFactory(Grammar g) {
|
||||
super(g);
|
||||
}
|
||||
|
||||
public ATN createATN() {
|
||||
super.createATN();
|
||||
|
||||
for (int i=0; i<firstChildStates.size(); i++) {
|
||||
ATNState firstChild = firstChildStates.get(i);
|
||||
LL1Analyzer analyzer = new LL1Analyzer(atn);
|
||||
IntervalSet look = analyzer.LOOK(firstChild, ParserRuleContext.EMPTY);
|
||||
if ( look.contains(Token.UP) ) {
|
||||
// nullable child list if we can see the UP as the next token.
|
||||
// convert r DN kids UP to r (DN kids UP)?; leave AST alone--
|
||||
// that drives code gen. This just affects analysis
|
||||
epsilon(downStates.get(i), upTargetStates.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
return atn;
|
||||
}
|
||||
|
||||
/** x y z from ^(x y z) becomes o-x->o-DOWN->o-y->o-z->o-UP->o
|
||||
* ANTLRParser.g has added DOWN_TOKEN, UP_TOKEN into AST.
|
||||
* Elems are [root, DOWN_TOKEN, x, y, UP_TOKEN]
|
||||
*/
|
||||
public Handle tree(GrammarAST node, List<Handle> els) {
|
||||
TreePatternAST root = (TreePatternAST) node;
|
||||
|
||||
Handle h = elemList(els);
|
||||
treePatternRootNodes.add(root);
|
||||
// find DOWN node then first child
|
||||
for (Handle elh : els) {
|
||||
Transition trans = elh.left.transition(0);
|
||||
if ( !trans.isEpsilon() && trans.label().contains(Token.DOWN) ) {
|
||||
ATNState downState = elh.left;
|
||||
downStates.add(downState);
|
||||
root.downState = downState;
|
||||
firstChildStates.add(downState.transition(0).target);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// find UP node
|
||||
for (Handle elh : els) {
|
||||
Transition trans = elh.left.transition(0);
|
||||
if ( trans instanceof AtomTransition && trans.label().contains(Token.UP) ) {
|
||||
ATNState upTargetState = elh.right;
|
||||
root.upState = elh.left;
|
||||
upTargetStates.add(upTargetState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
}
|
|
@ -52,18 +52,14 @@ public class ActionTranslator implements ActionSplitterListener {
|
|||
public static final Map<String, Class> thisRulePropToModelMap = new HashMap<String, Class>() {{
|
||||
put("start", ThisRulePropertyRef_start.class);
|
||||
put("stop", ThisRulePropertyRef_stop.class);
|
||||
put("tree", ThisRulePropertyRef_tree.class);
|
||||
put("text", ThisRulePropertyRef_text.class);
|
||||
put("st", ThisRulePropertyRef_st.class);
|
||||
put("ctx", ThisRulePropertyRef_ctx.class);
|
||||
}};
|
||||
|
||||
public static final Map<String, Class> rulePropToModelMap = new HashMap<String, Class>() {{
|
||||
put("start", RulePropertyRef_start.class);
|
||||
put("stop", RulePropertyRef_stop.class);
|
||||
put("tree", RulePropertyRef_tree.class);
|
||||
put("text", RulePropertyRef_text.class);
|
||||
put("st", RulePropertyRef_st.class);
|
||||
put("ctx", RulePropertyRef_ctx.class);
|
||||
}};
|
||||
|
||||
|
@ -76,7 +72,6 @@ public class ActionTranslator implements ActionSplitterListener {
|
|||
put("index", TokenPropertyRef_index.class);
|
||||
put("pos", TokenPropertyRef_pos.class);
|
||||
put("channel", TokenPropertyRef_channel.class);
|
||||
put("tree", TokenPropertyRef_tree.class);
|
||||
put("int", TokenPropertyRef_int.class);
|
||||
}};
|
||||
|
||||
|
@ -288,9 +283,7 @@ public class ActionTranslator implements ActionSplitterListener {
|
|||
RulePropertyRef getRulePropertyRef(Token x, Token prop) {
|
||||
Grammar g = factory.getGrammar();
|
||||
try {
|
||||
Class c = g.isTreeGrammar() ?
|
||||
treeRulePropToModelMap.get(prop.getText()) :
|
||||
rulePropToModelMap.get(prop.getText());
|
||||
Class c = rulePropToModelMap.get(prop.getText());
|
||||
Constructor ctor = c.getConstructor(new Class[] {String.class});
|
||||
RulePropertyRef ref =
|
||||
(RulePropertyRef)ctor.newInstance(getRuleLabel(x.getText()));
|
||||
|
|
|
@ -30,14 +30,11 @@
|
|||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.BlockAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.PredAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -62,13 +59,15 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory {
|
|||
|
||||
public CodeBlockForAlt epsilon() { return null; }
|
||||
|
||||
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args, GrammarAST astOp) { return null; }
|
||||
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) { return null; }
|
||||
|
||||
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args, GrammarAST astOp) { return null; }
|
||||
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) { return null; }
|
||||
|
||||
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label, GrammarAST astOp) { return tokenRef(ID, label, null, astOp); }
|
||||
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label) { return tokenRef(ID, label, null); }
|
||||
|
||||
public List<SrcOp> set(GrammarAST setAST, GrammarAST label, GrammarAST astOp, boolean invert) { return null; }
|
||||
public List<SrcOp> set(GrammarAST setAST, GrammarAST label, boolean invert) { return null; }
|
||||
|
||||
public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST) { return null; }
|
||||
|
||||
// ACTIONS
|
||||
|
||||
|
@ -78,40 +77,6 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory {
|
|||
|
||||
public List<SrcOp> sempred(GrammarAST ast) { return null; }
|
||||
|
||||
// AST OPS
|
||||
|
||||
public List<SrcOp> rootToken(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rootRule(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST, GrammarAST astOp) { return null; }
|
||||
|
||||
// AST REWRITES
|
||||
|
||||
public TreeRewrite treeRewrite(GrammarAST ast) { return null; }
|
||||
|
||||
public RewriteChoice rewrite_choice(PredAST pred, List<SrcOp> ops) { return null; }
|
||||
|
||||
public RewriteTreeOptional rewrite_optional(GrammarAST ast) { return null; }
|
||||
|
||||
public RewriteTreeClosure rewrite_closure(GrammarAST ast) { return null; }
|
||||
|
||||
public RewriteTreeStructure rewrite_treeStructure(GrammarAST root) { return null; }
|
||||
|
||||
public List<SrcOp> rewrite_ruleRef(GrammarAST ID, boolean isRoot) { return null; }
|
||||
|
||||
public List<SrcOp> rewrite_tokenRef(GrammarAST ID, boolean isRoot, ActionAST argAST) { return null; }
|
||||
|
||||
public List<SrcOp> rewrite_stringRef(GrammarAST ID, boolean isRoot) {
|
||||
return rewrite_tokenRef(ID, isRoot, null);
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot) { return null; }
|
||||
|
||||
public List<SrcOp> rewrite_action(ActionAST action, boolean isRoot) { return null; }
|
||||
|
||||
public List<SrcOp> rewrite_epsilon(GrammarAST epsilon) { return null; }
|
||||
|
||||
// BLOCKS
|
||||
|
||||
public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts, GrammarAST label) { return null; }
|
||||
|
|
|
@ -44,9 +44,6 @@ public class CodeGenPipeline {
|
|||
if ( g.isLexer() ) {
|
||||
gen.writeRecognizer(gen.generateLexer());
|
||||
}
|
||||
else if ( g.isTreeGrammar() ) {
|
||||
gen.writeRecognizer(gen.generateTreeParser());
|
||||
}
|
||||
else {
|
||||
gen.writeRecognizer(gen.generateParser());
|
||||
if ( g.tool.genListener) {
|
||||
|
|
|
@ -116,21 +116,6 @@ public class CodeGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
// public void buildOutputModel() {
|
||||
// OutputModelFactory factory;
|
||||
// if ( g.isLexer() ) factory = new LexerFactory(this);
|
||||
// else factory = new ParserFactory(this);
|
||||
// // CREATE OUTPUT MODEL FROM GRAMMAR OBJ AND AST WITHIN RULES
|
||||
// OutputModelController controller = new OutputModelController(factory);
|
||||
// if ( g.hasASTOption() ) {
|
||||
// controller.addExtension( new ParserASTExtension(factory) );
|
||||
// }
|
||||
// factory.setController(controller);
|
||||
//
|
||||
// if ( g.isLexer() ) outputModel = controller.buildLexerOutputModel();
|
||||
// else outputModel = controller.buildParserOutputModel();
|
||||
// }
|
||||
|
||||
// CREATE TEMPLATES BY WALKING MODEL
|
||||
public ST generateLexer() {
|
||||
OutputModelFactory factory = new LexerFactory(this);
|
||||
|
@ -160,9 +145,6 @@ public class CodeGenerator {
|
|||
|
||||
// CREATE OUTPUT MODEL FROM GRAMMAR OBJ AND AST WITHIN RULES
|
||||
OutputModelController controller = new OutputModelController(factory);
|
||||
if ( g.hasASTOption() ) {
|
||||
controller.addExtension( new ParserASTExtension(factory) );
|
||||
}
|
||||
factory.setController(controller);
|
||||
|
||||
OutputModelObject outputModel = controller.buildParserOutputModel();
|
||||
|
@ -178,29 +160,6 @@ public class CodeGenerator {
|
|||
return st;
|
||||
}
|
||||
|
||||
public ST generateTreeParser() {
|
||||
OutputModelFactory factory = new TreeParserFactory(this);
|
||||
|
||||
// CREATE OUTPUT MODEL FROM GRAMMAR OBJ AND AST WITHIN RULES
|
||||
OutputModelController controller = new OutputModelController(factory);
|
||||
if ( g.hasASTOption() ) {
|
||||
controller.addExtension( new ParserASTExtension(factory) );
|
||||
}
|
||||
factory.setController(controller);
|
||||
|
||||
OutputModelObject outputModel = controller.buildTreeParserOutputModel();
|
||||
|
||||
OutputModelWalker walker = new OutputModelWalker(tool, templates);
|
||||
ST st = walker.walk(outputModel);
|
||||
|
||||
if ( tool.launch_ST_inspector ) {
|
||||
st.inspect();
|
||||
//if ( templates.isDefined("headerFile") ) headerFileST.inspect();
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
public ST generateListener() {
|
||||
OutputModelFactory factory = new ParserFactory(this);
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ package org.antlr.v4.codegen;
|
|||
|
||||
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -52,10 +51,6 @@ public class CodeGeneratorExtension {
|
|||
|
||||
public Lexer lexer(Lexer l) { return l; }
|
||||
|
||||
public TreeParserFile treeParserFile(TreeParserFile f) { return f; }
|
||||
|
||||
public TreeParserModel treeParser(TreeParserModel p) { return p; }
|
||||
|
||||
public RuleFunction rule(RuleFunction rf) { return rf; }
|
||||
|
||||
public List<SrcOp> rulePostamble(List<SrcOp> ops) { return ops; }
|
||||
|
@ -76,36 +71,12 @@ public class CodeGeneratorExtension {
|
|||
|
||||
public List<SrcOp> wildcard(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public MatchTree tree(MatchTree matchTree) { return matchTree; }
|
||||
|
||||
// ACTIONS
|
||||
|
||||
public List<SrcOp> action(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> sempred(List<SrcOp> ops) { return ops; }
|
||||
|
||||
// AST OPS
|
||||
|
||||
public List<SrcOp> rootRule(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> leafRule(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rootToken(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> leafToken(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rootString(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> leafString(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rootSet(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> leafSet(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rootWildcard(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> leafWildcard(List<SrcOp> ops) { return ops; }
|
||||
|
||||
// BLOCKS
|
||||
|
||||
public Choice getChoiceBlock(Choice c) { return c; }
|
||||
|
@ -113,28 +84,4 @@ public class CodeGeneratorExtension {
|
|||
public Choice getEBNFBlock(Choice c) { return c; }
|
||||
|
||||
public boolean needsImplicitLabel(GrammarAST ID, LabeledOp op) { return false; }
|
||||
|
||||
// AST REWRITEs
|
||||
|
||||
public TreeRewrite treeRewrite(TreeRewrite r) { return r; }
|
||||
|
||||
public RewriteChoice rewrite_choice(RewriteChoice r) { return r; }
|
||||
|
||||
public RewriteTreeOptional rewrite_optional(RewriteTreeOptional o) { return o; }
|
||||
|
||||
public RewriteTreeClosure rewrite_closure(RewriteTreeClosure c) { return c; }
|
||||
|
||||
public RewriteTreeStructure rewrite_treeStructure(RewriteTreeStructure t) { return t; }
|
||||
|
||||
public List<SrcOp> rewrite_ruleRef(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rewrite_tokenRef(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rewrite_stringRef(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rewrite_labelRef(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rewrite_action(List<SrcOp> ops) { return ops; }
|
||||
|
||||
public List<SrcOp> rewrite_epsilon(List<SrcOp> ops) { return ops; }
|
||||
}
|
||||
|
|
|
@ -29,14 +29,15 @@
|
|||
|
||||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.OutputModelObject;
|
||||
import org.antlr.v4.codegen.model.RuleFunction;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -94,21 +95,6 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory
|
|||
@Override
|
||||
public int getTreeLevel() { return controller.treeLevel; }
|
||||
|
||||
@Override
|
||||
public TreeParserFile treeParserFile(String fileName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeParserModel treeParser(TreeParserFile file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MatchTree tree(GrammarAST treeBeginAST, List<? extends SrcOp> omos) {
|
||||
throw new UnsupportedOperationException("^(...) in non-tree grammar");
|
||||
}
|
||||
|
||||
// MISC
|
||||
|
||||
@NotNull
|
||||
|
|
|
@ -31,7 +31,6 @@ package org.antlr.v4.codegen;
|
|||
|
||||
import org.antlr.runtime.tree.CommonTreeNodeStream;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||
|
@ -111,21 +110,6 @@ public class OutputModelController {
|
|||
return file;
|
||||
}
|
||||
|
||||
public OutputModelObject buildTreeParserOutputModel() {
|
||||
Grammar g = delegate.getGrammar();
|
||||
CodeGenerator gen = delegate.getGenerator();
|
||||
TreeParserFile file = treeParserFile(gen.getRecognizerFileName());
|
||||
setRoot(file);
|
||||
Parser parser = treeParser(file);
|
||||
file.parser = parser;
|
||||
|
||||
for (Rule r : g.rules.values()) {
|
||||
buildRuleFunction(parser, r);
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
public OutputModelObject buildListenerOutputModel() {
|
||||
CodeGenerator gen = delegate.getGenerator();
|
||||
return new ListenerFile(delegate, gen.getListenerFileName());
|
||||
|
@ -156,18 +140,6 @@ public class OutputModelController {
|
|||
return new Lexer(delegate, file);
|
||||
}
|
||||
|
||||
public TreeParserFile treeParserFile(String fileName) {
|
||||
TreeParserFile f = delegate.treeParserFile(fileName);
|
||||
for (CodeGeneratorExtension ext : extensions) f = ext.treeParserFile(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
public TreeParserModel treeParser(TreeParserFile file) {
|
||||
TreeParserModel p = delegate.treeParser(file);
|
||||
for (CodeGeneratorExtension ext : extensions) p = ext.treeParser(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Create RuleFunction per rule and update sempreds,actions of parser
|
||||
* output object with stuff found in r.
|
||||
*/
|
||||
|
@ -183,7 +155,8 @@ public class OutputModelController {
|
|||
CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk);
|
||||
walker = new SourceGenTriggers(nodes, this);
|
||||
try {
|
||||
function.code = DefaultOutputModelFactory.list(walker.block(null, null, null)); // walk AST of rule alts/elements
|
||||
// walk AST of rule alts/elements
|
||||
function.code = DefaultOutputModelFactory.list(walker.block(null, null));
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace(System.err);
|
||||
|
@ -284,64 +257,36 @@ public class OutputModelController {
|
|||
return blk;
|
||||
}
|
||||
|
||||
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args,
|
||||
GrammarAST astOp)
|
||||
{
|
||||
List<SrcOp> ops = delegate.ruleRef(ID, label, args, astOp);
|
||||
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
|
||||
List<SrcOp> ops = delegate.ruleRef(ID, label, args);
|
||||
for (CodeGeneratorExtension ext : extensions) {
|
||||
ops = ext.ruleRef(ops);
|
||||
if ( astOp!=null && astOp.getType()==ANTLRParser.ROOT ) {
|
||||
ops = ext.rootRule(ops);
|
||||
}
|
||||
else if ( astOp==null ) {
|
||||
ops = ext.leafRule(ops);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args,
|
||||
GrammarAST astOp)
|
||||
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args)
|
||||
{
|
||||
List<SrcOp> ops = delegate.tokenRef(ID, label, args, astOp);
|
||||
List<SrcOp> ops = delegate.tokenRef(ID, label, args);
|
||||
for (CodeGeneratorExtension ext : extensions) {
|
||||
ops = ext.tokenRef(ops);
|
||||
if ( astOp!=null && astOp.getType()==ANTLRParser.ROOT ) {
|
||||
ops = ext.rootToken(ops);
|
||||
}
|
||||
else if ( astOp==null ) {
|
||||
ops = ext.leafToken(ops);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label, GrammarAST astOp) {
|
||||
List<SrcOp> ops = delegate.stringRef(ID, label, astOp);
|
||||
public List<SrcOp> stringRef(GrammarAST ID, GrammarAST label) {
|
||||
List<SrcOp> ops = delegate.stringRef(ID, label);
|
||||
for (CodeGeneratorExtension ext : extensions) {
|
||||
ops = ext.stringRef(ops);
|
||||
if ( astOp!=null && astOp.getType()==ANTLRParser.ROOT ) {
|
||||
ops = ext.rootString(ops);
|
||||
}
|
||||
else if ( astOp==null ) {
|
||||
ops = ext.leafString(ops);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
/** (A|B|C) possibly with ebnfRoot and label */
|
||||
public List<SrcOp> set(GrammarAST setAST, GrammarAST labelAST,
|
||||
GrammarAST astOp, boolean invert) {
|
||||
List<SrcOp> ops = delegate.set(setAST, labelAST, astOp, invert);
|
||||
public List<SrcOp> set(GrammarAST setAST, GrammarAST labelAST, boolean invert) {
|
||||
List<SrcOp> ops = delegate.set(setAST, labelAST, invert);
|
||||
for (CodeGeneratorExtension ext : extensions) {
|
||||
ops = ext.set(ops);
|
||||
if ( astOp!=null && astOp.getType()==ANTLRParser.ROOT ) {
|
||||
ops = ext.rootSet(ops);
|
||||
}
|
||||
else if ( astOp==null ) {
|
||||
ops = ext.leafSet(ops);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
@ -352,6 +297,14 @@ public class OutputModelController {
|
|||
return blk;
|
||||
}
|
||||
|
||||
public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST) {
|
||||
List<SrcOp> ops = delegate.wildcard(ast, labelAST);
|
||||
for (CodeGeneratorExtension ext : extensions) {
|
||||
ops = ext.set(ops);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> action(GrammarAST ast) {
|
||||
List<SrcOp> ops = delegate.action(ast);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.action(ops);
|
||||
|
@ -364,26 +317,6 @@ public class OutputModelController {
|
|||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST, GrammarAST astOp) {
|
||||
List<SrcOp> ops = delegate.wildcard(ast, labelAST, astOp);
|
||||
for (CodeGeneratorExtension ext : extensions) {
|
||||
ops = ext.set(ops);
|
||||
if ( astOp!=null && astOp.getType()==ANTLRParser.ROOT ) {
|
||||
ops = ext.rootWildcard(ops);
|
||||
}
|
||||
else if ( astOp==null ) {
|
||||
ops = ext.leafWildcard(ops);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public MatchTree tree(GrammarAST treeBeginAST, List<? extends SrcOp> omos) {
|
||||
MatchTree matchTree = delegate.tree(treeBeginAST, omos);
|
||||
for (CodeGeneratorExtension ext : extensions) matchTree = ext.tree(matchTree);
|
||||
return matchTree;
|
||||
}
|
||||
|
||||
public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts, GrammarAST label) {
|
||||
Choice c = delegate.getChoiceBlock(blkAST, alts, label);
|
||||
for (CodeGeneratorExtension ext : extensions) c = ext.getChoiceBlock(c);
|
||||
|
@ -402,72 +335,6 @@ public class OutputModelController {
|
|||
return needs;
|
||||
}
|
||||
|
||||
// REWRITES
|
||||
|
||||
public TreeRewrite treeRewrite(GrammarAST ast) {
|
||||
TreeRewrite r = delegate.treeRewrite(ast);
|
||||
for (CodeGeneratorExtension ext : extensions) r = ext.treeRewrite(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public RewriteChoice rewrite_choice(PredAST pred, List<SrcOp> ops) {
|
||||
RewriteChoice r = delegate.rewrite_choice(pred, ops);
|
||||
for (CodeGeneratorExtension ext : extensions) r = ext.rewrite_choice(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public RewriteTreeOptional rewrite_optional(GrammarAST ast) {
|
||||
RewriteTreeOptional o = delegate.rewrite_optional(ast);
|
||||
for (CodeGeneratorExtension ext : extensions) o = ext.rewrite_optional(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
public RewriteTreeClosure rewrite_closure(GrammarAST ast) {
|
||||
RewriteTreeClosure c = delegate.rewrite_closure(ast);
|
||||
for (CodeGeneratorExtension ext : extensions) c = ext.rewrite_closure(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public RewriteTreeStructure rewrite_treeStructure(GrammarAST root) {
|
||||
RewriteTreeStructure t = delegate.rewrite_treeStructure(root);
|
||||
for (CodeGeneratorExtension ext : extensions) t = ext.rewrite_treeStructure(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_ruleRef(GrammarAST ID, boolean isRoot) {
|
||||
List<SrcOp> ops = delegate.rewrite_ruleRef(ID, isRoot);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.rewrite_ruleRef(ops);
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_tokenRef(GrammarAST ID, boolean isRoot, ActionAST argAST) {
|
||||
List<SrcOp> ops = delegate.rewrite_tokenRef(ID, isRoot, argAST);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.rewrite_tokenRef(ops);
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_stringRef(GrammarAST ID, boolean isRoot) {
|
||||
return rewrite_tokenRef(ID, isRoot, null);
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot) {
|
||||
List<SrcOp> ops = delegate.rewrite_labelRef(ID, isRoot);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.rewrite_labelRef(ops);
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_action(ActionAST action, boolean isRoot) {
|
||||
List<SrcOp> ops = delegate.rewrite_action(action, isRoot);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.rewrite_action(ops);
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_epsilon(GrammarAST epsilon) {
|
||||
List<SrcOp> ops = delegate.rewrite_epsilon(epsilon);
|
||||
for (CodeGeneratorExtension ext : extensions) ops = ext.rewrite_epsilon(ops);
|
||||
return ops;
|
||||
}
|
||||
|
||||
public OutputModelObject getRoot() { return root; }
|
||||
|
||||
public void setRoot(OutputModelObject root) { this.root = root; }
|
||||
|
|
|
@ -30,16 +30,13 @@
|
|||
package org.antlr.v4.codegen;
|
||||
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.BlockAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.PredAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -58,10 +55,6 @@ public interface OutputModelFactory {
|
|||
|
||||
Lexer lexer(LexerFile file);
|
||||
|
||||
TreeParserFile treeParserFile(String fileName);
|
||||
|
||||
TreeParserModel treeParser(TreeParserFile file);
|
||||
|
||||
RuleFunction rule(Rule r);
|
||||
|
||||
List<SrcOp> rulePostamble(RuleFunction function, Rule r);
|
||||
|
@ -74,13 +67,15 @@ public interface OutputModelFactory {
|
|||
|
||||
CodeBlockForAlt epsilon();
|
||||
|
||||
List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args, GrammarAST astOp);
|
||||
List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args);
|
||||
|
||||
List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args, GrammarAST astOp);
|
||||
List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args);
|
||||
|
||||
List<SrcOp> stringRef(GrammarAST ID, GrammarAST label, GrammarAST astOp);
|
||||
List<SrcOp> stringRef(GrammarAST ID, GrammarAST label);
|
||||
|
||||
List<SrcOp> set(GrammarAST setAST, GrammarAST label, GrammarAST astOp, boolean invert);
|
||||
List<SrcOp> set(GrammarAST setAST, GrammarAST label, boolean invert);
|
||||
|
||||
List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST);
|
||||
|
||||
List<SrcOp> action(GrammarAST ast);
|
||||
|
||||
|
@ -88,14 +83,6 @@ public interface OutputModelFactory {
|
|||
|
||||
List<SrcOp> sempred(GrammarAST ast);
|
||||
|
||||
List<SrcOp> rootToken(List<SrcOp> ops);
|
||||
|
||||
List<SrcOp> rootRule(List<SrcOp> ops);
|
||||
|
||||
List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST, GrammarAST astOp);
|
||||
|
||||
MatchTree tree(GrammarAST treeBeginAST, List<? extends SrcOp> omos);
|
||||
|
||||
Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts, GrammarAST label);
|
||||
|
||||
Choice getEBNFBlock(GrammarAST ebnfRoot, List<CodeBlockForAlt> alts);
|
||||
|
@ -112,32 +99,6 @@ public interface OutputModelFactory {
|
|||
|
||||
boolean needsImplicitLabel(GrammarAST ID, LabeledOp op);
|
||||
|
||||
// AST REWRITE TRIGGERS
|
||||
// Though dealing with ASTs, we must deal with here since these are
|
||||
// triggered from elements in ANTLR's internal GrammarAST
|
||||
|
||||
TreeRewrite treeRewrite(GrammarAST ast);
|
||||
|
||||
RewriteChoice rewrite_choice(PredAST pred, List<SrcOp> ops);
|
||||
|
||||
RewriteTreeOptional rewrite_optional(GrammarAST ast);
|
||||
|
||||
RewriteTreeClosure rewrite_closure(GrammarAST ast);
|
||||
|
||||
RewriteTreeStructure rewrite_treeStructure(GrammarAST root);
|
||||
|
||||
List<SrcOp> rewrite_ruleRef(GrammarAST ID, boolean isRoot);
|
||||
|
||||
List<SrcOp> rewrite_tokenRef(GrammarAST ID, boolean isRoot, ActionAST argAST);
|
||||
|
||||
List<SrcOp> rewrite_stringRef(GrammarAST ID, boolean isRoot);
|
||||
|
||||
List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot);
|
||||
|
||||
List<SrcOp> rewrite_action(ActionAST action, boolean isRoot);
|
||||
|
||||
List<SrcOp> rewrite_epsilon(GrammarAST epsilon);
|
||||
|
||||
// CONTEXT INFO
|
||||
|
||||
OutputModelObject getRoot();
|
||||
|
|
|
@ -1,278 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
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;
|
||||
|
||||
public class ParserASTExtension extends CodeGeneratorExtension {
|
||||
public ParserASTExtension(OutputModelFactory factory) {
|
||||
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();
|
||||
if ( alt.hasRewrite() && choice.label!=null ) {
|
||||
trackExplicitLabel(choice.preamble, choice.label, choice);
|
||||
}
|
||||
return choice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlockForAlt alternative(CodeBlockForAlt blk, boolean outerMost) {
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
if ( outerMost && !alt.hasRewrite() ) {
|
||||
blk.addLocalDecl(new RootDecl(factory, 0));
|
||||
}
|
||||
return blk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, boolean outerMost) {
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
if ( !alt.hasRewrite() ) blk.addOp(new AssignTreeResult(factory));
|
||||
return blk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rulePostamble(List<SrcOp> ops) {
|
||||
RuleASTCleanup cleanup = new RuleASTCleanup(factory);
|
||||
return DefaultOutputModelFactory.list(ops, cleanup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rootRule(List<SrcOp> ops) {
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
if ( alt.hasRewrite() ) {
|
||||
return ops;
|
||||
}
|
||||
else {
|
||||
InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class);
|
||||
SrcOp treeOp = new RuleAST(factory, invokeOp.ast, invokeOp.getLabels().get(0));
|
||||
String rootName = factory.getGenerator().target.getRootName(0);
|
||||
SrcOp add = new BecomeRoot(factory, rootName, treeOp);
|
||||
return DefaultOutputModelFactory.list(ops, add);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> leafRule(List<SrcOp> ops) {
|
||||
InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class);
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
if ( alt.hasRewrite() ) {
|
||||
return leafRuleInRewriteAlt(invokeOp, ops);
|
||||
}
|
||||
else {
|
||||
RuleContextDecl label = (RuleContextDecl)invokeOp.getLabels().get(0);
|
||||
SrcOp treeOp = new RuleAST(factory, invokeOp.ast, label);
|
||||
String rootName = factory.getGenerator().target.getRootName(0);
|
||||
SrcOp add = new AddChild(factory, rootName, treeOp);
|
||||
ops.add(add);
|
||||
return ops;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rootToken(List<SrcOp> ops) {
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
if ( alt.hasRewrite() ) {
|
||||
return ops;
|
||||
}
|
||||
else {
|
||||
MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class);
|
||||
SrcOp treeOp = new TokenAST(factory, matchOp.ast, matchOp.getLabels().get(0));
|
||||
String rootName = factory.getGenerator().target.getRootName(0);
|
||||
SrcOp add = new BecomeRoot(factory, rootName, treeOp);
|
||||
return DefaultOutputModelFactory.list(ops, add);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> leafToken(List<SrcOp> ops) {
|
||||
MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class);
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
if ( alt.hasRewrite() ) {
|
||||
return leafTokenInRewriteAlt(matchOp, ops);
|
||||
}
|
||||
else {
|
||||
TokenDecl label = (TokenDecl)matchOp.getLabels().get(0);
|
||||
SrcOp treeOp = new TokenAST(factory, matchOp.ast, label);
|
||||
String rootName = factory.getGenerator().target.getRootName(0);
|
||||
SrcOp add = new AddChild(factory, rootName, treeOp);
|
||||
ops.add(add);
|
||||
return ops;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rootString(List<SrcOp> ops) { return rootToken(ops); }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> leafString(List<SrcOp> ops) { return leafToken(ops); }
|
||||
|
||||
public List<SrcOp> leafRuleInRewriteAlt(InvokeRule invokeOp, List<SrcOp> ops) {
|
||||
RuleContextDecl label = (RuleContextDecl)invokeOp.getLabels().get(0);
|
||||
CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock();
|
||||
String elemListName = factory.getGenerator().target.getElementListName(invokeOp.ast.getText());
|
||||
blk.addLocalDecl(new ElementListDecl(factory, elemListName));
|
||||
|
||||
// add code to track rule results in _track_r
|
||||
String trackName = factory.getGenerator().target.getElementListName(invokeOp.ast.getText());
|
||||
TrackRuleElement t = new TrackRuleElement(factory, invokeOp.ast, trackName, label);
|
||||
ops.add(t);
|
||||
|
||||
// track any explicit label like _track_label but not implicit label
|
||||
if ( !label.isImplicit ) trackExplicitLabel(ops, label, invokeOp);
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
public List<SrcOp> leafTokenInRewriteAlt(SrcOp matchOp, List<SrcOp> ops) {
|
||||
CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock();
|
||||
TokenDecl label = (TokenDecl)((LabeledOp)matchOp).getLabels().get(0);
|
||||
// First declare tracking lists for elements, labels
|
||||
// track the named element like _track_A
|
||||
String elemName = matchOp.ast.getText();
|
||||
if ( matchOp.ast.getType()==ANTLRParser.SET ) {
|
||||
elemName = String.valueOf(matchOp.ast.token.getTokenIndex());
|
||||
}
|
||||
String elemListName = factory.getGenerator().target.getElementListName(elemName);
|
||||
blk.addLocalDecl(new ElementListDecl(factory, elemListName));
|
||||
// Now, generate track instructions for element and any labels
|
||||
// do element
|
||||
String trackName = factory.getGenerator().target.getElementListName(elemName);
|
||||
TrackTokenElement t = new TrackTokenElement(factory, matchOp.ast, trackName,
|
||||
label);
|
||||
ops.add(t);
|
||||
if ( !label.isImplicit ) trackExplicitLabel(ops, label, matchOp);
|
||||
return ops;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rootSet(List<SrcOp> ops) { return rootToken(ops); }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> leafSet(List<SrcOp> ops) { return leafToken(ops); }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> wildcard(List<SrcOp> ops) {
|
||||
Wildcard wild = (Wildcard)Utils.find(ops, Wildcard.class);
|
||||
Alternative alt = factory.getCurrentOuterMostAlt();
|
||||
if ( alt.hasRewrite() ) {
|
||||
TokenDecl label = (TokenDecl)((LabeledOp)wild).getLabels().get(0);
|
||||
if ( !label.isImplicit ) trackExplicitLabel(ops, label, wild);
|
||||
return ops;
|
||||
}
|
||||
else {
|
||||
TokenDecl label = (TokenDecl)wild.getLabels().get(0);
|
||||
SrcOp treeOp = new TokenAST(factory, wild.ast, label);
|
||||
String rootName = factory.getGenerator().target.getRootName(0);
|
||||
SrcOp add = new AddChild(factory, rootName, treeOp);
|
||||
ops.add(add);
|
||||
return ops;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rootWildcard(List<SrcOp> ops) { return rootToken(ops); }
|
||||
|
||||
@Override
|
||||
public List<SrcOp> leafWildcard(List<SrcOp> ops) { return leafToken(ops); }
|
||||
|
||||
public void trackExplicitLabel(List<SrcOp> ops, Decl label, SrcOp opWithLabel) {
|
||||
CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock();
|
||||
// declare _track_label
|
||||
String labelListName =
|
||||
factory.getGenerator().target.getElementListName(label.name);
|
||||
blk.addLocalDecl(new ElementListDecl(factory, labelListName));
|
||||
|
||||
// add elements to _track_label
|
||||
SrcOp trk;
|
||||
if ( opWithLabel instanceof InvokeRule ) {
|
||||
trk = new TrackRuleElement(factory, opWithLabel.ast, labelListName, label);
|
||||
}
|
||||
else if ( opWithLabel instanceof Choice ||
|
||||
opWithLabel instanceof MatchToken ||
|
||||
opWithLabel instanceof Wildcard )
|
||||
{
|
||||
trk = new TrackTokenElement(factory, opWithLabel.ast, labelListName, label);
|
||||
}
|
||||
else {
|
||||
trk = null;
|
||||
}
|
||||
clearTrackingIfSingularLabel(ops, opWithLabel, labelListName);
|
||||
ops.add(trk);
|
||||
}
|
||||
|
||||
public void clearTrackingIfSingularLabel(List<SrcOp> ops, SrcOp opWithLabel, String trackName) {
|
||||
if ( opWithLabel.ast.parent.getType() == ANTLRParser.ASSIGN ) {
|
||||
// if x=A must keep it a single-element list; clear before add
|
||||
ClearElementList c = new ClearElementList(factory, opWithLabel.ast, trackName);
|
||||
ops.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsImplicitLabel(GrammarAST ID, LabeledOp op) {
|
||||
return op.getLabels().size()==0 && factory.getGrammar().hasASTOption();
|
||||
}
|
||||
|
||||
// REWRITES
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2011 Terence Parr
|
||||
Copyright (c) 2012 Terence Parr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -31,17 +31,20 @@ package org.antlr.v4.codegen;
|
|||
|
||||
import org.antlr.v4.analysis.AnalysisPipeline;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.codegen.model.decl.RuleContextDecl;
|
||||
import org.antlr.v4.codegen.model.decl.TokenDecl;
|
||||
import org.antlr.v4.codegen.model.decl.TokenListDecl;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.runtime.atn.DecisionState;
|
||||
import org.antlr.v4.runtime.atn.PlusBlockStartState;
|
||||
import org.antlr.v4.runtime.atn.StarLoopEntryState;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.semantics.UseDefAnalyzer;
|
||||
import org.antlr.v4.tool.Alternative;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.antlr.v4.tool.ast.BlockAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.TerminalAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -80,20 +83,15 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
|||
|
||||
public List<SrcOp> sempred(GrammarAST ast) { return list(new SemPred(this, ast)); }
|
||||
|
||||
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args,
|
||||
GrammarAST astOp)
|
||||
{
|
||||
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
|
||||
InvokeRule invokeOp = new InvokeRule(this, ID, label);
|
||||
// If no manual label and action refs as token/rule not label or
|
||||
// we're adding to trees, we need to define implicit label
|
||||
// If no manual label and action refs as token/rule not label, we need to define implicit label
|
||||
if ( controller.needsImplicitLabel(ID, invokeOp) ) defineImplicitLabel(ID, invokeOp);
|
||||
AddToLabelList listLabelOp = getListLabelIfPresent(invokeOp, label);
|
||||
return list(invokeOp, listLabelOp);
|
||||
}
|
||||
|
||||
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST labelAST, GrammarAST args,
|
||||
GrammarAST astOp)
|
||||
{
|
||||
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST labelAST, GrammarAST args) {
|
||||
LabeledOp matchOp = new MatchToken(this, (TerminalAST) ID);
|
||||
if ( labelAST!=null ) {
|
||||
String label = labelAST.getText();
|
||||
|
@ -119,9 +117,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> set(GrammarAST setAST, GrammarAST labelAST,
|
||||
GrammarAST astOp, boolean invert)
|
||||
{
|
||||
public List<SrcOp> set(GrammarAST setAST, GrammarAST labelAST, boolean invert) {
|
||||
LabeledOp matchOp;
|
||||
if ( invert ) matchOp = new MatchNotSet(this, setAST);
|
||||
else matchOp = new MatchSet(this, setAST);
|
||||
|
@ -141,7 +137,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST, GrammarAST astOp) {
|
||||
public List<SrcOp> wildcard(GrammarAST ast, GrammarAST labelAST) {
|
||||
Wildcard wild = new Wildcard(this, ast);
|
||||
// TODO: dup with tokenRef
|
||||
if ( labelAST!=null ) {
|
||||
|
@ -263,128 +259,8 @@ public class ParserFactory extends DefaultOutputModelFactory {
|
|||
return op.getLabels().size()==0 && (actionRefsAsToken || actionRefsAsRule);
|
||||
}
|
||||
|
||||
// AST REWRITE
|
||||
|
||||
|
||||
@Override
|
||||
public TreeRewrite treeRewrite(GrammarAST ast) {
|
||||
TreeRewrite tr = new TreeRewrite(this, getTreeLevel(), getCodeBlockLevel());
|
||||
tr.addLocalDecl(new RootDecl(this, 0));
|
||||
List<GrammarAST> refs =
|
||||
UseDefAnalyzer.getElementReferencesShallowInOuterAlt(ast);
|
||||
refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs);
|
||||
if ( refs!=null ) {
|
||||
for (GrammarAST ref : refs) {
|
||||
RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel());
|
||||
tr.addLocalDecl(d);
|
||||
RewriteIteratorInit init = new RewriteIteratorInit(this, d);
|
||||
tr.addPreambleOp(init);
|
||||
}
|
||||
}
|
||||
return tr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RewriteChoice rewrite_choice(PredAST pred, List<SrcOp> ops) {
|
||||
RewriteAction predAction = null;
|
||||
if ( pred!=null ) predAction = new RewriteAction(this, pred);
|
||||
RewriteChoice c = new RewriteChoice(this, predAction, ops);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RewriteTreeOptional rewrite_optional(GrammarAST ast) {
|
||||
RewriteTreeOptional o =
|
||||
new RewriteTreeOptional(this, ast, getTreeLevel(), getCodeBlockLevel());
|
||||
List<GrammarAST> refs = UseDefAnalyzer.getElementReferencesInEBNF(ast, true);
|
||||
refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs);
|
||||
if ( refs!=null ) {
|
||||
for (GrammarAST ref : refs) {
|
||||
RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel());
|
||||
o.addLocalDecl(d);
|
||||
o.conditionalDecls.add(d);
|
||||
RewriteIteratorInit init = new RewriteIteratorInit(this, d);
|
||||
o.addPreambleOp(init);
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RewriteTreeClosure rewrite_closure(GrammarAST ast) {
|
||||
RewriteTreeClosure c =
|
||||
new RewriteTreeClosure(this, ast, getTreeLevel(), getCodeBlockLevel());
|
||||
List<GrammarAST> refs = UseDefAnalyzer.getElementReferencesInEBNF(ast, false);
|
||||
refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs);
|
||||
if ( refs!=null ) {
|
||||
for (GrammarAST ref : refs) {
|
||||
RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel());
|
||||
c.addLocalDecl(d);
|
||||
c.iteratorDecls.add(d);
|
||||
RewriteIteratorInit init = new RewriteIteratorInit(this, d);
|
||||
c.addPreambleOp(init);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RewriteTreeStructure rewrite_treeStructure(GrammarAST root) {
|
||||
RewriteTreeStructure t = new RewriteTreeStructure(this, root, getTreeLevel(), getCodeBlockLevel());
|
||||
t.addLocalDecl( new RootDecl(this, getTreeLevel()) );
|
||||
return t;
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_ruleRef(GrammarAST ID, boolean isRoot) {
|
||||
String iterName = gen.target.getRewriteIteratorName(ID, getCodeBlockLevel());
|
||||
RewriteRuleRef ruleRef = new RewriteRuleRef(this, ID, iterName);
|
||||
return list(makeChildOrRoot(ruleRef, isRoot));
|
||||
}
|
||||
|
||||
public List<SrcOp> rewrite_tokenRef(GrammarAST ID, boolean isRoot, ActionAST argAST) {
|
||||
Alternative alt = getCurrentOuterMostAlt();
|
||||
String iterName = gen.target.getRewriteIteratorName(ID, getCodeBlockLevel());
|
||||
// not ref'd on left hand side or it is but we have an argument like ID["x"]
|
||||
// implies create new node
|
||||
SrcOp tokenRef;
|
||||
if ( alt.tokenRefs.get(ID.getText())==null || argAST!=null ) {
|
||||
tokenRef = new RewriteImagTokenRef(this, ID, ID.getText(), argAST);
|
||||
}
|
||||
else { // must be token ref on left of ->
|
||||
tokenRef = new RewriteTokenRef(this, ID, iterName);
|
||||
}
|
||||
return list(makeChildOrRoot(tokenRef, isRoot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot) {
|
||||
String iterName = gen.target.getRewriteIteratorName(ID, getCodeBlockLevel());
|
||||
SrcOp labelRef;
|
||||
if ( ID.getText().equals(getCurrentRuleFunction().rule.name) ) { // $e in rule e
|
||||
labelRef = new RewriteSelfRuleLabelRef(this, ID);
|
||||
}
|
||||
else { // normal element label
|
||||
labelRef = new RewriteLabelRef(this, ID, iterName);
|
||||
}
|
||||
return list(makeChildOrRoot(labelRef, isRoot));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SrcOp> rewrite_action(ActionAST actionAST, boolean isRoot) {
|
||||
RewriteAction action = new RewriteAction(this, actionAST);
|
||||
return list(makeChildOrRoot(action, isRoot));
|
||||
}
|
||||
|
||||
// support
|
||||
|
||||
public SrcOp makeChildOrRoot(SrcOp elemToAdd, boolean isRoot) {
|
||||
String rootName = gen.target.getRootName(getTreeLevel());
|
||||
SrcOp op;
|
||||
if ( isRoot ) op = new BecomeRoot(this, rootName, elemToAdd);
|
||||
else op = new AddChild(this, rootName, elemToAdd);
|
||||
return op;
|
||||
}
|
||||
|
||||
public void defineImplicitLabel(GrammarAST ast, LabeledOp op) {
|
||||
Decl d;
|
||||
Rule r = g.getRule(ast.getText());
|
||||
|
|
|
@ -38,7 +38,6 @@ package org.antlr.v4.codegen;
|
|||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
import org.antlr.v4.codegen.model.ast.*;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import java.util.Collections;
|
||||
|
@ -54,9 +53,9 @@ import java.util.HashMap;
|
|||
}
|
||||
}
|
||||
|
||||
dummy : block[null, null, null] ;
|
||||
dummy : block[null, null] ;
|
||||
|
||||
block[GrammarAST label, GrammarAST ebnfRoot, GrammarAST astOp] returns [List<? extends SrcOp> omos]
|
||||
block[GrammarAST label, GrammarAST ebnfRoot] returns [List<? extends SrcOp> omos]
|
||||
: ^( blk=BLOCK (^(OPTIONS .+))?
|
||||
{List<CodeBlockForAlt> alts = new ArrayList<CodeBlockForAlt>();}
|
||||
( alternative {alts.add($alternative.altCodeBlock);} )+
|
||||
|
@ -79,14 +78,7 @@ alternative returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
|
|||
@after {
|
||||
controller.finishAlternative($altCodeBlock, $ops, outerMost);
|
||||
}
|
||||
: ^(ALT_REWRITE
|
||||
a=alt[outerMost]
|
||||
( rewrite {$a.ops.add($rewrite.code);} // insert at end of alt's code
|
||||
|
|
||||
)
|
||||
{$altCodeBlock=$a.altCodeBlock; $ops=$a.ops;}
|
||||
)
|
||||
| a=alt[outerMost] {$altCodeBlock=$a.altCodeBlock; $ops=$a.ops;}
|
||||
: a=alt[outerMost] {$altCodeBlock=$a.altCodeBlock; $ops=$a.ops;}
|
||||
;
|
||||
|
||||
alt[boolean outerMost] returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
|
||||
|
@ -105,40 +97,28 @@ alt[boolean outerMost] returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
|
|||
|
||||
element returns [List<? extends SrcOp> omos]
|
||||
: labeledElement {$omos = $labeledElement.omos;}
|
||||
| atom[null,null,false] {$omos = $atom.omos;}
|
||||
| atom[null,false] {$omos = $atom.omos;}
|
||||
| subrule {$omos = $subrule.omos;}
|
||||
| ACTION {$omos = controller.action($ACTION);}
|
||||
| SEMPRED {$omos = controller.sempred($SEMPRED);}
|
||||
| ^(ACTION elementOptions) {$omos = controller.action($ACTION);}
|
||||
| ^(SEMPRED elementOptions) {$omos = controller.sempred($SEMPRED);}
|
||||
| treeSpec {$omos = DefaultOutputModelFactory.list($treeSpec.treeMatch);}
|
||||
;
|
||||
|
||||
labeledElement returns [List<? extends SrcOp> omos]
|
||||
: ^(ASSIGN ID atom[$ID,null,false] ) {$omos = $atom.omos;}
|
||||
| ^(PLUS_ASSIGN ID atom[$ID,null,false]) {$omos = $atom.omos;}
|
||||
| ^(ASSIGN ID block[$ID,null,null] ) {$omos = $block.omos;}
|
||||
| ^(PLUS_ASSIGN ID block[$ID,null,null]) {$omos = $block.omos;}
|
||||
;
|
||||
|
||||
treeSpec returns [MatchTree treeMatch]
|
||||
@init {
|
||||
List<SrcOp> elems = new ArrayList<SrcOp>();
|
||||
}
|
||||
: ^(TREE_BEGIN
|
||||
(e=element {if ($e.omos!=null) elems.addAll($e.omos);})+
|
||||
)
|
||||
{$treeMatch = controller.tree($TREE_BEGIN, elems);}
|
||||
: ^(ASSIGN ID atom[$ID,false] ) {$omos = $atom.omos;}
|
||||
| ^(PLUS_ASSIGN ID atom[$ID,false]) {$omos = $atom.omos;}
|
||||
| ^(ASSIGN ID block[$ID,null] ) {$omos = $block.omos;}
|
||||
| ^(PLUS_ASSIGN ID block[$ID,null]) {$omos = $block.omos;}
|
||||
;
|
||||
|
||||
subrule returns [List<? extends SrcOp> omos]
|
||||
: ^(astBlockSuffix block[null,null,$astBlockSuffix.start]) {$omos = $block.omos;}
|
||||
| ^(OPTIONAL b=block[null,$OPTIONAL,null])
|
||||
: ^(OPTIONAL b=block[null,$OPTIONAL])
|
||||
{
|
||||
$omos = $block.omos;
|
||||
}
|
||||
| ( ^(op=CLOSURE b=block[null,null,null])
|
||||
| ^(op=POSITIVE_CLOSURE b=block[null,null,null])
|
||||
| ( ^(op=CLOSURE b=block[null,null])
|
||||
| ^(op=POSITIVE_CLOSURE b=block[null,null])
|
||||
)
|
||||
{
|
||||
List<CodeBlockForAlt> alts = new ArrayList<CodeBlockForAlt>();
|
||||
|
@ -149,17 +129,11 @@ subrule returns [List<? extends SrcOp> omos]
|
|||
SrcOp loop = controller.getEBNFBlock($op, alts); // "star it"
|
||||
$omos = DefaultOutputModelFactory.list(loop);
|
||||
}
|
||||
| block[null, null,null] {$omos = $block.omos;}
|
||||
| block[null, null] {$omos = $block.omos;}
|
||||
;
|
||||
|
||||
astBlockSuffix
|
||||
: ROOT
|
||||
| IMPLIES
|
||||
| BANG
|
||||
;
|
||||
|
||||
blockSet[GrammarAST label, GrammarAST astOp, boolean invert] returns [List<SrcOp> omos]
|
||||
: ^(SET atom[null,null,false]+) {$omos = controller.set($SET, $label, $astOp, invert);}
|
||||
blockSet[GrammarAST label, boolean invert] returns [List<SrcOp> omos]
|
||||
: ^(SET atom[label,invert]+) {$omos = controller.set($SET, $label, invert);}
|
||||
;
|
||||
|
||||
/*
|
||||
|
@ -172,35 +146,32 @@ setElement
|
|||
|
||||
// TODO: combine ROOT/BANG into one then just make new op ref'ing return value of atom/terminal...
|
||||
// TODO: same for NOT
|
||||
atom[GrammarAST label, GrammarAST astOp, boolean invert] returns [List<SrcOp> omos]
|
||||
: ^(op=(ROOT|BANG) a=atom[$label, $op, $invert] ) {$omos = $a.omos;}
|
||||
| ^(NOT a=atom[$label, $astOp, true]) {$omos = $a.omos;}
|
||||
atom[GrammarAST label, boolean invert] returns [List<SrcOp> omos]
|
||||
: ^(NOT a=atom[$label, true]) {$omos = $a.omos;}
|
||||
| range[label] {$omos = $range.omos;}
|
||||
| ^(DOT ID terminal[$label, null])
|
||||
| ^(DOT ID ruleref[$label, null])
|
||||
| ^(WILDCARD .) {$omos = controller.wildcard($WILDCARD, $label, $astOp);}
|
||||
| WILDCARD {$omos = controller.wildcard($WILDCARD, $label, $astOp);}
|
||||
| terminal[label, $astOp] {$omos = $terminal.omos;}
|
||||
| ruleref[label, $astOp] {$omos = $ruleref.omos;}
|
||||
| blockSet[$label, $astOp, invert] {$omos = $blockSet.omos;}
|
||||
| ^(DOT ID terminal[$label])
|
||||
| ^(DOT ID ruleref[$label])
|
||||
| ^(WILDCARD .) {$omos = controller.wildcard($WILDCARD, $label);}
|
||||
| WILDCARD {$omos = controller.wildcard($WILDCARD, $label);}
|
||||
| terminal[label] {$omos = $terminal.omos;}
|
||||
| ruleref[label] {$omos = $ruleref.omos;}
|
||||
| blockSet[$label, invert] {$omos = $blockSet.omos;}
|
||||
;
|
||||
|
||||
ruleref[GrammarAST label, GrammarAST astOp] returns [List<SrcOp> omos]
|
||||
: ^(RULE_REF ARG_ACTION?) {$omos = controller.ruleRef($RULE_REF, $label, $ARG_ACTION, $astOp);}
|
||||
ruleref[GrammarAST label] returns [List<SrcOp> omos]
|
||||
: ^(RULE_REF ARG_ACTION?) {$omos = controller.ruleRef($RULE_REF, $label, $ARG_ACTION);}
|
||||
;
|
||||
|
||||
range[GrammarAST label] returns [List<SrcOp> omos]
|
||||
: ^(RANGE a=STRING_LITERAL b=STRING_LITERAL)
|
||||
;
|
||||
|
||||
terminal[GrammarAST label, GrammarAST astOp] returns [List<SrcOp> omos]
|
||||
: ^(STRING_LITERAL .) {$omos = controller.stringRef($STRING_LITERAL, $label, $astOp);}
|
||||
| STRING_LITERAL {$omos = controller.stringRef($STRING_LITERAL, $label, $astOp);}
|
||||
| ^(TOKEN_REF ARG_ACTION .) {$omos = controller.tokenRef($TOKEN_REF, $label, $ARG_ACTION, $astOp);}
|
||||
| ^(TOKEN_REF .) {$omos = controller.tokenRef($TOKEN_REF, $label, null, $astOp);}
|
||||
| TOKEN_REF {$omos = controller.tokenRef($TOKEN_REF, $label, null, $astOp);}
|
||||
| DOWN_TOKEN {$omos = controller.tokenRef($DOWN_TOKEN, null, null, null);}
|
||||
| UP_TOKEN {$omos = controller.tokenRef($UP_TOKEN, null, null, null);}
|
||||
terminal[GrammarAST label] returns [List<SrcOp> omos]
|
||||
: ^(STRING_LITERAL .) {$omos = controller.stringRef($STRING_LITERAL, $label);}
|
||||
| STRING_LITERAL {$omos = controller.stringRef($STRING_LITERAL, $label);}
|
||||
| ^(TOKEN_REF ARG_ACTION .) {$omos = controller.tokenRef($TOKEN_REF, $label, $ARG_ACTION);}
|
||||
| ^(TOKEN_REF .) {$omos = controller.tokenRef($TOKEN_REF, $label, null);}
|
||||
| TOKEN_REF {$omos = controller.tokenRef($TOKEN_REF, $label, null);}
|
||||
;
|
||||
|
||||
elementOptions
|
||||
|
@ -211,131 +182,5 @@ elementOption
|
|||
: ID
|
||||
| ^(ASSIGN ID ID)
|
||||
| ^(ASSIGN ID STRING_LITERAL)
|
||||
| ^(ASSIGN ID DOUBLE_QUOTE_STRING_LITERAL)
|
||||
| ^(ASSIGN ID ACTION)
|
||||
;
|
||||
|
||||
// R E W R I T E S T U F F
|
||||
|
||||
rewrite returns [Rewrite code]
|
||||
: {
|
||||
controller.treeLevel = 0;
|
||||
controller.codeBlockLevel++;
|
||||
$code = controller.treeRewrite($start);
|
||||
CodeBlock save = controller.getCurrentBlock();
|
||||
controller.setCurrentBlock($code);
|
||||
}
|
||||
( (p=predicatedRewrite {$code.alts.add($p.alt);})+
|
||||
r=nakedRewrite {$code.alts.add($r.alt);}
|
||||
| r=nakedRewrite {$code.alts.add($r.alt);}
|
||||
)
|
||||
{
|
||||
controller.setCurrentBlock(save);
|
||||
controller.codeBlockLevel--;
|
||||
}
|
||||
;
|
||||
|
||||
predicatedRewrite returns [RewriteChoice alt]
|
||||
: ^(ST_RESULT SEMPRED rewriteSTAlt)
|
||||
| ^(RESULT SEMPRED rewriteTreeAlt) {$alt = controller.rewrite_choice((PredAST)$SEMPRED, $rewriteTreeAlt.omos);}
|
||||
;
|
||||
|
||||
nakedRewrite returns [RewriteChoice alt]
|
||||
: ^(ST_RESULT rewriteSTAlt)
|
||||
| ^(RESULT rewriteTreeAlt) {$alt = controller.rewrite_choice(null, $rewriteTreeAlt.omos);}
|
||||
;
|
||||
|
||||
rewriteTreeAlt returns [List<SrcOp> omos]
|
||||
: ^(REWRITE_SEQ
|
||||
{List<SrcOp> elems = new ArrayList<SrcOp>();}
|
||||
( rewriteTreeElement {elems.addAll($rewriteTreeElement.omos);} )+
|
||||
)
|
||||
{$omos = elems;}
|
||||
| ETC
|
||||
| EPSILON {$omos = controller.rewrite_epsilon($EPSILON);}
|
||||
;
|
||||
|
||||
rewriteTreeElement returns [List<SrcOp> omos]
|
||||
: rewriteTreeAtom[false] {$omos = $rewriteTreeAtom.omos;}
|
||||
| rewriteTree {$omos = $rewriteTree.omos;}
|
||||
| rewriteTreeEbnf {$omos = DefaultOutputModelFactory.list($rewriteTreeEbnf.op);}
|
||||
;
|
||||
|
||||
rewriteTreeAtom[boolean isRoot] returns [List<SrcOp> omos]
|
||||
: ^(TOKEN_REF elementOptions ARG_ACTION) {$omos = controller.rewrite_tokenRef($TOKEN_REF, $isRoot, (ActionAST)$ARG_ACTION);}
|
||||
| ^(TOKEN_REF elementOptions) {$omos = controller.rewrite_tokenRef($TOKEN_REF, $isRoot, null);}
|
||||
| ^(TOKEN_REF ARG_ACTION) {$omos = controller.rewrite_tokenRef($TOKEN_REF, $isRoot, (ActionAST)$ARG_ACTION);}
|
||||
| TOKEN_REF {$omos = controller.rewrite_tokenRef($TOKEN_REF, $isRoot, null);}
|
||||
| RULE_REF {$omos = controller.rewrite_ruleRef($RULE_REF, $isRoot);}
|
||||
| ^(STRING_LITERAL elementOptions) {$omos = controller.rewrite_stringRef($STRING_LITERAL, $isRoot);}
|
||||
| STRING_LITERAL {$omos = controller.rewrite_stringRef($STRING_LITERAL, $isRoot);}
|
||||
| LABEL {$omos = controller.rewrite_labelRef($LABEL, $isRoot);}
|
||||
| ACTION {$omos = controller.rewrite_action((ActionAST)$ACTION, $isRoot);}
|
||||
;
|
||||
|
||||
rewriteTreeEbnf returns [CodeBlock op]
|
||||
: ^( (a=OPTIONAL|a=CLOSURE|a=POSITIVE_CLOSURE)
|
||||
^( REWRITE_BLOCK
|
||||
{
|
||||
controller.codeBlockLevel++;
|
||||
if ( $a.getType()==OPTIONAL ) $op = controller.rewrite_optional($start);
|
||||
else $op = controller.rewrite_closure($start);
|
||||
CodeBlock save = controller.getCurrentBlock();
|
||||
controller.setCurrentBlock($op);
|
||||
}
|
||||
talt=rewriteTreeAlt
|
||||
)
|
||||
)
|
||||
{
|
||||
$op.addOps($talt.omos);
|
||||
controller.setCurrentBlock(save);
|
||||
controller.codeBlockLevel--;
|
||||
}
|
||||
;
|
||||
|
||||
rewriteTree returns [List<SrcOp> omos]
|
||||
: {
|
||||
controller.treeLevel++;
|
||||
List<SrcOp> elems = new ArrayList<SrcOp>();
|
||||
RewriteTreeStructure t = controller.rewrite_treeStructure($start);
|
||||
}
|
||||
^( TREE_BEGIN
|
||||
rewriteTreeAtom[true] {elems.addAll($rewriteTreeAtom.omos);}
|
||||
( rewriteTreeElement {elems.addAll($rewriteTreeElement.omos);} )*
|
||||
)
|
||||
{
|
||||
t.ops = elems;
|
||||
$omos = DefaultOutputModelFactory.list(t);
|
||||
controller.treeLevel--;
|
||||
}
|
||||
;
|
||||
|
||||
rewriteSTAlt returns [List<SrcOp> omos]
|
||||
: rewriteTemplate
|
||||
| ETC
|
||||
| EPSILON
|
||||
;
|
||||
|
||||
rewriteTemplate returns [List<SrcOp> omos]
|
||||
: ^(TEMPLATE rewriteTemplateArgs? DOUBLE_QUOTE_STRING_LITERAL)
|
||||
| ^(TEMPLATE rewriteTemplateArgs? DOUBLE_ANGLE_STRING_LITERAL)
|
||||
| rewriteTemplateRef
|
||||
| rewriteIndirectTemplateHead
|
||||
| ACTION
|
||||
;
|
||||
|
||||
rewriteTemplateRef returns [List<SrcOp> omos]
|
||||
: ^(TEMPLATE ID rewriteTemplateArgs?)
|
||||
;
|
||||
|
||||
rewriteIndirectTemplateHead returns [List<SrcOp> omos]
|
||||
: ^(TEMPLATE ACTION rewriteTemplateArgs?)
|
||||
;
|
||||
|
||||
rewriteTemplateArgs returns [List<SrcOp> omos]
|
||||
: ^(ARGLIST rewriteTemplateArg+)
|
||||
;
|
||||
|
||||
rewriteTemplateArg returns [List<SrcOp> omos]
|
||||
: ^(ARG ID ACTION)
|
||||
;
|
||||
|
|
|
@ -392,21 +392,6 @@ public class Target {
|
|||
return st.render();
|
||||
}
|
||||
|
||||
// AST
|
||||
|
||||
public String getRootName(int level) {
|
||||
ST st = gen.templates.getInstanceOf("RootName");
|
||||
st.add("level", level);
|
||||
return st.render();
|
||||
}
|
||||
|
||||
public String getRewriteIteratorName(GrammarAST elem, int level) {
|
||||
ST st = gen.templates.getInstanceOf("RewriteIteratorName");
|
||||
st.add("elemName", getElementName(elem.getText()));
|
||||
st.add("level", level);
|
||||
return st.render();
|
||||
}
|
||||
|
||||
public String getElementListName(String name) {
|
||||
ST st = gen.templates.getInstanceOf("ElementListName");
|
||||
st.add("elemName", getElementName(name));
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.model.MatchTree;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.TreeParserModel;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.codegen.model.decl.NodeDecl;
|
||||
import org.antlr.v4.codegen.model.decl.NodeListDecl;
|
||||
import org.antlr.v4.codegen.model.decl.TokenListDecl;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TreeParserFactory extends ParserFactory {
|
||||
public TreeParserFactory(CodeGenerator gen) {
|
||||
super(gen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeParserFile treeParserFile(String fileName) {
|
||||
return new TreeParserFile(this, fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeParserModel treeParser(TreeParserFile file) {
|
||||
return new TreeParserModel(this, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MatchTree tree(GrammarAST treeBeginAST, List<? extends SrcOp> omos) {
|
||||
return new MatchTree(this, treeBeginAST, omos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Decl getTokenLabelDecl(String label) {
|
||||
return new NodeDecl(this, label);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenListDecl getTokenListLabelDecl(String label) {
|
||||
return new NodeListDecl(this, gen.target.getListLabel(label));
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.model.ParserFile;
|
||||
|
||||
public class TreeParserFile extends ParserFile {
|
||||
public TreeParserFile(OutputModelFactory factory, String fileName) {
|
||||
super(factory, fileName);
|
||||
}
|
||||
}
|
|
@ -30,15 +30,16 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.ast.ElementASTOp;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
|
||||
/** */
|
||||
public class AddToLabelList extends ElementASTOp {
|
||||
public class AddToLabelList extends SrcOp {
|
||||
public Decl label;
|
||||
public String listName;
|
||||
|
||||
public AddToLabelList(OutputModelFactory factory, String listName, Decl label) {
|
||||
super(factory, null, label);
|
||||
super(factory);
|
||||
this.label = label;
|
||||
this.listName = listName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,12 +30,14 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.codegen.model.decl.TokenTypeDecl;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** The class hierarchy underneath SrcOp is pretty deep but makes sense that,
|
||||
* for example LL1StarBlock is a kind of LL1Loop which is a kind of Choice.
|
||||
|
@ -91,11 +93,6 @@ public abstract class Choice extends RuleElement {
|
|||
public ThrowNoViableAlt getThrowNoViableAlt(OutputModelFactory factory,
|
||||
GrammarAST blkAST,
|
||||
IntervalSet expecting) {
|
||||
if ( factory.getGrammar().isTreeGrammar() ) {
|
||||
return new ThrowNoViableTreeAlt(factory, blkAST, expecting);
|
||||
}
|
||||
else {
|
||||
return new ThrowNoViableAlt(factory, blkAST, expecting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class MatchDOWN extends RuleElement {
|
||||
public MatchDOWN(OutputModelFactory factory, GrammarAST ast) {
|
||||
super(factory, ast);
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.LL1Analyzer;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.TreePatternAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MatchTree extends RuleElement {
|
||||
public boolean isNullable;
|
||||
|
||||
@ModelElement public SrcOp root;
|
||||
@ModelElement public List<? extends SrcOp> leftActions;
|
||||
@ModelElement public SrcOp down;
|
||||
@ModelElement public List<? extends SrcOp> kids;
|
||||
@ModelElement public SrcOp up;
|
||||
@ModelElement public List<? extends SrcOp> rightActions;
|
||||
|
||||
public MatchTree(OutputModelFactory factory, GrammarAST ast, List<? extends SrcOp> elems) {
|
||||
super(factory, ast);
|
||||
TreePatternAST rootNode = (TreePatternAST)ast;
|
||||
this.isNullable = isNullable(rootNode);
|
||||
List<? extends SrcOp> afterRoot = elems.subList(1, elems.size());
|
||||
int downIndex =
|
||||
Utils.indexOf(afterRoot, new Utils.Filter<SrcOp>() {
|
||||
public boolean select(SrcOp op) {
|
||||
return op instanceof MatchToken && ((MatchToken)op).ttype==Token.DOWN;
|
||||
}
|
||||
});
|
||||
downIndex++; // we skipped root
|
||||
down = elems.get(downIndex);
|
||||
int upIndex =
|
||||
Utils.lastIndexOf(elems, new Utils.Filter<SrcOp>() {
|
||||
public boolean select(SrcOp op) {
|
||||
return op instanceof MatchToken && ((MatchToken) op).ttype == Token.UP;
|
||||
}
|
||||
});
|
||||
up = elems.get(upIndex);
|
||||
root = elems.get(0);
|
||||
leftActions = elems.subList(1, downIndex);
|
||||
rightActions = elems.subList(upIndex+1, elems.size());
|
||||
this.kids = elems.subList(downIndex+1, upIndex);
|
||||
}
|
||||
|
||||
boolean isNullable(TreePatternAST rootNode) {
|
||||
ATNState firstChildState = rootNode.downState.transition(0).target;
|
||||
LL1Analyzer analyzer = new LL1Analyzer(firstChildState.atn);
|
||||
IntervalSet look = analyzer.LOOK(firstChildState, ParserRuleContext.EMPTY);
|
||||
return look.contains(Token.UP);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class MatchUP extends RuleElement {
|
||||
public MatchUP(OutputModelFactory factory, GrammarAST ast) {
|
||||
super(factory, ast);
|
||||
}
|
||||
}
|
|
@ -35,7 +35,6 @@ import org.antlr.v4.tool.Grammar;
|
|||
public abstract class OutputFile extends OutputModelObject {
|
||||
public final String fileName;
|
||||
public final String TokenLabelType;
|
||||
public final String ASTLabelType;
|
||||
public final String InputSymbolType;
|
||||
|
||||
public OutputFile(OutputModelFactory factory, String fileName) {
|
||||
|
@ -43,8 +42,6 @@ public abstract class OutputFile extends OutputModelObject {
|
|||
this.fileName = fileName;
|
||||
Grammar g = factory.getGrammar();
|
||||
TokenLabelType = g.getOptionString("TokenLabelType");
|
||||
ASTLabelType = g.getOptionString("ASTLabelType", "CommonAST");
|
||||
if ( g.isTreeGrammar() ) InputSymbolType = ASTLabelType;
|
||||
else InputSymbolType = TokenLabelType;
|
||||
InputSymbolType = TokenLabelType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.ast.RewriteChoice;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** Either an ST or Tree rewrite */
|
||||
public class Rewrite extends CodeBlock {
|
||||
@ModelElement public List<RewriteChoice> alts = new ArrayList<RewriteChoice>();
|
||||
|
||||
public Rewrite(OutputModelFactory factory, int treeLevel, int codeBlockLevel) {
|
||||
super(factory, treeLevel, codeBlockLevel);
|
||||
}
|
||||
}
|
|
@ -30,11 +30,14 @@
|
|||
package org.antlr.v4.codegen.model;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.decl.*;
|
||||
import org.antlr.v4.codegen.model.decl.AltLabelStructDecl;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.codegen.model.decl.StructDecl;
|
||||
import org.antlr.v4.misc.Utils;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.Attribute;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -73,9 +76,7 @@ public class RuleFunction extends OutputModelObject {
|
|||
|
||||
index = r.index;
|
||||
|
||||
ruleCtx = r.g.isTreeGrammar() ?
|
||||
new TreeParserStructDecl(factory, r) :
|
||||
new StructDecl(factory, r);
|
||||
ruleCtx = new StructDecl(factory, r);
|
||||
|
||||
List<String> labels = r.getAltLabels();
|
||||
if ( labels!=null ) {
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class ThrowNoViableTreeAlt extends ThrowNoViableAlt {
|
||||
public ThrowNoViableTreeAlt(OutputModelFactory factory,
|
||||
GrammarAST blkOrEbnfRootAST,
|
||||
IntervalSet expecting)
|
||||
{
|
||||
super(factory, blkOrEbnfRootAST, expecting);
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
[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;
|
||||
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.actions.ActionText;
|
||||
import org.antlr.v4.codegen.model.actions.DefaultTreeParserSuperClass;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
|
||||
public class TreeParserModel extends Parser {
|
||||
public TreeParserModel(OutputModelFactory factory, ParserFile file) {
|
||||
super(factory, file);
|
||||
Grammar g = factory.getGrammar();
|
||||
if (g.getOptionString("superClass") != null) {
|
||||
superclass = new ActionText(g.getOptionString("superClass"));
|
||||
} else {
|
||||
superclass = new DefaultTreeParserSuperClass();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
[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 DefaultTreeParserSuperClass extends ActionChunk {
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
[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 {
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
[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 RulePropertyRef_st extends RulePropertyRef {
|
||||
public RulePropertyRef_st(String label) {
|
||||
super(label);
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
[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 RulePropertyRef_tree extends RulePropertyRef {
|
||||
public RulePropertyRef_tree(String label) {
|
||||
super(label);
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
[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 ThisRulePropertyRef_st extends RulePropertyRef {
|
||||
public ThisRulePropertyRef_st(String label) {
|
||||
super(label);
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
[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 ThisRulePropertyRef_tree extends RulePropertyRef {
|
||||
public ThisRulePropertyRef_tree(String label) {
|
||||
super(label);
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
[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 TokenPropertyRef_tree extends TokenPropertyRef {
|
||||
public TokenPropertyRef_tree(String label) {
|
||||
super(label);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
|
||||
public class AddChild extends SrcOp {
|
||||
public String rootName;
|
||||
@ModelElement public SrcOp child;
|
||||
|
||||
public AddChild(OutputModelFactory factory, String rootName, SrcOp child) {
|
||||
super(factory);
|
||||
this.rootName = rootName;
|
||||
this.child = child;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
|
||||
public class AssignTreeResult extends SrcOp {
|
||||
public AssignTreeResult(OutputModelFactory factory) {
|
||||
super(factory);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
|
||||
public class BecomeRoot extends SrcOp {
|
||||
public String rootName;
|
||||
@ModelElement public SrcOp newRoot;
|
||||
|
||||
public BecomeRoot(OutputModelFactory factory, String rootName, SrcOp newRoot) {
|
||||
super(factory);
|
||||
this.rootName = rootName;
|
||||
this.newRoot = newRoot;
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class ClearElementList extends SrcOp {
|
||||
public String name;
|
||||
|
||||
public ClearElementList(OutputModelFactory factory, GrammarAST ast, String name) {
|
||||
super(factory, ast);
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class ElementASTOp extends SrcOp {
|
||||
public Decl label;
|
||||
|
||||
public ElementASTOp(OutputModelFactory factory, GrammarAST ast, Decl label) {
|
||||
super(factory, ast);
|
||||
this.label = label;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
[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 {
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
[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 {
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
[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.ActionTranslator;
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.ModelElement;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.actions.ActionChunk;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RewriteAction extends SrcOp {
|
||||
@ModelElement public List<ActionChunk> chunks;
|
||||
|
||||
public RewriteAction(OutputModelFactory factory, ActionAST ast) {
|
||||
super(factory, ast);
|
||||
if ( ast!=null ) {
|
||||
chunks = ActionTranslator.translateAction(factory,
|
||||
factory.getCurrentRuleFunction(),
|
||||
ast.token, ast);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** A collection of operations possibly with a predicate
|
||||
* that indicates whether to apply the rewrite.
|
||||
* This is a single alternative and a list of predicated choices.
|
||||
*/
|
||||
public class RewriteChoice extends SrcOp {
|
||||
@ModelElement public SrcOp predicate;
|
||||
@ModelElement public List<SrcOp> ops;
|
||||
|
||||
public RewriteChoice(OutputModelFactory factory, SrcOp predicate, List<SrcOp> ops) {
|
||||
super(factory);
|
||||
this.predicate = predicate;
|
||||
this.ops = ops;
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
[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.ActionTranslator;
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.ModelElement;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.actions.ActionChunk;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RewriteImagTokenRef extends SrcOp {
|
||||
public String tokenType;
|
||||
|
||||
@ModelElement public List<ActionChunk> argChunks;
|
||||
|
||||
public RewriteImagTokenRef(OutputModelFactory factory,
|
||||
GrammarAST ast,
|
||||
String tokenType,
|
||||
ActionAST argAST)
|
||||
{
|
||||
super(factory, ast);
|
||||
this.tokenType = tokenType;
|
||||
if ( argAST!=null ) {
|
||||
argChunks = ActionTranslator.translateAction(factory,
|
||||
factory.getCurrentRuleFunction(),
|
||||
argAST.token, argAST);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.decl.RewriteIteratorDecl;
|
||||
|
||||
public class RewriteIteratorInit extends SrcOp {
|
||||
public RewriteIteratorDecl decl;
|
||||
public RewriteIteratorInit(OutputModelFactory factory, RewriteIteratorDecl decl) {
|
||||
super(factory);
|
||||
this.decl = decl;
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class RewriteLabelRef extends SrcOp {
|
||||
public String iterName;
|
||||
|
||||
public RewriteLabelRef(OutputModelFactory factory, GrammarAST ast,
|
||||
String iterName) {
|
||||
super(factory, ast);
|
||||
this.iterName = iterName;
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class RewriteRuleRef extends SrcOp {
|
||||
public String iterName;
|
||||
|
||||
public RewriteRuleRef(OutputModelFactory factory, GrammarAST ast,
|
||||
String iterName)
|
||||
{
|
||||
super(factory, ast);
|
||||
this.iterName = iterName;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class RewriteSelfRuleLabelRef extends SrcOp {
|
||||
public RewriteSelfRuleLabelRef(OutputModelFactory factory, GrammarAST ast) {
|
||||
super(factory, ast);
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class RewriteTokenRef extends SrcOp {
|
||||
public String iterName;
|
||||
public RewriteTokenRef(OutputModelFactory factory, GrammarAST ast,
|
||||
String iterName)
|
||||
{
|
||||
super(factory, ast);
|
||||
this.iterName = iterName;
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RewriteTreeClosure extends CodeBlock {
|
||||
public List<Decl> iteratorDecls = new ArrayList<Decl>();
|
||||
|
||||
public RewriteTreeClosure(OutputModelFactory factory, GrammarAST ast,
|
||||
int treeLevel, int codeBlockLevel)
|
||||
{
|
||||
super(factory, treeLevel, codeBlockLevel);
|
||||
this.ast = ast;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.decl.CodeBlock;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class RewriteTreeOptional extends CodeBlock {
|
||||
public List<Decl> conditionalDecls = new ArrayList<Decl>();
|
||||
|
||||
public RewriteTreeOptional(OutputModelFactory factory, GrammarAST ast,
|
||||
int treeLevel, int codeBlockLevel) {
|
||||
super(factory, treeLevel, codeBlockLevel);
|
||||
this.ast = ast;
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.ModelElement;
|
||||
import org.antlr.v4.codegen.model.SrcOp;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.runtime.misc.OrderedHashSet;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** ^(A B C) */
|
||||
public class RewriteTreeStructure extends SrcOp {
|
||||
public int treeLevel;
|
||||
public int codeBlockLevel;
|
||||
|
||||
@ModelElement public List<SrcOp> ops;
|
||||
@ModelElement public OrderedHashSet<Decl> locals;
|
||||
|
||||
public RewriteTreeStructure(OutputModelFactory factory,
|
||||
GrammarAST ast,
|
||||
int treeLevel,
|
||||
int codeBlockLevel)
|
||||
{
|
||||
super(factory, ast);
|
||||
this.treeLevel = treeLevel;
|
||||
this.codeBlockLevel = codeBlockLevel;
|
||||
}
|
||||
|
||||
/** Add local var decl */
|
||||
public void addLocalDecl(Decl d) {
|
||||
if ( locals==null ) locals = new OrderedHashSet<Decl>();
|
||||
locals.add(d);
|
||||
d.isLocal = true;
|
||||
}
|
||||
|
||||
public int getEnclosingTreeLevel() { return treeLevel - 1; }
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
[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.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.model.decl.Decl;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
|
||||
public class RuleAST extends ElementASTOp {
|
||||
public RuleAST(OutputModelFactory factory, GrammarAST ast, Decl label) {
|
||||
super(factory, ast, label);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue