anchor.diff:              if (pos > 0)
               then
                   for e in outEdgesInnerGraph.[startV.vNum] do
  -                    let arr = parserSource.Reduces.[state].[parserSource.TokenToNumber e.Tag]
  -                    if arr <> null then
  -                        for (prod, pos) in arr do
  -                            startV.AddReduction(new Reduction(newVertex, prod, pos, Some edge))
  +                    addNonZeroReduction newVertex state e.Tag edge startV
                   if startV.reductions.Count > 0 then customEnqueue startV
               addChildren nodes.[nodes.Count - 1] path prod
   
  
positive.code:                     targetGssV.addEdge edge
  
                  for e2 in outEdgesInnerGraph.[e.Target.vNum] do
                      let arr = parserSource.ZeroReduces.[push].[parserSource.TokenToNumber e2.Tag]
                      if arr <> null then
                          for prod in arr do
                              reductions.Add(new Reduction(targetGssV, prod, 0, None), e.Target)
  
                      let arr = parserSource.Reduces.[push].[parserSource.TokenToNumber e2.Tag]
                      if arr <> null then
                          for (prod, pos) in arr do
                              //printf "%A %A %d %d\n" v.label v.outEdges prod pos
                              reductions.Add(new Reduction(gssVertex, prod, pos, Some edge), e.Target)
  
              let arr = parserSource.ZeroReduces.[state].[parserSource.TokenToNumber e.Tag]
              if arr <> null then
                  customEnqueue currentGraphV
                  for prod in arr do
                      reductions.Add(new Reduction(gssVertex, prod, 0, None), currentGraphV)
          
          let reductionSet = new ResizeArray<Reduction * VInfo<_>>(10)
          for r, target in reductions do
              let reductionExists = 
                  reductionSet
                  |> ResizeArray.exists(function red, _ -> red = r)
              if not reductionExists then reductionSet.Add(r, target)
          for r, target in reductionSet do
              target.AddReduction(r)
          
          if not <| currentGraphV.processedGssVertices.Contains(gssVertex)
          then 
              currentGraphV.processedGssVertices.Add(gssVertex)
          newUnprocessedGssVs
  
      let (*inline*) addVertex (currentGraphV:VInfo<_>) state =
          let mutable v = null
          let mutable isNew = false
          let vOpt = currentGraphV.processedGssVertices |> ResizeArray.tryFind (fun v -> v.State = state)
          match vOpt with
          | None ->
              let vOpt = currentGraphV.unprocessedGssVertices |> ResizeArray.tryFind (fun v -> v.State = state)
              match vOpt with
              | None ->
                  v <- new Vertex(state, currentGraphV.vNum)
                  isNew <- true
                  currentGraphV.unprocessedGssVertices.Add v
              |Some x -> v <- x
          |Some x -> 
              v <- x
          v, isNew
      
      let verticesToRecalc = new ResizeArray<_> (10)
  
      let (*inline*) addChildren node (path : Path) prod =
  
negative.code:     new (edge) = new Path (edge, null, 1)
  
  let buildAstAbstract<'TokenType> (parserSource : ParserSource<'TokenType>) (tokens : ParserInputGraph<'TokenType>) =
      let startV, finalV, innerGraph =
          let verticesMap = Array.zeroCreate (Seq.max tokens.Vertices + 1)            
          for i in tokens.Vertices do
               verticesMap.[i] <- new VInfo<_> (i)
          let g = new QuickGraph.AdjacencyGraph<_,_>()
          tokens.Edges 
          |> Seq.map (fun e -> new QuickGraph.TaggedEdge<_,_>(verticesMap.[e.Source], verticesMap.[e.Target], e.Tag))
          |> g.AddVerticesAndEdgeRange
          |> ignore
          verticesMap.[tokens.InitState], verticesMap.[tokens.FinalState], g
      
      let nodes = new BlockResizeArray<AstNode>()
      let terminals = new BlockResizeArray<'TokenType>()
      let startState = 0
      let inline getEpsilon i = new Epsilon(-1-i)
      let startNonTerm = parserSource.LeftSide.[parserSource.StartRule]
      let verticesToProcess = new Queue<_>()
      verticesToProcess.Enqueue (startV)
      let mutable errorIndex = -1
      let outEdgesInnerGraph = Array.init (Seq.max tokens.Vertices + 1) (fun _ -> [||])
      for v in innerGraph.Vertices do
          outEdgesInnerGraph.[v.vNum] <- innerGraph.OutEdges v |> Array.ofSeq
      
      let customEnqueue (elem : VInfo<_>) =
          if verticesToProcess.Count = 0 || ((verticesToProcess.ElementAt (verticesToProcess.Count - 1)).vNum = elem.vNum |> not)
          then
              verticesToProcess.Enqueue(elem)
      
      let (*inline*) addVertex (currentGraphV:VInfo<_>) state (listToAddUnprocessedGssV : ResizeArray<_>) =
          let mutable v = null
          let mutable isNew = false
          let vOpt = currentGraphV.processedGssVertices |> ResizeArray.tryFind (fun v -> v.State = state)
          match vOpt with
          | Some x -> v <- x
          | None ->
              let vOpt = currentGraphV.unprocessedGssVertices |> ResizeArray.tryFind (fun v -> v.State = state)
              match vOpt with
              | Some x -> v <- x
              | None ->
                  v <- new Vertex(state, currentGraphV.vNum)
                  isNew <- true
                  listToAddUnprocessedGssV.Add v
          v, isNew
  
      let addNonZeroReduction gssVertex state token gssEdge (innerGraphV : VInfo<_>)=
          let arr = parserSource.Reduces.[state].[parserSource.TokenToNumber token]
          if arr <> null 
          then
              for (prod, pos) in arr do
                  innerGraphV.AddReduction(new Reduction(gssVertex, prod, pos, Some gssEdge))
  
      let addZeroReduction gssVertex state token (innerGraphV : VInfo<_>) shouldEnqueue =
          let arr = parserSource.ZeroReduces.[state].[parserSource.TokenToNumber token]
          if arr <> null
          then
              for prod in arr do
                  innerGraphV.AddReduction(new Reduction(gssVertex, prod, 0, None))
              if shouldEnqueue then customEnqueue innerGraphV
  
      let edgesToTerms = new Dictionary<_,_>()
      let push (currentGraphV:VInfo<_>) gssVertex state =
          let newUnprocessedGssVs = new ResizeArray<_>(2)
          for e in outEdgesInnerGraph.[currentGraphV.vNum] do
              let push = parserSource.Gotos.[state].[parserSource.TokenToNumber e.Tag]
              if push <> 0 
              then
                  let targetGssV, isNew = addVertex e.Target push (if currentGraphV.vNum = e.Target.vNum then newUnprocessedGssVs else e.Target.unprocessedGssVertices)
  
                  if not <| edgesToTerms.ContainsKey e
                  then
                      terminals.Add e.Tag
                      nodes.Add <| Terminal (terminals.Count - 1)
                      edgesToTerms.Add(e, nodes.Count - 1)
  
                  let edge = new Edge(gssVertex, edgesToTerms.[e])
  
                  if targetGssV.FindIndex gssVertex.State gssVertex.Level = -1
                  then
  