inline Symbol const *Item::dotSymbol() const    // symbol at the dot (must 
{                                               // exist!)
    return &(*d_production)[d_dot];
}

inline Symbol const *Item::dotSymbolOr0() const // symbol at the dot or 0
{                                       // if dot at end of production
    return d_dot == d_production->size() ?
                0
            :
                dotSymbol();
}

inline Symbol const *Item::symbolBeforeDot() const  // symbol before the dot
{
    return &(*d_production)[d_dot - 1];
}

inline size_t Item::dot() const
{
    return d_dot;
}

inline Item Item::incDot() const
{
    return Item(this, d_dot + 1);
}

inline Production const *Item::production() const  
{
    return d_production;
}

inline Symbol const *Item::lhs() const
{
    return d_production->lhs();
}

inline bool Item::isReducible() const                // if dot at end
{
    return d_dot == productionSize();
}

inline bool Item::empty() const                 // if no size
{
    return productionSize() == 0;
}

inline size_t Item::productionSize() const
{
    return d_production->size();
}

inline void Item::inserter(std::ostream &(Item::*insertPtr)
                                         (std::ostream &out) const)
{
    s_insertPtr = insertPtr;
}

inline std::ostream &operator<<(std::ostream &out, Item const &item)
{
    return (item.*Item::s_insertPtr)(out);
    // Set by static void inserter(Item::*insertPtr)
    // to 'plainItem' or 'pNrDotItem'
}
