anchor.diff:  
   let Q = Set.union_all (Set.of_list[Item('S',[NTerm('E');Dot(' ',1)])]::items)
   
  -
   let getText a (x,y,z)= 
       match a 
       with 
       |Term(t) -> if x = 0 then ' ' else t 
       |NTerm(t)-> if y = 0 then ' ' else t
       |Dot(t,i)  -> if z = 0 then ' ' else t 
  -    
       
   //запоминалка. Используем для запоминания результатов ф-ий parse и climb   
   let memoize (f: 'a ->'b) =
  
positive.code: let closure_set = 
      let t = System.Collections.Generic.Dictionary<item,Set<item>>()
      in
      Set.map (fun x -> t.Add(x,closure (Set.add  x empty)))Q;
      t
  
  let goto_set = 
  
negative.code:     in
      let t = System.Collections.Generic.Dictionary<(item*char),Set<item>>() 
      in
      List.iter (fun x-> (Set.iter (fun y-> t.Add((y,x),(make_goto (add y empty)) x)))Q) lex_list;
      t  
  //это предпросчёт goto. сам анализатор тогда работает быстрее. (closure - очень дорогая операция)           
  let goto (q,x) = union_all (Set.map (fun y -> goto_set.[(y,x)])q )
                         
  let ItNext (Item(a,lst)) = Item(a,next lst)
  let ItPrev (Item(a,lst)) = Item(a,prev lst)
     
  let union_from_Some set = set |> List.filter Option.is_some |> List.map Option.get |> Set.of_list                              
     
  do printfn "End time: %A Total: %A" System.DateTime.UtcNow (System.DateTime.UtcNow - (!start_time))
  
  let rec climb =
      memoize (fun (q,x,i) -> 
      if debug then print_climb_1 i x q;
      if q = empty
      then empty
      else
      let gt =  goto (q,x)
      in
      if debug then print_climb_2 gt;
      let new_q = parse (gt,i)
      in 
      if debug then print_climb_3 new_q;
      if Set.exists (fun x->x = (Item('S',[NTerm('E');Dot(' ',1)]),[]))new_q
      then new_q
      else    
      Set.union_all
      [Set.filter (fun x1-> 
                     Set.exists (fun (Item(ch,lst) as y) -> 
                                     (ItNext y) = (fst x1)
                                     &&(function Dot(_)::tl-> false
                                                |[]        -> false
                                                | _        -> true)lst
                                 )q)new_q
       |>Set.map (fun x1->((ItPrev (fst x1)),snd x1))                      
      
      ;
      Set.union_all(
      union_from_Some[for (Item(a,hd::tl),str) in new_q -> 
                          if getText hd (1,1,1)=x &&(a<>'S')&&(function Dot(_)::tl->true | _ -> false)tl
                          then Some(climb (q, a, str))
                          else None])
      ])                
  
  and parse = 
      memoize (fun (q,i) -> 
      if debug  then print_parse q i;    
      union_all
          [map (fun x -> (x,i))(Set.filter (fun(Item(a,lst))-> (List.hd (List.rev lst)) = Dot(' ',1))q)
           ;if i = [] then empty else climb (q,  (List.hd i), (List.tl i))
           ;union_from_Some[for (Item(a,lst)) in Q -> match lst 
                                                      with
                                                      | NTerm('`')::[]->Some (climb (q, a, i))
                                                      | _             ->None]|> union_all 
           ])
                   
  let res str = 
      start_time:=System.DateTime.UtcNow;
      printfn "Start time: %A" System.DateTime.UtcNow;
      not(parse (items.Head,Seq.to_list str)=empty)
   
  let test_str1 = "a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))*a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))"
  
  let test_str2 = "a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))*a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))+a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))*a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))"
  
  let test_str3 = "a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))*a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))+a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))*a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))+a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))*a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))+a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))*a+a*a*(a+a)*a+a*a*(a+a)+a*a*(a+a)*a+a*a*(a+a)+a+a*a*(a+a)*a+a*a*(a+a)+(a*a*(a+a)*a+a*a*(a+a))"
       
  do let str = 
         if interacive
         then 
          (Console.WriteLine("Insert string:"); 
          Console.ReadLine())
         else
          test_str2 
     in     
     let r = res(str) in
     printfn "Result : %A" r;
     Console.WriteLine();
     printfn "End time: %A Total: %A" System.DateTime.UtcNow (System.DateTime.UtcNow - (!start_time));   
     Console.ReadLine()|>ignore