docs: function complete(tokens, states, i, j) {
    let newItem
      , curr = states[i][j];
  
    // completion (check first because the position may be out of bounds)
    if (curr.position >= curr.rule.length) {
      states[curr.origin].forEach((earleyItem) => {
        if (earleyItem.rule[earleyItem.position] === curr.rule.lhs) {
          let stateHasItem = states[i].filter((ei) => {
            return ei.rule === earleyItem.rule &&
                   ei.position === earleyItem.position + 1 &&
                   ei.origin === earleyItem.origin;
          }).length > 0;
  
          if (stateHasItem) {
            return;
          }
          newItem = Object.assign({}, earleyItem);
          newItem.position += 1;
          states[i].push(newItem);
        }
      });
    }
  }