docs: function(){
              var self = this,
                  item0 = new DataTypes.Item(self.productions[0], 0, [self.EOF]),  //S' -> S #dotPos=0
                  itemSet0 = new DataTypes.ItemSet();
  
              itemSet0.push(item0);
  
              var firstItemSet = self._closureItemSet(itemSet0),
                  itemSets = this.itemSets = [],
                  itemSetsHash = {},      //这个hash是为了判断项集是否已存在(在closure扩展项集之前生成key来判断)
                  itemSet,
                  formState,
                  curIdx,
                  dotSymbolHash;         //这个hash是为了基于当前项集 和 各子项的dotSymbol进行goto运算时，避免已经goto运算过的dotSymbol再次运算
  
              //为什么是itemSet0.key() 不是firstItemSet.key()
              //因为要用仅包含内核项的项集做KEY，下次GOTO运算的结果项集在未CLOSURE运算前，
              //就能判断是否已经存在于项集族中，如果已存在，就直接拿到ID，否则进行CLOSURE运算增加到项集族中
              //避免没必要的CLOSURE计算
              itemSetsHash[itemSet0.key()] = 0;       
  
              itemSets.push(firstItemSet);
  
              curIdx=0;
  
              while(curIdx !== itemSets.length){   //C0 
  
                  itemSet = itemSets[curIdx];
                  curIdx++;
  
                  dotSymbolHash = {};
  
                  _.each(itemSet.subItems, function(item){
  
                      if(item.dotSymbol && !dotSymbolHash[item.dotSymbol]){
  
                          dotSymbolHash[item.dotSymbol] = true;
                          var gotoItemSet = self._gotoItemSet(itemSet, item.dotSymbol);
  
                          if(itemSetsHash[gotoItemSet.key()]){
                              itemSet.gotos[item.dotSymbol] = itemSetsHash[gotoItemSet.key()];
                              self.gotoItemSetRepeatCount = self.gotoItemSetRepeatCount || 0;
                              self.gotoItemSetRepeatCount += 1;
                          }else{
                              itemSetsHash[gotoItemSet.key()] = itemSets.length;
                              if (gotoItemSet.subItems.length){
                                  gotoItemSet = self._closureItemSet(gotoItemSet);
                              }
                              //原itemSet通过该dotSymbol，转换到的新itemSet的序号
                              itemSet.gotos[item.dotSymbol] = itemSets.length;
                              itemSets.push(gotoItemSet);
                              console.log('generate lr state:' + itemSets.length);
                          }
                      }
                  });
  
              }
  
              return itemSets;
          }