anchor.diff:  }
   
   //
  +type internal Lr0Item<'NonterminalId, 'Token
  +        when 'NonterminalId : comparison
  +        and 'Token : comparison> = {
  +    //
  +    Nonterminal : 'NonterminalId;
  +    //
  +    Production : Symbol<'NonterminalId, 'Token>[];
  +    //
  +    Position : int<ParserPosition>;
  +} with
  +    override this.ToString () =
  +        let productionString =
  +            let sb = System.Text.StringBuilder ()
  +            for i = 0 to Array.length this.Production do
  +                if i < int this.Position then
  +                    this.Production.[i].ToString ()
  +                    |> sb.Append |> ignore
  +                elif i = int this.Position then
  +                    // Append the dot character representing the parser position.
  +                    sb.Append "\u2022" |> ignore
  +                else
  +                    this.Production.[i - 1].ToString ()
  +                    |> sb.Append |> ignore
  +
  +            sb.ToString ()
  +
  +        sprintf "%O \u2192 %s" this.Nonterminal productionString
  +
  +//
  +type internal ParserState<'NonterminalId, 'Token
  +        when 'NonterminalId : comparison
  +        and 'Token : comparison> = Set<Lr0Item<'NonterminalId, 'Token>>
  +
  +/// LR(0) parser table generation state.
  +type internal Lr0TableGenState<'NonterminalId, 'Token
  +        when 'NonterminalId : comparison
  +        and 'Token : comparison> = {
  +    //
  +    Table : Map<LrParserStateId * Symbol<'NonterminalId, 'Token>, Set<LrParserTableAction>>;
  +    //
  +    ParserStates : Map<ParserState<'NonterminalId, 'Token>, LrParserStateId>;
  +    //
  +    ReductionRules : Map<'NonterminalId * Symbol<'NonterminalId, 'Token>[], LrReductionRuleId>;
  +    //
  +    ReductionRulesById : Map<LrReductionRuleId, 'NonterminalId * Symbol<'NonterminalId, 'Token>[]>;
  +}
  +
  +//
  +[<RequireQualifiedAccess; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  +module internal Lr0TableGenState =
  +    /// Returns an empty Lr0TableGenState with the given
  +    /// nonterminal and terminal types.
  +    let empty : Lr0TableGenState<'NonterminalId, 'Token> = {
  +        Table = Map.empty;
  +        ParserStates = Map.empty;
  +        ReductionRules = Map.empty;
  +        ReductionRulesById = Map.empty; }
  +
  +    /// Retrives the identifier for a given parser state (set of items).
  +    /// If the state has not been assigned an identifier, one is created
  +    /// and added to the table-generation state before returning.
  +    let stateId (parserState : ParserState<'NonterminalId, 'Token>) (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  +        // Try to retrieve an existing id for this state.
  +        match Map.tryFind parserState tableGenState.ParserStates with
  +        | Some parserStateId ->
  +            parserStateId, tableGenState
  +
  +        | None ->
  +            // Create a new ID for this state.
  +            let parserStateId = LanguagePrimitives.Int32WithMeasure <| tableGenState.ParserStates.Count + 1
  +
  +            // Return the id, along with the updated table-gen state.
  +            parserStateId,
  +            { tableGenState with
  +                ParserStates = Map.add parserState parserStateId tableGenState.ParserStates; }
  +
  +    //
  +    let reductionRuleId (reductionRule : 'NonterminalId * Symbol<'NonterminalId, 'Token>[]) (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  +        // Reduction rules should only be added, but for safety we'll check to
  +        // see if the rule has already been assigned an identifier.
  +        match Map.tryFind reductionRule tableGenState.ReductionRules with
  +        | Some reductionRuleId ->
  +            reductionRuleId, tableGenState
  +
  +        | None ->
  +            // Create a new ID for this reduction rule.
  +            let reductionRuleId = LanguagePrimitives.Int32WithMeasure <| tableGenState.ReductionRules.Count + 1
  +
  +            // Return the id, along with the updated table-gen state.
  +            reductionRuleId,
  +            { tableGenState with
  +                ReductionRules = Map.add reductionRule reductionRuleId tableGenState.ReductionRules;
  +                ReductionRulesById = Map.add reductionRuleId reductionRule tableGenState.ReductionRulesById; }
  +
  +    /// Add a 'shift' action to the parser table.
  +    let shift (sourceState : LrParserStateId)
  +                (transitionSymbol : 'Token)
  +                (targetState : LrParserStateId)
  +                (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  +        //
  +        let tableKey = sourceState, Symbol.Terminal transitionSymbol
  +
  +        //
  +        let entry =
  +            let action = Shift targetState
  +            match Map.tryFind tableKey tableGenState.Table with
  +            | None ->
  +                Set.singleton action
  +            | Some entry ->
  +                Set.add action entry
  +
  +        // Update the table with the new entry.
  +        (),
  +        { tableGenState with
  +            Table = Map.add tableKey entry tableGenState.Table; }
  +
  +    /// Add a 'goto' action to the parser table.
  +    let goto (sourceState : LrParserStateId)
  +                (transitionSymbol : 'NonterminalId)
  +                (targetState : LrParserStateId)
  +                (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  +        //
  +        let tableKey = sourceState, Symbol.Nonterminal transitionSymbol
  +
  +        //
  +        let entry =
  +            let action = Goto targetState
  +            match Map.tryFind tableKey tableGenState.Table with
  +            | None ->
  +                Set.singleton action
  +            | Some entry ->
  +                Set.add action entry
  +
  +        // Update the table with the new entry.
  +        (),
  +        { tableGenState with
  +            Table = Map.add tableKey entry tableGenState.Table; }
  +
  +    /// Add an 'accept' action to the parser table.
  +    let accept (sourceState : LrParserStateId) (tableGenState : Lr0TableGenState<'NonterminalId, AugmentedTerminal<'Token>>) =
  +        //
  +        let tableKey = sourceState, Symbol.Terminal EndOfFile
  +
  +        //
  +        let entry =
  +            match Map.tryFind tableKey tableGenState.Table with
  +            | None ->
  +                // Create a new 'accept' action for this table entry.
  +                Set.singleton Accept
  +            | Some entry ->
  +                // Create a new 'accept' action and add it to the existing table entry.
  +                Set.add Accept entry
  +
  +        // Update the table with the new entry.
  +        (),
  +        { tableGenState with
  +            Table = Map.add tableKey entry tableGenState.Table; }
  +
  +    /// Add 'reduce' actions to the parser table for each terminal (token) in the grammar.
  +    let reduce (sourceState : LrParserStateId) (reductionRuleId : LrReductionRuleId) (terminals : Set<_>) (tableGenState : Lr0TableGenState<'NonterminalId, AugmentedTerminal<'Token>>) =
  +        // Fold over the set of terminals (tokens) in the grammar.
  +        let table =
  +            (tableGenState.Table, terminals)
  +            ||> Set.fold (fun table token ->
  +                //
  +                let tableKey = sourceState, Symbol.Terminal token
  +
  +                //
  +                let entry =
  +                    let action = Reduce reductionRuleId
  +                    match Map.tryFind tableKey table with
  +                    | None ->
  +                        Set.singleton action
  +                    | Some entry ->
  +                        Set.add action entry
  +
  +                // Update the table with the entry.
  +                Map.add tableKey entry table)
  +
  +        // Return the updated table-gen state.
  +        (),
  +        { tableGenState with
  +            Table = table; }
  +
  +//
   [<RequireQualifiedAccess>]
   module Lr0 =
  -    //
  -    type private Lr0Item<'NonterminalId, 'Token
  -            when 'NonterminalId : comparison
  -            and 'Token : comparison> = {
  -        //
  -        Nonterminal : 'NonterminalId;
  -        //
  -        Production : Symbol<'NonterminalId, 'Token>[];
  -        //
  -        Position : int<ParserPosition>;
  -    }
  -
  -    //
  -    type private ParserState<'NonterminalId, 'Token
  -            when 'NonterminalId : comparison
  -            and 'Token : comparison> = Set<Lr0Item<'NonterminalId, 'Token>>
  -
  -    /// LR(0) parser table generation state.
  -    type private Lr0TableGenState<'NonterminalId, 'Token
  -            when 'NonterminalId : comparison
  -            and 'Token : comparison> = {
  -        //
  -        Table : Map<LrParserStateId * Symbol<'NonterminalId, 'Token>, Set<LrParserTableAction>>;
  -        //
  -        ParserStates : Map<ParserState<'NonterminalId, 'Token>, LrParserStateId>;
  -        //
  -        ReductionRules : Map<'NonterminalId * Symbol<'NonterminalId, 'Token>[], LrReductionRuleId>;
  -        //
  -        ReductionRulesById : Map<LrReductionRuleId, 'NonterminalId * Symbol<'NonterminalId, 'Token>[]>;
  -    }
  -
  -    //
  -    [<RequireQualifiedAccess; CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  -    module private Lr0TableGenState =
  -        /// Returns an empty Lr0TableGenState with the given
  -        /// nonterminal and terminal types.
  -        let empty : Lr0TableGenState<'NonterminalId, 'Token> = {
  -            Table = Map.empty;
  -            ParserStates = Map.empty;
  -            ReductionRules = Map.empty;
  -            ReductionRulesById = Map.empty; }
  -
  -        /// Retrives the identifier for a given parser state (set of items).
  -        /// If the state has not been assigned an identifier, one is created
  -        /// and added to the table-generation state before returning.
  -        let stateId (parserState : ParserState<'NonterminalId, 'Token>) (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  -            // Try to retrieve an existing id for this state.
  -            match Map.tryFind parserState tableGenState.ParserStates with
  -            | Some parserStateId ->
  -                parserStateId, tableGenState
  -
  -            | None ->
  -                // Create a new ID for this state.
  -                let parserStateId = LanguagePrimitives.Int32WithMeasure <| tableGenState.ParserStates.Count + 1
  -
  -                // Return the id, along with the updated table-gen state.
  -                parserStateId,
  -                { tableGenState with
  -                    ParserStates = Map.add parserState parserStateId tableGenState.ParserStates; }
  -
  -        //
  -        let reductionRuleId (reductionRule : 'NonterminalId * Symbol<'NonterminalId, 'Token>[]) (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  -            // Reduction rules should only be added, but for safety we'll check to
  -            // see if the rule has already been assigned an identifier.
  -            match Map.tryFind reductionRule tableGenState.ReductionRules with
  -            | Some reductionRuleId ->
  -                reductionRuleId, tableGenState
  -
  -            | None ->
  -                // Create a new ID for this reduction rule.
  -                let reductionRuleId = LanguagePrimitives.Int32WithMeasure <| tableGenState.ReductionRules.Count + 1
  -
  -                // Return the id, along with the updated table-gen state.
  -                reductionRuleId,
  -                { tableGenState with
  -                    ReductionRules = Map.add reductionRule reductionRuleId tableGenState.ReductionRules;
  -                    ReductionRulesById = Map.add reductionRuleId reductionRule tableGenState.ReductionRulesById; }
  -
  -        /// Add a 'shift' action to the parser table.
  -        let shift (sourceState : LrParserStateId)
  -                    (transitionSymbol : 'Token)
  -                    (targetState : LrParserStateId)
  -                    (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  -            //
  -            let tableKey = sourceState, Symbol.Terminal transitionSymbol
  -
  -            //
  -            let entry =
  -                let action = Shift targetState
  -                match Map.tryFind tableKey tableGenState.Table with
  -                | None ->
  -                    Set.singleton action
  -                | Some entry ->
  -                    Set.add action entry
  -
  -            // Update the table with the new entry.
  -            (),
  -            { tableGenState with
  -                Table = Map.add tableKey entry tableGenState.Table; }
  -
  -        /// Add a 'goto' action to the parser table.
  -        let goto (sourceState : LrParserStateId)
  -                    (transitionSymbol : 'NonterminalId)
  -                    (targetState : LrParserStateId)
  -                    (tableGenState : Lr0TableGenState<'NonterminalId, 'Token>) =
  -            //
  -            let tableKey = sourceState, Symbol.Nonterminal transitionSymbol
  -
  -            //
  -            let entry =
  -                let action = Goto targetState
  -                match Map.tryFind tableKey tableGenState.Table with
  -                | None ->
  -                    Set.singleton action
  -                | Some entry ->
  -                    Set.add action entry
  -
  -            // Update the table with the new entry.
  -            (),
  -            { tableGenState with
  -                Table = Map.add tableKey entry tableGenState.Table; }
  -
  -        /// Add an 'accept' action to the parser table.
  -        let accept (sourceState : LrParserStateId) (tableGenState : Lr0TableGenState<'NonterminalId, AugmentedTerminal<'Token>>) =
  -            //
  -            let tableKey = sourceState, Symbol.Terminal EndOfFile
  -
  -            //
  -            let entry =
  -                match Map.tryFind tableKey tableGenState.Table with
  -                | None ->
  -                    // Create a new 'accept' action for this table entry.
  -                    Set.singleton Accept
  -                | Some entry ->
  -                    // Create a new 'accept' action and add it to the existing table entry.
  -                    Set.add Accept entry
  -
  -            // Update the table with the new entry.
  -            (),
  -            { tableGenState with
  -                Table = Map.add tableKey entry tableGenState.Table; }
  -
  -        /// Add 'reduce' actions to the parser table for each terminal (token) in the grammar.
  -        let reduce (sourceState : LrParserStateId) (reductionRuleId : LrReductionRuleId) (terminals : Set<_>) (tableGenState : Lr0TableGenState<'NonterminalId, AugmentedTerminal<'Token>>) =
  -            // Fold over the set of terminals (tokens) in the grammar.
  -            let table =
  -                (tableGenState.Table, terminals)
  -                ||> Set.fold (fun table token ->
  -                    //
  -                    let tableKey = sourceState, Symbol.Terminal token
  -
  -                    //
  -                    let entry =
  -                        let action = Reduce reductionRuleId
  -                        match Map.tryFind tableKey table with
  -                        | None ->
  -                            Set.singleton action
  -                        | Some entry ->
  -                            Set.add action entry
  -
  -                    // Update the table with the entry.
  -                    Map.add tableKey entry table)
  -
  -            // Return the updated table-gen state.
  -            (),
  -            { tableGenState with
  -                Table = table; }
  -
  -    
       /// Computes the LR(0) closure of a set of items.
  -    let private closure (productions : Map<'NonterminalId, Set<Symbol<'NonterminalId, 'Token>[]>>) items =
  +    let internal closure (productions : Map<'NonterminalId, Set<Symbol<'NonterminalId, 'Token>[]>>) items =
           /// Implementation of the LR(0) closure algorithm.
           let rec closure items =
               let items' =
  
positive.code:         createTableImpl grammar initialTableGenState
  
  
  //    let test (grammar : Grammar<_,_>) =
  //        let state3StartItem = {
  //            Nonterminal = 'S';
  //            Production =
  //                [|
  //                Ast.Terminal "(";
  //                Ast.Nonterminal 'L';
  //                Ast.Terminal ")"; |]
  //            Position = 1<_>; }
  //
  //        let state3Closure =
  //            closure (Set.singleton state3StartItem) grammar.Productions
  //
  //        ()
  
  
  
negative.code: 
      /// Moves the 'dot' (the current parser position) past the
      /// specified symbol for each item in a set of items.
      let internal goto symbol items (productions : Map<'NonterminalId, Set<Symbol<'NonterminalId, 'Token>[]>>) =
          /// The updated 'items' set.
          let items =
              (Set.empty, items)
  