anchor.diff:  open LanguagePrimitives
   open ExtCore
   open ExtCore.Collections
  +open ExtCore.Control
   open SpecializedCollections
   open Graph
   open Regex
  
positive.code:     //
      Transitions : LexerDfaGraph;
      /// Final (accepting) DFA states.
      FinalStates : Set<DfaStateId>;
      /// Maps regular vectors to the DFA state representing them.
      RegularVectorToDfaState : Map<RegularVector, DfaStateId>;
      /// Maps a DFA state to the regular vector it represents.
      DfaStateToRegularVector : Map<DfaStateId, RegularVector>;
  }
  
  
negative.code:         else
              Choice1Of2 <| results.ToArray ()
  
      /// The DFA compiled from the rule clause patterns.
      let compiledPatternDfa =
          let regexOriginalClauseIndices, ruleClauseRegexes =
              Array.unzip ruleClauseRegexes
              
          (* TEMP :   For compatibility with fslex, we need to determine the alphabet used
                      by the rule, then rewrite any negated character sets so the transition
                      table is generated in a way that fslex can handle. *)
          let ruleAlphabet =
              ruleClauseRegexes
              |> Array.map getAlphabet
              |> Array.reduce CharSet.union
              // Add the low ASCII characters too, like fslex does.
              |> CharSet.union (CharSet.ofRange (char 0) (char 127))
  
          // Rewrite the regexes so they don't contain negated character sets.
          let ruleClauseRegexes =
              ruleClauseRegexes
              |> Array.map (rewriteNegatedCharSets ruleAlphabet)
  
          rulePatternsToDfa ruleClauseRegexes regexOriginalClauseIndices options
  
      // If this rule has a pattern accepting the end-of-file marker,
      // create an additional DFA state to serve as the EOF-accepting state
      // and create a transition edge labeled with the EOF symbol to it.
      let compiledPatternDfa =
          match eofAcceptingClauseIndex with
          | None ->
              compiledPatternDfa
          | Some eofAcceptingClauseIndex ->
              let eofAcceptingState, transitions =
                  LexerDfaGraph.createVertex compiledPatternDfa.Transitions
              let transitions =
                  LexerDfaGraph.addEofEdge compiledPatternDfa.InitialState eofAcceptingState transitions
              { compiledPatternDfa with
                  Transitions = transitions;
                  RuleClauseAcceptedByState =
                      compiledPatternDfa.RuleClauseAcceptedByState
                      |> Map.add eofAcceptingState eofAcceptingClauseIndex; }
  
      // If this rule has a clause with the wildcard pattern, create an additional
      // DFA state which accepts any single character which won't be matched by the
      // earlier patterns in the rule.
      let compiledPatternDfa =
          match wildcardAcceptingClauseIndex with
          | None ->
              compiledPatternDfa
          | Some wildcardAcceptingClauseIndex ->
              // TEMP : The way the transition characters are computed here is specific
              // to fslex -- once we implement our own interpreter, we'll have to come
              // up with a backend-specific way to handle this. Perhaps we can just store
              // the wildcard-clause index in the returned DFA, and let the plugins themselves
              // compute the transition characters.
  
              /// The alphabet for this rule.
              let ruleAlphabet =
                  // The alphabet for this rule is the edge-label-set of the transition graph.
                  (CharSet.empty, compiledPatternDfa.Transitions.AdjacencyMap)
                  ||> Map.fold (fun ruleAlphabet _ edgeChars ->
                      CharSet.union ruleAlphabet edgeChars)
  
              /// The set of characters labelling the out-edges of the initial DFA state.
              let initialEdgeLabels =
                  (CharSet.empty, compiledPatternDfa.Transitions.AdjacencyMap)
                  ||> Map.fold (fun initialEdgeLabels edgeKey edgeChars ->
                      // We only care about out-edges from the initial DFA state.
                      if edgeKey.Source = compiledPatternDfa.InitialState then
                          CharSet.union initialEdgeLabels edgeChars
                      else
                          initialEdgeLabels)
  
              /// The characters matched by this rule's wildcard pattern.
              let wildcardChars =
                  // Augment the rule alphabet with the low ASCII characters,
                  // because that's how fslex does it and we need to be compatible (for now).
                  let ruleAlphabet =
                      CharSet.ofRange (char 0) (char 127)
                      |> CharSet.union ruleAlphabet
  
                  CharSet.difference ruleAlphabet initialEdgeLabels
  
              // If the set of characters matched by the wildcard pattern is not empty,
              // create a new DFA state which accepts the wildcard pattern, then add
              // transition edges to it from the initial state.
              if CharSet.isEmpty wildcardChars then
                  // TODO : Emit a warning to let the user know this pattern will never be matched.
                  Debug.WriteLine "Warning: Wildcard pattern in rule will never be matched."
  
                  compiledPatternDfa
              else
                  let wildcardAcceptingState, transitions =
                      LexerDfaGraph.createVertex compiledPatternDfa.Transitions
                  let transitions =
                      LexerDfaGraph.addEdges compiledPatternDfa.InitialState wildcardAcceptingState wildcardChars transitions
  
                  { compiledPatternDfa with
                      Transitions = transitions;
                      RuleClauseAcceptedByState =
                          compiledPatternDfa.RuleClauseAcceptedByState
                          |> Map.add wildcardAcceptingState wildcardAcceptingClauseIndex; }
  
      // TODO : Emit warnings about any overlapping patterns.
      // E.g., "This pattern will never be matched."
  
      // Create a CompiledRule record from the compiled DFA.
      return {
          Dfa = compiledPatternDfa;
          Parameters =
              // Reverse the list so it's in the correct left-to-right order.
              List.rev rule.Parameters
              |> List.toArray;
          RuleClauseActions =
              ruleClauses
              |> Array.map (fun clause ->
                  clause.Action); }
      }
  
  
  /// A compiled lexer specification.
  