public virtual DFA CreateLL_1_LookaheadDFA( int decision )
{
Decision d = GetDecision( decision );
string enclosingRule = d.startState.enclosingRule.Name;
Rule r = d.startState.enclosingRule;
NFAState decisionStartState = GetDecisionNFAStartState( decision );
if ( composite.WatchNFAConversion )
{
Console.Out.WriteLine( "--------------------\nattempting LL(1) DFA (d="
+ decisionStartState.DecisionNumber + ") for " +
decisionStartState.Description );
}
if ( r.IsSynPred && !synPredNamesUsedInDFA.Contains( enclosingRule ) )
{
return null;
}
// compute lookahead for each alt
int numAlts = GetNumberOfAltsForDecisionNFA( decisionStartState );
LookaheadSet[] altLook = new LookaheadSet[numAlts + 1];
for ( int alt = 1; alt <= numAlts; alt++ )
{
int walkAlt =
decisionStartState.TranslateDisplayAltToWalkAlt( alt );
NFAState altLeftEdge = GetNFAStateForAltOfDecision( decisionStartState, walkAlt );
NFAState altStartState = (NFAState)altLeftEdge.transition[0].Target;
//[email protected]("alt "+alt+" start state = "+altStartState.stateNumber);
altLook[alt] = ll1Analyzer.Look( altStartState );
//[email protected]("alt "+alt+": "+altLook[alt].toString(this));
}
// compare alt i with alt j for disjointness
bool decisionIsLL_1 = true;
for ( int i = 1; i <= numAlts; i++ )
{
for ( int j = i + 1; j <= numAlts; j++ )
{
/*
[email protected]("compare "+i+", "+j+": "+
altLook[i].toString(this)+" with "+
altLook[j].toString(this));
*/
LookaheadSet collision = altLook[i].Intersection( altLook[j] );
if ( !collision.IsNil )
{
//[email protected]("collision (non-LL(1)): "+collision.toString(this));
decisionIsLL_1 = false;
goto outer;
}
}
}
outer:
bool foundConfoundingPredicate =
ll1Analyzer.DetectConfoundingPredicates( decisionStartState );
if ( decisionIsLL_1 && !foundConfoundingPredicate )
{
// build an LL(1) optimized DFA with edge for each altLook[i]
if ( NFAToDFAConverter.debug )
{
Console.Out.WriteLine( "decision " + decision + " is simple LL(1)" );
}
DFA lookaheadDFA2 = new LL1DFA( decision, decisionStartState, altLook );
SetLookaheadDFA( decision, lookaheadDFA2 );
UpdateLineColumnToLookaheadDFAMap( lookaheadDFA2 );
return lookaheadDFA2;
}
// not LL(1) but perhaps we can solve with simplified predicate search
// even if k=1 set manually, only resolve here if we have preds; i.e.,
// don't resolve etc...
/*
SemanticContext visiblePredicates =
ll1Analyzer.getPredicates(decisionStartState);
boolean foundConfoundingPredicate =
ll1Analyzer.detectConfoundingPredicates(decisionStartState);
*/
// exit if not forced k=1 or we found a predicate situation we
// can't handle: predicates in rules invoked from this decision.
if ( GetUserMaxLookahead( decision ) != 1 || // not manually set to k=1
!GetAutoBacktrackMode( decision ) ||
foundConfoundingPredicate )
{
//[email protected]("trying LL(*)");
return null;
}
IList<IIntSet> edges = new List<IIntSet>();
for ( int i = 1; i < altLook.Length; i++ )
{
LookaheadSet s = altLook[i];
edges.Add( (IntervalSet)s.TokenTypeSet );
}
IList<IIntSet> disjoint = MakeEdgeSetsDisjoint( edges );
//[email protected]("disjoint="+disjoint);
MultiMap<IntervalSet, int> edgeMap = new MultiMap<IntervalSet, int>();
for ( int i = 0; i < disjoint.Count; i++ )
{
IntervalSet ds = (IntervalSet)disjoint[i];
for ( int alt = 1; alt < altLook.Length; alt++ )
{
LookaheadSet look = altLook[alt];
if ( !ds.And( look.TokenTypeSet ).IsNil )
{
edgeMap.Map( ds, alt );
}
}
}
//[email protected]("edge map: "+edgeMap);
// TODO: how do we know we covered stuff?
// build an LL(1) optimized DFA with edge for each altLook[i]
DFA lookaheadDFA = new LL1DFA( decision, decisionStartState, edgeMap );
SetLookaheadDFA( decision, lookaheadDFA );
// create map from line:col to decision DFA (for ANTLRWorks)
UpdateLineColumnToLookaheadDFAMap( lookaheadDFA );
return lookaheadDFA;
}