public GetTransition ( int trans ) : Transition | ||
trans | int | |
return | Transition |
public List<DFAState> GetAnyDFAPathToTarget(DFAState startState, DFAState targetState, HashSet<DFAState> visited) { List<DFAState> dfaStates = new List<DFAState>(); visited.Add(startState); if (startState.Equals(targetState)) { dfaStates.Add(targetState); return dfaStates; } // for (Edge e : startState.edges) { // walk edges looking for valid // path for (int i = 0; i < startState.NumberOfTransitions; i++) { Transition e = startState.GetTransition(i); if (!visited.Contains((DFAState)e.Target)) { List<DFAState> path = GetAnyDFAPathToTarget((DFAState)e.Target, targetState, visited); if (path != null) { // found path, we're done dfaStates.Add(startState); dfaStates.AddRange(path); return dfaStates; } } } return null; }
public List <DFAState> GetAnyDFAPathToTarget(DFAState startState, DFAState targetState, HashSet <DFAState> visited) { List <DFAState> dfaStates = new List <DFAState>(); visited.Add(startState); if (startState.Equals(targetState)) { dfaStates.Add(targetState); return(dfaStates); } // for (Edge e : startState.edges) { // walk edges looking for valid // path for (int i = 0; i < startState.NumberOfTransitions; i++) { Transition e = startState.GetTransition(i); if (!visited.Contains((DFAState)e.Target)) { List <DFAState> path = GetAnyDFAPathToTarget((DFAState)e.Target, targetState, visited); if (path != null) { // found path, we're done dfaStates.Add(startState); dfaStates.AddRange(path); return(dfaStates); } } } return(null); }
// S U P P O R T /** Given a start state and a target state, return true if start can reach * target state. Also, compute the set of DFA states * that are on a path from start to target; return in states parameter. */ protected virtual bool ReachesState(DFAState startState, DFAState targetState, HashSet <object> states) { if (startState == targetState) { states.Add(targetState); //[email protected]("found target DFA state "+targetState.getStateNumber()); _stateReachable[startState.StateNumber] = Reachable.Yes; return(true); } DFAState s = startState; // avoid infinite loops _stateReachable[s.StateNumber] = Reachable.Busy; // look for a path to targetState among transitions for this state // stop when you find the first one; I'm pretty sure there is // at most one path to any DFA state with conflicting predictions for (int i = 0; i < s.NumberOfTransitions; i++) { Transition t = s.GetTransition(i); DFAState edgeTarget = (DFAState)t.Target; Reachable targetStatus; //= stateReachable.get( edgeTarget.stateNumber ); if (_stateReachable.TryGetValue(edgeTarget.StateNumber, out targetStatus)) { if (targetStatus == Reachable.Busy) { // avoid cycles; they say nothing continue; } if (targetStatus == Reachable.Yes) { // return success! _stateReachable[s.StateNumber] = Reachable.Yes; return(true); } if (targetStatus == Reachable.No) { // try another transition continue; } } // if null, target must be REACHABLE_UNKNOWN (i.e., unvisited) if (ReachesState(edgeTarget, targetState, states)) { states.Add(s); _stateReachable[s.StateNumber] = Reachable.Yes; return(true); } } _stateReachable[s.StateNumber] = Reachable.No; return(false); // no path to targetState found. }
protected virtual void OptimizeEOTBranches(DFAState state) { if (state == null) { throw new ArgumentNullException("state"); } int sI = state.StateNumber; if (_visited.Contains(sI)) { return; // already visited } _visited.Add(sI); for (int i = 0; i < state.NumberOfTransitions; i++) { Transition edge = state.GetTransition(i); DFAState edgeTarget = ((DFAState)edge.Target); /* * [email protected](d.stateNumber+"-"+ * edge.label.toString(d.dfa.nfa.grammar)+"->"+ * edgeTarget.stateNumber); */ // if only one edge coming out, it is EOT, and target is accept prune if (PRUNE_TOKENS_RULE_SUPERFLUOUS_EOT_EDGES && edgeTarget.IsAcceptState && state.NumberOfTransitions == 1 && edge.Label.IsAtom && edge.Label.Atom == Label.EOT) { //[email protected]("state "+d+" can be pruned"); // remove the superfluous EOT edge state.RemoveTransition(i); state.IsAcceptState = true; // make it an accept state // force it to uniquely predict the originally predicted state state.CachedUniquelyPredicatedAlt = edgeTarget.GetUniquelyPredictedAlt(); i--; // back up one so that i++ of loop iteration stays within bounds } OptimizeEOTBranches(edgeTarget); } }
/** Return a list of edge labels from start state to targetState. */ public List <IIntSet> GetEdgeLabels(DFAState targetState) { List <DFAState> dfaStates = GetAnyDFAPathToTarget(targetState); List <IIntSet> labels = new List <IIntSet>(); for (int i = 0; i < dfaStates.Count - 1; i++) { DFAState d = dfaStates[i]; DFAState nextState = dfaStates[i + 1]; // walk looking for edge whose target is next dfa state for (int j = 0; j < d.NumberOfTransitions; j++) { Transition e = d.GetTransition(j); if (e.Target.StateNumber == nextState.StateNumber) { labels.Add(e.Label.Set); } } } return(labels); }
protected virtual void OptimizeExitBranches(DFAState state) { if (state == null) { throw new ArgumentNullException("state"); } int sI = state.StateNumber; if (_visited.Contains(sI)) { return; // already visited } _visited.Add(sI); int nAlts = state.Dfa.NumberOfAlts; for (int i = 0; i < state.NumberOfTransitions; i++) { Transition edge = (Transition)state.GetTransition(i); DFAState edgeTarget = ((DFAState)edge.Target); /* * [email protected](d.stateNumber+"-"+ * edge.label.toString(d.dfa.nfa.grammar)+"->"+ * edgeTarget.stateNumber); */ // if target is an accept state and that alt is the exit alt if (edgeTarget.IsAcceptState && edgeTarget.GetUniquelyPredictedAlt() == nAlts) { /* * [email protected]("ignoring transition "+i+" to max alt "+ * d.dfa.getNumberOfAlts()); */ state.RemoveTransition(i); i--; // back up one so that i++ of loop iteration stays within bounds } OptimizeExitBranches(edgeTarget); } }
/** Set up the EOT and EOF tables; we cannot put -1 min/max values so * we need another way to test that in the DFA transition function. */ protected virtual void CreateEOTAndEOFTables( DFAState s ) { for ( int j = 0; j < s.NumberOfTransitions; j++ ) { Transition edge = s.GetTransition( j ); Label label = edge.Label; if ( label.IsAtom ) { if ( label.Atom == Label.EOT ) { // eot[s] points to accept state _eot[s.StateNumber] = edge.Target.StateNumber; } else if ( label.Atom == Label.EOF ) { // eof[s] points to accept state _eof[s.StateNumber] = edge.Target.StateNumber; } } else if ( label.IsSet ) { if ( label.Set.Contains( Label.EOT ) ) { _eot[s.StateNumber] = edge.Target.StateNumber; } if ( label.Set.Contains( Label.EOF ) ) { _eof[s.StateNumber] = edge.Target.StateNumber; } } } }
private int CalculateMaxLookaheadDepth(DFAState d, int depth) { // not cyclic; don't worry about termination // fail if pred edge. int max = depth; for (int i = 0; i < d.NumberOfTransitions; i++) { Transition t = d.GetTransition(i); // if ( t.isSemanticPredicate() ) return Integer.MAX_VALUE; if (!t.IsSemanticPredicate) { // if pure pred not gated, it must target stop state; don't count DFAState edgeTarget = (DFAState)t.Target; int m = CalculateMaxLookaheadDepth(edgeTarget, depth + 1); max = Math.Max(max, m); } } return max; }
/** Do a depth-first walk of the state machine graph and * fill a DOT description template. Keep filling the * states and edges attributes. */ protected virtual void WalkCreatingDFADOT( StringTemplate dot, DFAState s ) { if ( markedStates.Contains( s.StateNumber ) ) { return; // already visited this node } markedStates.Add( s.StateNumber ); // mark this node as completed. // first add this node StringTemplate st; if ( s.IsAcceptState ) { st = GetTemplates().GetInstanceOf( "stopstate" ); } else { st = GetTemplates().GetInstanceOf( "state" ); } st.SetAttribute( "name", GetStateLabel( s ) ); dot.SetAttribute( "states", st ); // make a DOT edge for each transition for ( int i = 0; i < s.NumberOfTransitions; i++ ) { Transition edge = (Transition)s.GetTransition( i ); //Console.Out.WriteLine( "dfa " + s.dfa.decisionNumber + " edge from s" // + s.stateNumber + " [" + i + "] of " + s.NumberOfTransitions ); if ( StripNonreducedStates ) { if ( edge.Target is DFAState && ( (DFAState)edge.Target ).AcceptStateReachable != Reachable.Yes ) { continue; // don't generate nodes for terminal states } } st = GetTemplates().GetInstanceOf( "edge" ); st.SetAttribute( "label", GetEdgeLabel( edge ) ); st.SetAttribute( "src", GetStateLabel( s ) ); st.SetAttribute( "target", GetStateLabel( edge.Target ) ); st.SetAttribute( "arrowhead", arrowhead ); dot.SetAttribute( "edges", st ); WalkCreatingDFADOT( dot, (DFAState)edge.Target ); // keep walkin' } }
protected virtual void CreateTransitionTableEntryForState( DFAState s ) { /* [email protected]("createTransitionTableEntryForState s"+s.stateNumber+ " dec "+s.dfa.decisionNumber+" cyclic="+s.dfa.isCyclic()); */ int smax = _max[s.StateNumber]; int smin = _min[s.StateNumber]; int[] stateTransitions = new int[smax - smin + 1]; for ( int i = 0; i < stateTransitions.Length; i++ ) stateTransitions[i] = EmptyValue; _transition[s.StateNumber] = stateTransitions; for ( int j = 0; j < s.NumberOfTransitions; j++ ) { Transition edge = s.GetTransition( j ); Label label = edge.Label; if ( label.IsAtom && label.Atom >= Label.MIN_CHAR_VALUE ) { int labelIndex = label.Atom - smin; // offset from 0 stateTransitions[labelIndex] = edge.Target.StateNumber; } else if ( label.IsSet ) { foreach ( var interval in ((IntervalSet)label.Set).Intervals ) { for ( int i = Math.Max( interval.a, Label.MIN_CHAR_VALUE ); i <= interval.b; i++ ) { stateTransitions[i - smin] = edge.Target.StateNumber; } } } } // track unique state transition tables so we can reuse int? edgeClass; // = edgeTransitionClassMap.get( stateTransitions ); if ( _edgeTransitionClassMap.TryGetValue( stateTransitions, out edgeClass ) && edgeClass != null ) { //[email protected]("we've seen this array before; size="+stateTransitions.size()); _transitionEdgeTables[s.StateNumber] = edgeClass; } else { edgeClass = _edgeTransitionClass; _transitionEdgeTables[s.StateNumber] = edgeClass; _edgeTransitionClassMap[stateTransitions] = edgeClass; _edgeTransitionClass++; } }
/** figure out if this state eventually reaches an accept state and * modify the instance variable 'reduced' to indicate if we find * at least one state that cannot reach an accept state. This implies * that the overall DFA is not reduced. This algorithm should be * linear in the number of DFA states. * * The algorithm also tracks which alternatives have no accept state, * indicating a nondeterminism. * * Also computes whether the DFA is cyclic. * * TODO: I call getUniquelyPredicatedAlt too much; cache predicted alt */ protected virtual bool DoesStateReachAcceptState( DFAState d ) { if ( d.IsAcceptState ) { // accept states have no edges emanating from them so we can return d.AcceptStateReachable = Reachable.Yes; // this alt is uniquely predicted, remove from nondeterministic list int predicts = d.GetUniquelyPredictedAlt(); UnreachableAlts.Remove( predicts ); return true; } // avoid infinite loops d.AcceptStateReachable = Reachable.Busy; bool anEdgeReachesAcceptState = false; // Visit every transition, track if at least one edge reaches stop state // Cannot terminate when we know this state reaches stop state since // all transitions must be traversed to set status of each DFA state. for ( int i = 0; i < d.NumberOfTransitions; i++ ) { Transition t = d.GetTransition( i ); DFAState edgeTarget = (DFAState)t.Target; Reachable targetStatus = edgeTarget.AcceptStateReachable; if ( targetStatus == Reachable.Busy ) { // avoid cycles; they say nothing _cyclic = true; continue; } if ( targetStatus == Reachable.Yes ) { // avoid unnecessary work anEdgeReachesAcceptState = true; continue; } if ( targetStatus == Reachable.No ) { // avoid unnecessary work continue; } // target must be REACHABLE_UNKNOWN (i.e., unvisited) if ( DoesStateReachAcceptState( edgeTarget ) ) { anEdgeReachesAcceptState = true; // have to keep looking so don't break loop // must cover all states even if we find a path for this state } } if ( anEdgeReachesAcceptState ) { d.AcceptStateReachable = Reachable.Yes; } else { d.AcceptStateReachable = Reachable.No; _reduced = false; } return anEdgeReachesAcceptState; }
protected virtual void OptimizeExitBranches( DFAState state ) { if (state == null) throw new ArgumentNullException("state"); int sI = state.StateNumber; if ( _visited.Contains( sI ) ) { return; // already visited } _visited.Add( sI ); int nAlts = state.Dfa.NumberOfAlts; for ( int i = 0; i < state.NumberOfTransitions; i++ ) { Transition edge = (Transition)state.GetTransition( i ); DFAState edgeTarget = ( (DFAState)edge.Target ); /* [email protected](d.stateNumber+"-"+ edge.label.toString(d.dfa.nfa.grammar)+"->"+ edgeTarget.stateNumber); */ // if target is an accept state and that alt is the exit alt if ( edgeTarget.IsAcceptState && edgeTarget.GetUniquelyPredictedAlt() == nAlts ) { /* [email protected]("ignoring transition "+i+" to max alt "+ d.dfa.getNumberOfAlts()); */ state.RemoveTransition( i ); i--; // back up one so that i++ of loop iteration stays within bounds } OptimizeExitBranches( edgeTarget ); } }
protected virtual void CreateSpecialTable( DFAState s ) { // number all special states from 0...n-1 instead of their usual numbers bool hasSemPred = false; // TODO this code is very similar to canGenerateSwitch. Refactor to share for ( int j = 0; j < s.NumberOfTransitions; j++ ) { Transition edge = (Transition)s.GetTransition( j ); Label label = edge.Label; // can't do a switch if the edges have preds or are going to // require gated predicates if ( label.IsSemanticPredicate || ( (DFAState)edge.Target ).GetGatedPredicatesInNFAConfigurations() != null ) { hasSemPred = true; break; } } // if has pred or too big for table, make it special int smax = _max[s.StateNumber]; int smin = _min[s.StateNumber]; if ( hasSemPred || smax - smin > MAX_STATE_TRANSITIONS_FOR_TABLE ) { _special[s.StateNumber] = _uniqueCompressedSpecialStateNum; _uniqueCompressedSpecialStateNum++; _specialStates.Add( s ); } else { _special[s.StateNumber] = EmptyValue; // not special } }
private void WalkCreatingDfaDgml(DFAState dfaState) { if (!_markedStates.Add(dfaState.StateNumber)) return; // first add this node string nodeCategory; if (dfaState.IsAcceptState) { nodeCategory = Categories.StopState; } else { nodeCategory = Categories.State; } XElement node = new XElement(Elements.Node, new XAttribute(Attributes.Id, "state_" + dfaState.StateNumber), new XAttribute(Attributes.Label, GetStateLabel(dfaState)), new XAttribute(Attributes.Category, nodeCategory)); _nodes.Add(dfaState, node); if (GroupNodes) _extraLinks.Add(CreateContainmentLink(_groupId, "state_" + dfaState.StateNumber)); // make an edge for each transition for (int i = 0; i < dfaState.NumberOfTransitions; i++) { Transition edge = dfaState.GetTransition(i); if (StripNonreducedStates) { DFAState target = edge.Target as DFAState; // don't generate nodes for terminal states if (target != null && target.AcceptStateReachable != Reachable.Yes) continue; } string edgeCategory = Categories.Edge; XElement edgeElement = new XElement(Elements.Link, new XAttribute(Attributes.Source, "state_" + dfaState.StateNumber), new XAttribute(Attributes.Target, "state_" + edge.Target.StateNumber), new XAttribute(Attributes.Category, edgeCategory), new XAttribute(Attributes.Label, GetEdgeLabel(edge))); _links.Add(new KeyValuePair<State, Transition>(dfaState, edge), edgeElement); WalkCreatingDfaDgml((DFAState)edge.Target); } }
internal virtual bool CalculateHasSynPred(DFAState d, HashSet<DFAState> busy) { busy.Add(d); for (int i = 0; i < d.NumberOfTransitions; i++) { Transition t = d.GetTransition(i); if (t.IsSemanticPredicate) { SemanticContext ctx = t.Label.SemanticContext; // if ( ctx.toString().indexOf("synpred")>=0 ) { // System.out.println("has pred "+ctx.toString()+" "+ctx.isSyntacticPredicate()); // System.out.println(((SemanticContext.Predicate)ctx).predicateAST.token); // } if (ctx.IsSyntacticPredicate) return true; } DFAState edgeTarget = (DFAState)t.Target; if (!busy.Contains(edgeTarget) &&CalculateHasSynPred(edgeTarget, busy)) return true; } return false; }
internal virtual bool CalculateHasSemPred(DFAState d, HashSet<DFAState> busy) { busy.Add(d); for (int i = 0; i < d.NumberOfTransitions; i++) { Transition t = d.GetTransition(i); if (t.IsSemanticPredicate) { SemanticContext ctx = t.Label.SemanticContext; if (ctx.HasUserSemanticPredicate) return true; } DFAState edgeTarget = (DFAState)t.Target; if (!busy.Contains(edgeTarget) && CalculateHasSemPred(edgeTarget, busy)) return true; } return false; }
internal virtual bool CalculateHasCycle(DFAState d, IDictionary<DFAState, Cyclic> busy) { busy[d] = Cyclic.Busy; for (int i = 0; i < d.NumberOfTransitions; i++) { Transition t = d.GetTransition(i); DFAState target = (DFAState)t.Target; Cyclic cond; if (!busy.TryGetValue(target, out cond)) cond = Cyclic.Unknown; if (cond == Cyclic.Busy) return true; if (cond != Cyclic.Done && CalculateHasCycle(target, busy)) return true; } busy[d] = Cyclic.Done; return false; }
protected virtual StringTemplate WalkFixedDFAGeneratingStateMachine( TemplateGroup templates, DFA dfa, DFAState s, int k ) { //System.Console.Out.WriteLine( "walk " + s.stateNumber + " in dfa for decision " + dfa.decisionNumber ); if ( s.IsAcceptState ) { StringTemplate dfaST2 = templates.GetInstanceOf( "dfaAcceptState" ); dfaST2.SetAttribute( "alt", s.GetUniquelyPredictedAlt() ); return dfaST2; } // the default templates for generating a state and its edges // can be an if-then-else structure or a switch string dfaStateName = "dfaState"; string dfaLoopbackStateName = "dfaLoopbackState"; string dfaOptionalBlockStateName = "dfaOptionalBlockState"; string dfaEdgeName = "dfaEdge"; if ( _parentGenerator.CanGenerateSwitch( s ) ) { dfaStateName = "dfaStateSwitch"; dfaLoopbackStateName = "dfaLoopbackStateSwitch"; dfaOptionalBlockStateName = "dfaOptionalBlockStateSwitch"; dfaEdgeName = "dfaEdgeSwitch"; } StringTemplate dfaST = templates.GetInstanceOf( dfaStateName ); if ( dfa.NFADecisionStartState.decisionStateType == NFAState.LOOPBACK ) { dfaST = templates.GetInstanceOf( dfaLoopbackStateName ); } else if ( dfa.NFADecisionStartState.decisionStateType == NFAState.OPTIONAL_BLOCK_START ) { dfaST = templates.GetInstanceOf( dfaOptionalBlockStateName ); } dfaST.SetAttribute( "k", k ); dfaST.SetAttribute( "stateNumber", s.StateNumber ); dfaST.SetAttribute( "semPredState", s.IsResolvedWithPredicates ); /* string description = dfa.getNFADecisionStartState().Description; description = parentGenerator.target.getTargetStringLiteralFromString( description ); //System.Console.Out.WriteLine( "DFA: " + description + " associated with AST " + dfa.getNFADecisionStartState() ); if ( description != null ) { dfaST.SetAttribute( "description", description ); } */ int EOTPredicts = NFA.INVALID_ALT_NUMBER; DFAState EOTTarget = null; //System.Console.Out.WriteLine( "DFA state " + s.stateNumber ); for ( int i = 0; i < s.NumberOfTransitions; i++ ) { Transition edge = (Transition)s.GetTransition( i ); //System.Console.Out.WriteLine( "edge " + s.stateNumber + "-" + edge.label.ToString() + "->" + edge.target.stateNumber ); if ( edge.Label.Atom == Label.EOT ) { // don't generate a real edge for EOT; track alt EOT predicts // generate that prediction in the else clause as default case EOTTarget = (DFAState)edge.Target; EOTPredicts = EOTTarget.GetUniquelyPredictedAlt(); /* System.Console.Out.WriteLine("DFA s"+s.stateNumber+" EOT goes to s"+ edge.target.stateNumber+" predicates alt "+ EOTPredicts); */ continue; } StringTemplate edgeST = templates.GetInstanceOf( dfaEdgeName ); // If the template wants all the label values delineated, do that if ( edgeST.impl.TryGetFormalArgument( "labels" ) != null ) { List<string> labels = edge.Label.Set.Select( value => _parentGenerator.GetTokenTypeAsTargetLabel( value ) ).ToList(); edgeST.SetAttribute( "labels", labels ); } else { // else create an expression to evaluate (the general case) edgeST.SetAttribute( "labelExpr", _parentGenerator.GenLabelExpr( templates, edge, k ) ); } // stick in any gated predicates for any edge if not already a pred if ( !edge.Label.IsSemanticPredicate ) { DFAState target = (DFAState)edge.Target; SemanticContext preds = target.GetGatedPredicatesInNFAConfigurations(); if ( preds != null ) { //System.Console.Out.WriteLine( "preds=" + target.getGatedPredicatesInNFAConfigurations() ); StringTemplate predST = preds.GenExpr( _parentGenerator, _parentGenerator.Templates, dfa ); edgeST.SetAttribute( "predicates", predST ); } } StringTemplate targetST = WalkFixedDFAGeneratingStateMachine( templates, dfa, (DFAState)edge.Target, k + 1 ); edgeST.SetAttribute( "targetState", targetST ); dfaST.SetAttribute( "edges", edgeST ); //System.Console.Out.WriteLine( "back to DFA " + dfa.decisionNumber + "." + s.stateNumber ); } // HANDLE EOT EDGE if ( EOTPredicts != NFA.INVALID_ALT_NUMBER ) { // EOT unique predicts an alt dfaST.SetAttribute( "eotPredictsAlt", EOTPredicts ); } else if ( EOTTarget != null && EOTTarget.NumberOfTransitions > 0 ) { // EOT state has transitions so must split on predicates. // Generate predicate else-if clauses and then generate // NoViableAlt exception as else clause. // Note: these predicates emanate from the EOT target state // rather than the current DFAState s so the error message // might be slightly misleading if you are looking at the // state number. Predicates emanating from EOT targets are // hoisted up to the state that has the EOT edge. for ( int i = 0; i < EOTTarget.NumberOfTransitions; i++ ) { Transition predEdge = (Transition)EOTTarget.GetTransition( i ); StringTemplate edgeST = templates.GetInstanceOf( dfaEdgeName ); edgeST.SetAttribute( "labelExpr", _parentGenerator.GenSemanticPredicateExpr( templates, predEdge ) ); // the target must be an accept state //System.Console.Out.WriteLine( "EOT edge" ); StringTemplate targetST = WalkFixedDFAGeneratingStateMachine( templates, dfa, (DFAState)predEdge.Target, k + 1 ); edgeST.SetAttribute( "targetState", targetST ); dfaST.SetAttribute( "edges", edgeST ); } } return dfaST; }
protected virtual void CreateMinMaxTables( DFAState s ) { int smin = Label.MAX_CHAR_VALUE + 1; int smax = Label.MIN_ATOM_VALUE - 1; for ( int j = 0; j < s.NumberOfTransitions; j++ ) { Transition edge = (Transition)s.GetTransition( j ); Label label = edge.Label; if ( label.IsAtom ) { if ( label.Atom >= Label.MIN_CHAR_VALUE ) { if ( label.Atom < smin ) { smin = label.Atom; } if ( label.Atom > smax ) { smax = label.Atom; } } } else if ( label.IsSet ) { IntervalSet labels = (IntervalSet)label.Set; int lmin = labels.GetMinElement(); // if valid char (don't do EOF) and less than current min if ( lmin < smin && lmin >= Label.MIN_CHAR_VALUE ) { smin = labels.GetMinElement(); } if ( labels.GetMaxElement() > smax ) { smax = labels.GetMaxElement(); } } } if ( smax < 0 ) { // must be predicates or pure EOT transition; just zero out min, max smin = Label.MIN_CHAR_VALUE; smax = Label.MIN_CHAR_VALUE; } _min[s.StateNumber] = (char)smin; _max[s.StateNumber] = (char)smax; if ( smax < 0 || smin > Label.MAX_CHAR_VALUE || smin < 0 ) { ErrorManager.InternalError( "messed up: min=" + _min + ", max=" + _max ); } }
protected virtual void OptimizeEOTBranches( DFAState state ) { if (state == null) throw new ArgumentNullException("state"); int sI = state.StateNumber; if ( _visited.Contains( sI ) ) { return; // already visited } _visited.Add( sI ); for ( int i = 0; i < state.NumberOfTransitions; i++ ) { Transition edge = state.GetTransition( i ); DFAState edgeTarget = ( (DFAState)edge.Target ); /* [email protected](d.stateNumber+"-"+ edge.label.toString(d.dfa.nfa.grammar)+"->"+ edgeTarget.stateNumber); */ // if only one edge coming out, it is EOT, and target is accept prune if ( PRUNE_TOKENS_RULE_SUPERFLUOUS_EOT_EDGES && edgeTarget.IsAcceptState && state.NumberOfTransitions == 1 && edge.Label.IsAtom && edge.Label.Atom == Label.EOT ) { //[email protected]("state "+d+" can be pruned"); // remove the superfluous EOT edge state.RemoveTransition( i ); state.IsAcceptState = true; // make it an accept state // force it to uniquely predict the originally predicted state state.CachedUniquelyPredicatedAlt = edgeTarget.GetUniquelyPredictedAlt(); i--; // back up one so that i++ of loop iteration stays within bounds } OptimizeEOTBranches( edgeTarget ); } }