rm for now

This commit is contained in:
Terence Parr 2012-07-29 10:12:09 -07:00
parent e3e739dfc7
commit ceab49e3ce
1 changed files with 140 additions and 155 deletions

View File

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