rm for now
This commit is contained in:
parent
e3e739dfc7
commit
ceab49e3ce
|
@ -29,161 +29,146 @@
|
|||
|
||||
package org.antlr.v4.runtime.atn;
|
||||
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.RuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
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.Nullable;
|
||||
import org.antlr.v4.runtime.tree.TraceTree;
|
||||
public class ParserATNPathFinder /*extends ParserATNSimulator<Token>*/ {
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ParserATNPathFinder extends ParserATNSimulator<Token> {
|
||||
public ParserATNPathFinder(@Nullable Parser parser, @NotNull ATN atn, @NotNull DFA[] decisionToDFA) {
|
||||
super(parser, atn, decisionToDFA);
|
||||
}
|
||||
|
||||
/** Given an input sequence, as a subset of the input stream, trace the path through the
|
||||
* ATN starting at s. The path returned includes s and the final target of the last input
|
||||
* symbol. If there are multiple paths through the ATN to the final state, it uses the first
|
||||
* method finds. This is used to figure out how input sequence is matched in more than one
|
||||
* way between the alternatives of a decision. It's only that decision we are concerned with
|
||||
* and so if there are ambiguous decisions further along, we will ignore them for the
|
||||
* purposes of computing the path to the final state. To figure out multiple paths for
|
||||
* decision, use this method on the left edge of the alternatives of the decision in question.
|
||||
*
|
||||
* TODO: I haven't figured out what to do with nongreedy decisions yet
|
||||
* TODO: preds. unless i create rule specific ctxs, i can't eval preds. also must eval args!
|
||||
*/
|
||||
public TraceTree trace(@NotNull ATNState s, @Nullable RuleContext ctx,
|
||||
TokenStream input, int start, int stop)
|
||||
{
|
||||
System.out.println("REACHES "+s.stateNumber+" start state");
|
||||
List<TraceTree> leaves = new ArrayList<TraceTree>();
|
||||
HashSet<ATNState>[] busy = new HashSet[stop-start+1];
|
||||
for (int i = 0; i < busy.length; i++) {
|
||||
busy[i] = new HashSet<ATNState>();
|
||||
}
|
||||
TraceTree path = _trace(s, ctx, ctx, input, start, start, stop, leaves, busy);
|
||||
if ( path!=null ) path.leaves = leaves;
|
||||
return path;
|
||||
}
|
||||
|
||||
/** Returns true if we found path */
|
||||
public TraceTree _trace(@NotNull ATNState s, RuleContext initialContext, RuleContext ctx,
|
||||
TokenStream input, int start, int i, int stop,
|
||||
List<TraceTree> leaves, @NotNull Set<ATNState>[] busy)
|
||||
{
|
||||
TraceTree root = new TraceTree(s);
|
||||
if ( i>stop ) {
|
||||
leaves.add(root); // track final states
|
||||
System.out.println("leaves=" + leaves);
|
||||
return root;
|
||||
}
|
||||
|
||||
if ( !busy[i-start].add(s) ) {
|
||||
System.out.println("already visited "+s.stateNumber+" at input "+i+"="+input.get(i).getText());
|
||||
return null;
|
||||
}
|
||||
busy[i-start].add(s);
|
||||
|
||||
System.out.println("TRACE "+s.stateNumber+" at input "+input.get(i).getText());
|
||||
|
||||
if ( s instanceof RuleStopState) {
|
||||
// We hit rule end. If we have context info, use it
|
||||
if ( ctx!=null && !ctx.isEmpty() ) {
|
||||
System.out.println("stop state "+s.stateNumber+", ctx="+ctx);
|
||||
ATNState invokingState = atn.states.get(ctx.invokingState);
|
||||
RuleTransition rt = (RuleTransition)invokingState.transition(0);
|
||||
ATNState retState = rt.followState;
|
||||
return _trace(retState, initialContext, ctx.parent, input, start, i, stop, leaves, busy);
|
||||
}
|
||||
else {
|
||||
// else if we have no context info, just chase follow links (if greedy)
|
||||
System.out.println("FALLING off rule "+getRuleName(s.ruleIndex));
|
||||
}
|
||||
}
|
||||
|
||||
int n = s.getNumberOfTransitions();
|
||||
boolean aGoodPath = false;
|
||||
TraceTree found;
|
||||
for (int j=0; j<n; j++) {
|
||||
Transition t = s.transition(j);
|
||||
if ( t.getClass() == RuleTransition.class ) {
|
||||
RuleContext newContext =
|
||||
new RuleContext(ctx, s.stateNumber);
|
||||
found = _trace(t.target, initialContext, newContext, input, start, i, stop, leaves, busy);
|
||||
if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
continue;
|
||||
}
|
||||
if ( t instanceof PredicateTransition ) {
|
||||
found = predTransition(initialContext, ctx, input, start, i, stop, leaves, busy, root, t);
|
||||
if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
continue;
|
||||
}
|
||||
if ( t.isEpsilon() ) {
|
||||
found = _trace(t.target, initialContext, ctx, input, start, i, stop, leaves, busy);
|
||||
if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
continue;
|
||||
}
|
||||
if ( t.getClass() == WildcardTransition.class ) {
|
||||
System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
|
||||
found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
|
||||
if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
continue;
|
||||
}
|
||||
IntervalSet set = t.label();
|
||||
if ( set!=null ) {
|
||||
if ( t instanceof NotSetTransition ) {
|
||||
if ( !set.contains(input.get(i).getType()) ) {
|
||||
System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
|
||||
found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
|
||||
if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( set.contains(input.get(i).getType()) ) {
|
||||
System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
|
||||
found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
|
||||
if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( aGoodPath ) return root; // found at least one transition leading to success
|
||||
return null;
|
||||
}
|
||||
|
||||
public TraceTree predTransition(RuleContext initialContext, RuleContext ctx, TokenStream input, int start,
|
||||
int i, int stop, List<TraceTree> leaves, Set<ATNState>[] busy,
|
||||
TraceTree root, Transition t)
|
||||
{
|
||||
SemanticContext.Predicate pred = ((PredicateTransition) t).getPredicate();
|
||||
boolean pass;
|
||||
if ( pred.isCtxDependent ) {
|
||||
if ( ctx instanceof ParserRuleContext && ctx==initialContext ) {
|
||||
System.out.println("eval pred "+pred+"="+pred.eval(parser, ctx));
|
||||
pass = pred.eval(parser, ctx);
|
||||
}
|
||||
else {
|
||||
pass = true; // see thru ctx dependent when out of context
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.out.println("eval pred "+pred+"="+pred.eval(parser, initialContext));
|
||||
pass = pred.eval(parser, ctx);
|
||||
}
|
||||
if ( pass ) {
|
||||
return _trace(t.target, initialContext, ctx, input, start, i, stop, leaves, busy);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// public ParserATNPathFinder(@Nullable Parser parser, @NotNull ATN atn, @NotNull DFA[] decisionToDFA) {
|
||||
// super(parser, atn, decisionToDFA);
|
||||
// }
|
||||
//
|
||||
// /** Given an input sequence, as a subset of the input stream, trace the path through the
|
||||
// * ATN starting at s. The path returned includes s and the final target of the last input
|
||||
// * symbol. If there are multiple paths through the ATN to the final state, it uses the first
|
||||
// * method finds. This is used to figure out how input sequence is matched in more than one
|
||||
// * way between the alternatives of a decision. It's only that decision we are concerned with
|
||||
// * and so if there are ambiguous decisions further along, we will ignore them for the
|
||||
// * purposes of computing the path to the final state. To figure out multiple paths for
|
||||
// * decision, use this method on the left edge of the alternatives of the decision in question.
|
||||
// *
|
||||
// * TODO: I haven't figured out what to do with nongreedy decisions yet
|
||||
// * TODO: preds. unless i create rule specific ctxs, i can't eval preds. also must eval args!
|
||||
// */
|
||||
// public TraceTree trace(@NotNull ATNState s, @Nullable RuleContext ctx,
|
||||
// TokenStream input, int start, int stop)
|
||||
// {
|
||||
// System.out.println("REACHES "+s.stateNumber+" start state");
|
||||
// List<TraceTree> leaves = new ArrayList<TraceTree>();
|
||||
// HashSet<ATNState>[] busy = new HashSet[stop-start+1];
|
||||
// for (int i = 0; i < busy.length; i++) {
|
||||
// busy[i] = new HashSet<ATNState>();
|
||||
// }
|
||||
// TraceTree path = _trace(s, ctx, ctx, input, start, start, stop, leaves, busy);
|
||||
// if ( path!=null ) path.leaves = leaves;
|
||||
// return path;
|
||||
// }
|
||||
//
|
||||
// /** Returns true if we found path */
|
||||
// public TraceTree _trace(@NotNull ATNState s, RuleContext initialContext, RuleContext ctx,
|
||||
// TokenStream input, int start, int i, int stop,
|
||||
// List<TraceTree> leaves, @NotNull Set<ATNState>[] busy)
|
||||
// {
|
||||
// TraceTree root = new TraceTree(s);
|
||||
// if ( i>stop ) {
|
||||
// leaves.add(root); // track final states
|
||||
// System.out.println("leaves=" + leaves);
|
||||
// return root;
|
||||
// }
|
||||
//
|
||||
// if ( !busy[i-start].add(s) ) {
|
||||
// System.out.println("already visited "+s.stateNumber+" at input "+i+"="+input.get(i).getText());
|
||||
// return null;
|
||||
// }
|
||||
// busy[i-start].add(s);
|
||||
//
|
||||
// System.out.println("TRACE "+s.stateNumber+" at input "+input.get(i).getText());
|
||||
//
|
||||
// if ( s instanceof RuleStopState) {
|
||||
// // We hit rule end. If we have context info, use it
|
||||
// if ( ctx!=null && !ctx.isEmpty() ) {
|
||||
// System.out.println("stop state "+s.stateNumber+", ctx="+ctx);
|
||||
// ATNState invokingState = atn.states.get(ctx.invokingState);
|
||||
// RuleTransition rt = (RuleTransition)invokingState.transition(0);
|
||||
// ATNState retState = rt.followState;
|
||||
// return _trace(retState, initialContext, ctx.parent, input, start, i, stop, leaves, busy);
|
||||
// }
|
||||
// else {
|
||||
// // else if we have no context info, just chase follow links (if greedy)
|
||||
// System.out.println("FALLING off rule "+getRuleName(s.ruleIndex));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// int n = s.getNumberOfTransitions();
|
||||
// boolean aGoodPath = false;
|
||||
// TraceTree found;
|
||||
// for (int j=0; j<n; j++) {
|
||||
// Transition t = s.transition(j);
|
||||
// if ( t.getClass() == RuleTransition.class ) {
|
||||
// RuleContext newContext =
|
||||
// new RuleContext(ctx, s.stateNumber);
|
||||
// found = _trace(t.target, initialContext, newContext, input, start, i, stop, leaves, busy);
|
||||
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
// continue;
|
||||
// }
|
||||
// if ( t instanceof PredicateTransition ) {
|
||||
// found = predTransition(initialContext, ctx, input, start, i, stop, leaves, busy, root, t);
|
||||
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
// continue;
|
||||
// }
|
||||
// if ( t.isEpsilon() ) {
|
||||
// found = _trace(t.target, initialContext, ctx, input, start, i, stop, leaves, busy);
|
||||
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
// continue;
|
||||
// }
|
||||
// if ( t.getClass() == WildcardTransition.class ) {
|
||||
// System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
|
||||
// found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
|
||||
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
// continue;
|
||||
// }
|
||||
// IntervalSet set = t.label();
|
||||
// if ( set!=null ) {
|
||||
// if ( t instanceof NotSetTransition ) {
|
||||
// if ( !set.contains(input.get(i).getType()) ) {
|
||||
// System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
|
||||
// found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
|
||||
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// if ( set.contains(input.get(i).getType()) ) {
|
||||
// System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
|
||||
// found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
|
||||
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ( aGoodPath ) return root; // found at least one transition leading to success
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// public TraceTree predTransition(RuleContext initialContext, RuleContext ctx, TokenStream input, int start,
|
||||
// int i, int stop, List<TraceTree> leaves, Set<ATNState>[] busy,
|
||||
// TraceTree root, Transition t)
|
||||
// {
|
||||
// SemanticContext.Predicate pred = ((PredicateTransition) t).getPredicate();
|
||||
// boolean pass;
|
||||
// if ( pred.isCtxDependent ) {
|
||||
// if ( ctx instanceof ParserRuleContext && ctx==initialContext ) {
|
||||
// System.out.println("eval pred "+pred+"="+pred.eval(parser, ctx));
|
||||
// pass = pred.eval(parser, ctx);
|
||||
// }
|
||||
// else {
|
||||
// pass = true; // see thru ctx dependent when out of context
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// System.out.println("eval pred "+pred+"="+pred.eval(parser, initialContext));
|
||||
// pass = pred.eval(parser, ctx);
|
||||
// }
|
||||
// if ( pass ) {
|
||||
// return _trace(t.target, initialContext, ctx, input, start, i, stop, leaves, busy);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue